Skip to content
This repository has been archived by the owner on Feb 17, 2024. It is now read-only.

test: don't exit on flag parsing error #42

Merged
merged 3 commits into from
Jun 1, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ timecraft.src.go = \
$(wildcard */*/*.go) \
$(wildcard */*/*/*.go)

timecraft: go.mod flatbuffers $(timecraft.src.go)
timecraft: go.mod $(timecraft.src.go)
$(GO) build -o timecraft

clean:
Expand All @@ -32,7 +32,7 @@ generate: flatbuffers
flatbuffers: go.mod $(format.src.go)
$(GO) build ./format/...

test: timecraft testdata
test: testdata
$(GO) test ./...

testdata: $(testdata.go.wasm)
Expand Down
15 changes: 6 additions & 9 deletions config.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,12 +35,6 @@ var (
configPath human.Path = "~/.timecraft/config.yaml"
)

func init() {
if v := os.Getenv("TIMECRAFTCONFIG"); v != "" {
configPath = human.Path(v)
}
}

func config(ctx context.Context, args []string) error {
var (
edit bool
Expand All @@ -50,7 +44,10 @@ func config(ctx context.Context, args []string) error {
flagSet := newFlagSet("timecraft config", configUsage)
boolVar(flagSet, &edit, "edit")
customVar(flagSet, &output, "o", "output")
parseFlags(flagSet, args)

if _, err := parseFlags(flagSet, args); err != nil {
return err
}

r, path, err := openConfig()
if err != nil {
Expand Down Expand Up @@ -259,11 +256,11 @@ func (c *configuration) newRuntime(ctx context.Context) wazero.Runtime {
// user but still go ahead with the runtime instantiation.
path, err := cachePath.Resolve()
if err != nil {
fmt.Fprintf(os.Stderr, "ERR: resolving timecraft cache location: %s\n", err)
perrorf("ERR: resolving timecraft cache location: %s", err)
} else {
cache, err = createCacheDirectory(path)
if err != nil {
fmt.Fprintf(os.Stderr, "ERR: creating timecraft cache directory: %s\n", err)
perrorf("ERR: creating timecraft cache directory: %s", err)
} else {
config = config.WithCompilationCache(cache)
}
Expand Down
8 changes: 6 additions & 2 deletions describe.go
Original file line number Diff line number Diff line change
Expand Up @@ -58,10 +58,14 @@ func describe(ctx context.Context, args []string) error {

flagSet := newFlagSet("timecraft describe", describeUsage)
customVar(flagSet, &output, "o", "output")
args = parseFlags(flagSet, args)

args, err := parseFlags(flagSet, args)
if err != nil {
return err
}
if len(args) == 0 {
return errors.New(`expected a resource type as argument`)
perror(`expected a resource type as argument`)
return exitCode(2)
}

resource, err := findResource("describe", args[0])
Expand Down
11 changes: 8 additions & 3 deletions export.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,14 +28,19 @@ Options:

func export(ctx context.Context, args []string) error {
flagSet := newFlagSet("timecraft export", exportUsage)
args = parseFlags(flagSet, args)

args, err := parseFlags(flagSet, args)
if err != nil {
return err
}
if len(args) != 3 {
return usageError(`Expected resource type, id, and output file as argument` + useCmd("export"))
perrorf(`Expected resource type, id, and output file as argument` + useCmd("export"))
return exitCode(2)
}
resource, err := findResource("describe", args[0])
if err != nil {
return usageError(err.Error())
perror(err)
return exitCode(2)
}
config, err := loadConfig()
if err != nil {
Expand Down
32 changes: 16 additions & 16 deletions export_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,53 +10,53 @@ import (

var export = tests{
"show the export command help with the short option": func(t *testing.T) {
stdout, stderr, err := timecraft(t, "export", "-h")
assert.OK(t, err)
stdout, stderr, exitCode := timecraft(t, "export", "-h")
assert.Equal(t, exitCode, 0)
assert.HasPrefix(t, stdout, "Usage:\ttimecraft export ")
assert.Equal(t, stderr, "")
},

"show the export command help with the long option": func(t *testing.T) {
stdout, stderr, err := timecraft(t, "export", "--help")
assert.OK(t, err)
stdout, stderr, exitCode := timecraft(t, "export", "--help")
assert.Equal(t, exitCode, 0)
assert.HasPrefix(t, stdout, "Usage:\ttimecraft export ")
assert.Equal(t, stderr, "")
},

"export without a resource type": func(t *testing.T) {
stdout, stderr, err := timecraft(t, "export")
assert.ExitError(t, err, 2)
stdout, stderr, exitCode := timecraft(t, "export")
assert.Equal(t, exitCode, 2)
assert.Equal(t, stdout, "")
assert.HasPrefix(t, stderr, "Expected resource type, id, and output file as argument")
},

"export without a resource id": func(t *testing.T) {
stdout, stderr, err := timecraft(t, "export", "profile")
assert.ExitError(t, err, 2)
stdout, stderr, exitCode := timecraft(t, "export", "profile")
assert.Equal(t, exitCode, 2)
assert.Equal(t, stdout, "")
assert.HasPrefix(t, stderr, "Expected resource type, id, and output file as argument")
},

"export without an output file": func(t *testing.T) {
stdout, stderr, err := timecraft(t, "export", "profile", "74080192e42e")
assert.ExitError(t, err, 2)
stdout, stderr, exitCode := timecraft(t, "export", "profile", "74080192e42e")
assert.Equal(t, exitCode, 2)
assert.Equal(t, stdout, "")
assert.HasPrefix(t, stderr, "Expected resource type, id, and output file as argument")
},

"export a module to stdout": func(t *testing.T) {
stdout, processID, err := timecraft(t, "run", "./testdata/go/sleep.wasm", "1ns")
assert.OK(t, err)
stdout, processID, exitCode := timecraft(t, "run", "./testdata/go/sleep.wasm", "1ns")
assert.Equal(t, exitCode, 0)
assert.Equal(t, stdout, "sleeping for 1ns\n")
assert.NotEqual(t, processID, "")

moduleID, stderr, err := timecraft(t, "get", "mod", "-q")
assert.OK(t, err)
moduleID, stderr, exitCode := timecraft(t, "get", "mod", "-q")
assert.Equal(t, exitCode, 0)
assert.Equal(t, stderr, "")
moduleID = strings.TrimSuffix(moduleID, "\n")

moduleData, stderr, err := timecraft(t, "export", "mod", moduleID, "-")
assert.OK(t, err)
moduleData, stderr, exitCode := timecraft(t, "export", "mod", moduleID, "-")
assert.Equal(t, exitCode, 0)
assert.Equal(t, stderr, "")

sleepWasm, err := os.ReadFile("./testdata/go/sleep.wasm")
Expand Down
11 changes: 8 additions & 3 deletions get.go
Original file line number Diff line number Diff line change
Expand Up @@ -124,14 +124,19 @@ func get(ctx context.Context, args []string) error {
flagSet := newFlagSet("timecraft get", getUsage)
customVar(flagSet, &output, "o", "output")
boolVar(flagSet, &quiet, "q", "quiet")
args = parseFlags(flagSet, args)

args, err := parseFlags(flagSet, args)
if err != nil {
return err
}
if len(args) != 1 {
return usageError(`Expected exactly one resource type as argument` + useCmd("get"))
perrorf(`Expected exactly one resource type as argument` + useCmd("get"))
return exitCode(2)
}
resource, err := findResource("get", args[0])
if err != nil {
return usageError(err.Error())
perror(err)
return exitCode(2)
}
config, err := loadConfig()
if err != nil {
Expand Down
64 changes: 32 additions & 32 deletions get_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,103 +8,103 @@ import (

var get = tests{
"show the get command help with the short option": func(t *testing.T) {
stdout, stderr, err := timecraft(t, "get", "-h")
assert.OK(t, err)
stdout, stderr, exitCode := timecraft(t, "get", "-h")
assert.Equal(t, exitCode, 0)
assert.HasPrefix(t, stdout, "Usage:\ttimecraft get ")
assert.Equal(t, stderr, "")
},

"show the get command help with the long option": func(t *testing.T) {
stdout, stderr, err := timecraft(t, "get", "--help")
assert.OK(t, err)
stdout, stderr, exitCode := timecraft(t, "get", "--help")
assert.Equal(t, exitCode, 0)
assert.HasPrefix(t, stdout, "Usage:\ttimecraft get ")
assert.Equal(t, stderr, "")
},

"get without a resource type": func(t *testing.T) {
stdout, stderr, err := timecraft(t, "get")
assert.ExitError(t, err, 2)
stdout, stderr, exitCode := timecraft(t, "get")
assert.Equal(t, exitCode, 2)
assert.Equal(t, stdout, "")
assert.HasPrefix(t, stderr, "Expected exactly one resource type as argument")
},

"get configs on an empty time machine": func(t *testing.T) {
stdout, stderr, err := timecraft(t, "get", "configs")
assert.OK(t, err)
stdout, stderr, exitCode := timecraft(t, "get", "configs")
assert.Equal(t, exitCode, 0)
assert.Equal(t, stdout, "CONFIG ID RUNTIME MODULES SIZE\n")
assert.Equal(t, stderr, "")
},

"get logs on an empty time machine": func(t *testing.T) {
stdout, stderr, err := timecraft(t, "get", "logs")
assert.OK(t, err)
stdout, stderr, exitCode := timecraft(t, "get", "logs")
assert.Equal(t, exitCode, 0)
assert.Equal(t, stdout, "PROCESS ID SEGMENTS START SIZE\n")
assert.Equal(t, stderr, "")
},

"get modules on an empty time machine": func(t *testing.T) {
stdout, stderr, err := timecraft(t, "get", "modules")
assert.OK(t, err)
stdout, stderr, exitCode := timecraft(t, "get", "modules")
assert.Equal(t, exitCode, 0)
assert.Equal(t, stdout, "MODULE ID MODULE NAME SIZE\n")
assert.Equal(t, stderr, "")
},

"get process on an empty time machine": func(t *testing.T) {
stdout, stderr, err := timecraft(t, "get", "processes")
assert.OK(t, err)
stdout, stderr, exitCode := timecraft(t, "get", "processes")
assert.Equal(t, exitCode, 0)
assert.Equal(t, stdout, "PROCESS ID START\n")
assert.Equal(t, stderr, "")
},

"get runtimes on an empty time machine": func(t *testing.T) {
stdout, stderr, err := timecraft(t, "get", "runtimes")
assert.OK(t, err)
stdout, stderr, exitCode := timecraft(t, "get", "runtimes")
assert.Equal(t, exitCode, 0)
assert.Equal(t, stdout, "RUNTIME ID RUNTIME NAME VERSION\n")
assert.Equal(t, stderr, "")
},

"get config after run": func(t *testing.T) {
stdout, processID, err := timecraft(t, "run", "./testdata/go/sleep.wasm", "1ns")
assert.OK(t, err)
stdout, processID, exitCode := timecraft(t, "run", "./testdata/go/sleep.wasm", "1ns")
assert.Equal(t, exitCode, 0)
assert.Equal(t, stdout, "sleeping for 1ns\n")
assert.NotEqual(t, processID, "")

configID, stderr, err := timecraft(t, "get", "conf", "-q")
assert.OK(t, err)
configID, stderr, exitCode := timecraft(t, "get", "conf", "-q")
assert.Equal(t, exitCode, 0)
assert.NotEqual(t, configID, "")
assert.Equal(t, stderr, "")
},

"get log after run": func(t *testing.T) {
stdout, processID, err := timecraft(t, "run", "./testdata/go/sleep.wasm", "1ns")
assert.OK(t, err)
stdout, processID, exitCode := timecraft(t, "run", "./testdata/go/sleep.wasm", "1ns")
assert.Equal(t, exitCode, 0)
assert.Equal(t, stdout, "sleeping for 1ns\n")

logID, stderr, err := timecraft(t, "get", "log", "-q")
assert.OK(t, err)
logID, stderr, exitCode := timecraft(t, "get", "log", "-q")
assert.Equal(t, exitCode, 0)
assert.Equal(t, logID, processID)
assert.Equal(t, stderr, "")
},

"get process after run": func(t *testing.T) {
stdout, processID, err := timecraft(t, "run", "./testdata/go/sleep.wasm", "1ns")
assert.OK(t, err)
stdout, processID, exitCode := timecraft(t, "run", "./testdata/go/sleep.wasm", "1ns")
assert.Equal(t, exitCode, 0)
assert.Equal(t, stdout, "sleeping for 1ns\n")

procID, stderr, err := timecraft(t, "get", "proc", "-q")
assert.OK(t, err)
procID, stderr, exitCode := timecraft(t, "get", "proc", "-q")
assert.Equal(t, exitCode, 0)
assert.Equal(t, procID, processID)
assert.Equal(t, stderr, "")
},

"get runtime after run": func(t *testing.T) {
stdout, processID, err := timecraft(t, "run", "./testdata/go/sleep.wasm", "1ns")
assert.OK(t, err)
stdout, processID, exitCode := timecraft(t, "run", "./testdata/go/sleep.wasm", "1ns")
assert.Equal(t, exitCode, 0)
assert.Equal(t, stdout, "sleeping for 1ns\n")
assert.NotEqual(t, processID, "")

runtimeID, stderr, err := timecraft(t, "get", "rt", "-q")
assert.OK(t, err)
runtimeID, stderr, exitCode := timecraft(t, "get", "rt", "-q")
assert.Equal(t, exitCode, 0)
assert.NotEqual(t, runtimeID, "")
assert.Equal(t, stderr, "")
},
Expand Down
9 changes: 7 additions & 2 deletions help.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,11 @@ For a description of each command, run 'timecraft help <command>'.`

func help(ctx context.Context, args []string) error {
flagSet := newFlagSet("timecraft help", helpUsage)
args = parseFlags(flagSet, args)

args, err := parseFlags(flagSet, args)
if err != nil {
return err
}
if len(args) == 0 {
args = []string{"help"}
}
Expand Down Expand Up @@ -66,7 +70,8 @@ func help(ctx context.Context, args []string) error {
case "version":
msg = versionUsage
default:
return usageError("timecraft help %s: unknown command", cmd)
perrorf("timecraft help %s: unknown command", cmd)
return exitCode(2)
}

fmt.Println(strings.TrimSpace(msg))
Expand Down
Loading
Loading