Implemented run command

This commit is contained in:
Eduard Urbach 2024-07-06 19:40:20 +02:00
parent 230bb36709
commit 6fc234c700
Signed by: akyoto
GPG Key ID: C874F672B1AF20C0
7 changed files with 95 additions and 19 deletions

View File

@ -17,11 +17,10 @@ go build
## Usage ## Usage
Build a Linux x86-64 ELF executable from `examples/hello`: Build a Linux x86-64 ELF executable from `examples/hello` and run it:
```shell ```shell
./q build examples/hello ./q run examples/hello
./examples/hello/hello
``` ```
## Documentation ## Documentation

View File

@ -0,0 +1,13 @@
package errors
import "fmt"
// UnknownCLIParameter error is created when a command line parameter is not recognized.
type UnknownCLIParameter struct {
Parameter string
}
// Error generates the string representation.
func (err *UnknownCLIParameter) Error() string {
return fmt.Sprintf("Unknown parameter '%s'", err.Parameter)
}

View File

@ -7,10 +7,30 @@ import (
"git.akyoto.dev/cli/q/src/build" "git.akyoto.dev/cli/q/src/build"
"git.akyoto.dev/cli/q/src/build/config" "git.akyoto.dev/cli/q/src/build/config"
"git.akyoto.dev/cli/q/src/build/errors"
) )
// Build parses the arguments and creates a build. // Build parses the arguments and creates a build.
func Build(args []string) int { func Build(args []string) int {
_, err := buildWithArgs(args)
if err != nil {
fmt.Fprintln(os.Stderr, err)
switch err.(type) {
case *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() b := build.New()
for i := 0; i < len(args); i++ { for i := 0; i < len(args); i++ {
@ -26,8 +46,7 @@ func Build(args []string) int {
config.Comments = true config.Comments = true
default: default:
if strings.HasPrefix(args[i], "-") { if strings.HasPrefix(args[i], "-") {
fmt.Printf("Unknown parameter: %s\n", args[i]) return b, &errors.UnknownCLIParameter{Parameter: args[i]}
return 2
} }
b.Files = append(b.Files, args[i]) b.Files = append(b.Files, args[i])
@ -38,16 +57,16 @@ func Build(args []string) int {
b.Files = append(b.Files, ".") b.Files = append(b.Files, ".")
} }
return run(b) err := makeExecutable(b)
return b, err
} }
// run starts the build by running the compiler and then writing the result to disk. // makeExecutable starts the build by running the compiler and then writing the result to disk.
func run(b *build.Build) int { func makeExecutable(b *build.Build) error {
result, err := b.Run() result, err := b.Run()
if err != nil { if err != nil {
fmt.Fprintln(os.Stderr, err) return err
return 1
} }
if config.Assembler { if config.Assembler {
@ -55,15 +74,8 @@ func run(b *build.Build) int {
} }
if config.Dry { if config.Dry {
return 0 return nil
} }
err = result.Write(b.Executable()) return result.Write(b.Executable())
if err != nil {
fmt.Fprintln(os.Stderr, err)
return 1
}
return 0
} }

View File

@ -12,6 +12,7 @@ func Help(w io.Writer, code int) int {
commands: commands:
build [directory | file] build [directory | file]
run [directory | file]
help help
system system

View File

@ -14,6 +14,9 @@ func Main(args []string) int {
case "build": case "build":
return Build(args[1:]) return Build(args[1:])
case "run":
return Run(args[1:])
case "system": case "system":
return System(args[1:]) return System(args[1:])

View File

@ -25,6 +25,8 @@ func TestCLI(t *testing.T) {
{[]string{"build", "../../examples/hello", "--dry", "--verbose"}, 0}, {[]string{"build", "../../examples/hello", "--dry", "--verbose"}, 0},
{[]string{"build", "../../examples/hello/hello.q", "--dry"}, 0}, {[]string{"build", "../../examples/hello/hello.q", "--dry"}, 0},
{[]string{"build", "../../examples/hello"}, 0}, {[]string{"build", "../../examples/hello"}, 0},
{[]string{"run", "../../examples/hello", "--invalid"}, 2},
{[]string{"run", "../../examples/hello"}, 0},
} }
for _, test := range tests { for _, test := range tests {

46
src/cli/Run.go Normal file
View File

@ -0,0 +1,46 @@
package cli
import (
"fmt"
"os"
"os/exec"
"git.akyoto.dev/cli/q/src/build/errors"
)
// Run builds and runs the executable.
func Run(args []string) int {
b, err := buildWithArgs(args)
if err != nil {
fmt.Fprintln(os.Stderr, err)
switch err.(type) {
case *errors.UnknownCLIParameter:
return 2
default:
return 1
}
}
cmd := exec.Command(b.Executable())
cmd.Stdout = os.Stdout
cmd.Stdin = os.Stdin
cmd.Stderr = os.Stderr
err = cmd.Run()
if err != nil {
fmt.Fprintln(os.Stderr, err)
switch err.(type) {
case *exec.ExitError:
return 0
default:
return 1
}
}
return 0
}