diff --git a/cmd/cue/cmd/root.go b/cmd/cue/cmd/root.go index fd65bedf7..de4c8f661 100644 --- a/cmd/cue/cmd/root.go +++ b/cmd/cue/cmd/root.go @@ -239,8 +239,8 @@ func New(args []string) (cmd *Command, err error) { // "fix": {"fix", nil}, } - // handle help and --help on root 'cue' command - if args[0] == "help" || args[0] == "--help" { + // handle help, --help and -h on root 'cue' command + if args[0] == "help" || args[0] == "--help" || args[0] == "-h" { // Allow errors. _ = addSubcommands(cmd, sub, args[1:], true) return cmd, nil @@ -301,10 +301,10 @@ func addSubcommands(cmd *Command, sub map[string]*subSpec, args []string, isHelp oldargs := []string{args[0]} args = args[1:] - // Check for 'cue cmd --help' + // Check for 'cue cmd --help|-h' // it is behaving differently for this one command, cobra does not seem to pick it up // See issue #340 - if len(args) == 1 && args[0] == "--help" { + if len(args) == 1 && (args[0] == "--help" || args[0] == "-h") { return cmd.Usage() } diff --git a/cmd/cue/cmd/root_test.go b/cmd/cue/cmd/root_test.go index 31ef2ec1e..5232f4cb8 100644 --- a/cmd/cue/cmd/root_test.go +++ b/cmd/cue/cmd/root_test.go @@ -27,6 +27,11 @@ func TestHelp(t *testing.T) { t.Error("help command failed unexpectedly") } + cmd, err = New([]string{"-h"}) + if err != nil || cmd == nil { + t.Error("help command failed unexpectedly") + } + cmd, err = New([]string{"help", "cmd"}) if err != nil || cmd == nil { t.Error("help command failed unexpectedly") @@ -37,6 +42,11 @@ func TestHelp(t *testing.T) { t.Error("help command failed unexpectedly") } + cmd, err = New([]string{"cmd", "-h"}) + if err != nil || cmd == nil { + t.Error("help command failed unexpectedly") + } + cmd, err = New([]string{"help", "eval"}) if err != nil || cmd == nil { t.Error("help command failed unexpectedly") diff --git a/cmd/cue/cmd/testdata/script/help.txt b/cmd/cue/cmd/testdata/script/help.txt new file mode 100644 index 000000000..268867dd8 --- /dev/null +++ b/cmd/cue/cmd/testdata/script/help.txt @@ -0,0 +1,67 @@ +# Verify that the various forms of requesting help work + +cue help +cmp stdout stdout.golden + +cue --help +cmp stdout stdout.golden + +cue -h +cmp stdout stdout.golden + +-- stdout.golden -- +cue evaluates CUE files, an extension of JSON, and sends them +to user-defined commands for processing. + +Commands are defined in CUE as follows: + + import "tool/exec" + command: deploy: { + exec.Run + cmd: "kubectl" + args: [ "-f", "deploy" ] + in: json.Encode(userValue) // encode the emitted configuration. + } + +cue can also combine the results of http or grpc request with the input +configuration for further processing. For more information on defining commands +run 'cue help cmd' or go to cuelang.org/pkg/cmd. + +For more information on writing CUE configuration files see cuelang.org. + +Usage: + cue [command] + +Available Commands: + cmd run a user-defined shell command + completion Generate completion script + def print consolidated definitions + eval evaluate and print a configuration + export output data in a standard format + fix rewrite packages to latest standards + fmt formats CUE configuration files + get add dependencies to the current module + help Help about any command + import convert other formats to CUE files + mod module maintenance + trim remove superfluous fields + version print CUE version + vet validate data + +Flags: + -E, --all-errors print all available errors + -h, --help help for cue + -i, --ignore proceed in the presence of errors + -s, --simplify simplify output + --strict report errors for lossy mappings + --trace trace computation + -v, --verbose print information about progress + +Additional help topics: + cue commands user-defined commands + cue filetypes supported file types and qualifiers + cue flags common flags for composing packages + cue injection inject files or values into specific fields for a build + cue inputs package list, patterns, and files + +Use "cue [command] --help" for more information about a command. diff --git a/cmd/cue/cmd/testdata/script/help_cmd_flags.txt b/cmd/cue/cmd/testdata/script/help_cmd_flags.txt new file mode 100644 index 000000000..8cad5488b --- /dev/null +++ b/cmd/cue/cmd/testdata/script/help_cmd_flags.txt @@ -0,0 +1,148 @@ +cue cmd -h +cmp stdout expect-stdout + +cue cmd --help +cmp stdout expect-stdout + +-- cue.mod -- +-- task_tool.cue -- +package home + +import "tool/cli" + +// say hello to someone +command: hello: { + task: say: { + cli.Print + text: "Hello world!" + } +} + +// echo something back +command: echo: { + task: echo: { + cli.Print + text: "ECHO Echo echo..." + } +} + +-- expect-stdout -- +cmd executes the named command for each of the named instances. + +Commands define actions on instances. For example, they may +specify how to upload a configuration to Kubernetes. Commands are +defined directly in tool files, which are regular CUE files +within the same package with a filename ending in _tool.cue. +These are typically defined at the module root so that they apply +to all instances. + +Each command consists of one or more tasks. A task may, for +example, load or write a file, consult a user on the command +line, fetch a web page, and so on. Each task has inputs and +outputs. Outputs are typically filled out by the task +implementation as the task completes. + +Inputs of tasks my refer to outputs of other tasks. The cue tool +does a static analysis of the configuration and only starts tasks +that are fully specified. Upon completion of each task, cue +rewrites the instance, filling in the completed task, and +reevaluates which other tasks can now start, and so on until all +tasks have completed. + +Available tasks can be found in the package documentation at + + https://pkg.go.dev/cuelang.org/go/pkg/tool?tab=subdirectories + +Examples: + +In this simple example, we define a command called "hello", +which declares a single task called "print" which uses +"tool/exec.Run" to execute a shell command that echos output to +the terminal: + + $ cat < hello_tool.cue + package foo + + import "tool/exec" + + city: "Amsterdam" + who: *"World" | string @tag(who) + + // Say hello! + command: hello: { + print: exec.Run & { + cmd: "echo Hello \(who)! Welcome to \(city)." + } + } + EOF + +We run the "hello" command like this: + + $ cue cmd hello + Hello World! Welcome to Amsterdam. + + $ cue cmd --inject who=Jan hello + Hello Jan! Welcome to Amsterdam. + + +In this example we declare the "prompted" command which has four +tasks. The first task prompts the user for a string input. The +second task depends on the first, and echos the response back to +the user with a friendly message. The third task pipes the output +from the second to a file. The fourth task pipes the output from +the second to standard output (i.e. it echos it again). + + package foo + + import ( + "tool/cli" + "tool/exec" + "tool/file" + ) + + city: "Amsterdam" + + // Say hello! + command: prompter: { + // save transcript to this file + var: file: *"out.txt" | string @tag(file) + + ask: cli.Ask & { + prompt: "What is your name?" + response: string + } + + // starts after ask + echo: exec.Run & { + cmd: ["echo", "Hello", ask.response + "!"] + stdout: string // capture stdout + } + + // starts after echo + append: file.Append & { + filename: var.file + contents: echo.stdout + } + + // also starts after echo + print: cli.Print & { + text: echo.stdout + } + } + +Run "cue help commands" for more details on tasks and commands. + +Usage: + cue cmd [inputs] [flags] + +Flags: + -h, --help help for cmd + -t, --inject stringArray set the value of a tagged field + +Global Flags: + -E, --all-errors print all available errors + -i, --ignore proceed in the presence of errors + -s, --simplify simplify output + --strict report errors for lossy mappings + --trace trace computation + -v, --verbose print information about progress