Skip to content
This repository has been archived by the owner on Nov 18, 2021. It is now read-only.

Commit

Permalink
cmd: fix -h handling
Browse files Browse the repository at this point in the history
Fixes `cue -h` and `cue cmd -h` parsing.

Closes #723

Change-Id: I1aeafab49fe8630400829ba2b48372d61ad83232

Closes #827
#827

GitOrigin-RevId: 30996db
Change-Id: I4370ec8860c47ca79496e24a55ffc3416f8fefcb
Reviewed-on: https://cue-review.googlesource.com/c/cue/+/9081
Reviewed-by: CUE cueckoo <[email protected]>
Reviewed-by: Paul Jolly <[email protected]>
  • Loading branch information
eonpatapon authored and myitcv committed Mar 22, 2021
1 parent 35e19b2 commit 27d305c
Show file tree
Hide file tree
Showing 4 changed files with 229 additions and 4 deletions.
8 changes: 4 additions & 4 deletions cmd/cue/cmd/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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()
}

Expand Down
10 changes: 10 additions & 0 deletions cmd/cue/cmd/root_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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")
Expand All @@ -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")
Expand Down
67 changes: 67 additions & 0 deletions cmd/cue/cmd/testdata/script/help.txt
Original file line number Diff line number Diff line change
@@ -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.
148 changes: 148 additions & 0 deletions cmd/cue/cmd/testdata/script/help_cmd_flags.txt
Original file line number Diff line number Diff line change
@@ -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 <<EOF > 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 <name> [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

0 comments on commit 27d305c

Please sign in to comment.