q/src/cli/Build.go
2024-08-12 12:16:01 +02:00

100 lines
1.7 KiB
Go

package cli
import (
"fmt"
"os"
"strings"
"git.akyoto.dev/cli/q/src/build"
"git.akyoto.dev/cli/q/src/config"
"git.akyoto.dev/cli/q/src/errors"
)
// Build parses the arguments and creates a build.
func Build(args []string) int {
_, err := buildWithArgs(args)
if err != nil {
fmt.Fprintln(os.Stderr, err)
switch err.(type) {
case *errors.ExpectedCLIParameter, *errors.UnknownCLIParameter:
return 2
default:
return 1
}
}
return 0
}
// buildWithArgs creates a new build with the given arguments.
func buildWithArgs(args []string) (*build.Build, error) {
b := build.New()
for i := 0; i < len(args); i++ {
switch args[i] {
case "-a", "--assembler":
config.Assembler = true
case "-d", "--dry":
config.Dry = true
case "-v", "--verbose":
config.Assembler = true
case "--arch":
i++
if i >= len(args) {
return b, &errors.ExpectedCLIParameter{Parameter: "arch"}
}
config.TargetArch = args[i]
case "--os":
i++
if i >= len(args) {
return b, &errors.ExpectedCLIParameter{Parameter: "os"}
}
config.TargetOS = args[i]
default:
if strings.HasPrefix(args[i], "-") {
return b, &errors.UnknownCLIParameter{Parameter: args[i]}
}
b.Files = append(b.Files, args[i])
}
}
if len(b.Files) == 0 {
b.Files = append(b.Files, ".")
}
err := makeExecutable(b)
return b, err
}
// makeExecutable starts the build by running the compiler and then writing the result to disk.
func makeExecutable(b *build.Build) error {
result, err := b.Run()
if err != nil {
return err
}
if config.Assembler {
result.PrintInstructions()
}
if config.Dry {
return nil
}
return result.WriteFile(b.Executable())
}