cmd/cue/cmd: update cmd documentation

Refer to --inject and remove redundant task section.

Change-Id: I13d993dce3eeb0213d94d53899d7aa01d9e589da
Reviewed-on: https://cue-review.googlesource.com/c/cue/+/5540
Reviewed-by: Marcel van Lohuizen <mpvl@google.com>
diff --git a/cmd/cue/cmd/cmd.go b/cmd/cue/cmd/cmd.go
index 1d21973..fb31790 100644
--- a/cmd/cue/cmd/cmd.go
+++ b/cmd/cue/cmd/cmd.go
@@ -29,131 +29,36 @@
 		Short: "run a user-defined shell command",
 		Long: `cmd executes defined 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 top of the module root so that they apply to all
-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 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 are
-filled out by the task implementation as the task completes.
+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.
-
-Commands are defined at the top-level of the configuration:
-
-	command: [Name=string]: { // from tool.Command
-		// usage gives a short usage pattern of the command.
-		// Example:
-		//    fmt [-s] [inputs]
-		usage?: Name | string
-
-		// short gives a brief on-line description of the command.
-		// Example:
-		//    reformat package sources
-		short?: string
-
-		// long gives a detailed description of the command, including a
-		// description of flags usage and examples.
-		long?: string
-
-		// A task defines a single action to be run as part of this command.
-		// Each task can have inputs and outputs, depending on the type
-		// task. The outputs are initially unspecified, but are filled out
-		// by the tooling
-		task: [string]: { // from "tool".Task
-			// supported fields depend on type
-		}
-
-		VarValue = string | bool | int | float | [...string|int|float]
-
-		// var declares values that can be set by command line flags or
-		// environment variables.
-		//
-		// Example:
-		//   // environment to run in
-		//   var env: "test" | "prod"
-		// The tool would print documentation of this flag as:
-		//   Flags:
-		//      --env string    environment to run in: test(default) or prod
-		var: [string]: VarValue
-
-		// flag defines a command line flag.
-		//
-		// Example:
-		//   var env: "test" | "prod"
-		//
-		//   // augment the flag information for var
-		//   flag env: {
-		//       shortFlag:   "e"
-		//       description: "environment to run in"
-		//   }
-		//
-		// The tool would print documentation of this flag as:
-		//   Flags:
-		//     -e, --env string    environment to run in: test(default), staging, or prod
-		//
-		flag [Name=_]: { // from "tool".Flag
-			// value defines the possible values for this flag.
-			// The default is string. Users can define default values by
-			// using disjunctions.
-			value: *env[Name].value | VarValue
-
-			// name, if set, allows var to be set with the command-line flag
-			// of the given name. null disables the command line flag.
-			name?: *Name | string
-
-			// short defines an abbreviated version of the flag.
-			// Disabled by default.
-			short?: string
-		}
-
-		// populate flag with the default values for
-		for k, v in var {
-			flag: { "\(k)": { value: v } | null  }
-		}
-
-		// env defines environment variables. It is populated with values
-		// for var.
-		//
-		// To specify a var without an equivalent environment variable,
-		// either specify it as a flag directly or disable the equally
-		// named env entry explicitly:
-		//
-		//     var foo: string
-		//     env foo: null  // don't use environment variables for foo
-		//
-		env: [Name=_]: {
-			// name defines the environment variable that sets this flag.
-			name?: *"CUE_VAR_" + strings.Upper(Name) | string
-
-			// The value retrieved from the environment variable or null
-			// if not set.
-			value?: string | bytes
-		}
-		env: {
-			for k, v in var {
-				"\(k)": { value: v } | null
-			}
-		}
-	}
+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://godoc.org/cuelang.org/go/pkg/tool
-
-More on tasks can be found in the tasks topic.
+	https://pkg.go.dev/cuelang.org/go/pkg/tool?tab=subdirectories
 
 Examples:
 
-A simple file using command line execution:
+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
@@ -161,60 +66,71 @@
 	import "tool/exec"
 
 	city: "Amsterdam"
+	who: *"World" | string @tag(who)
 
 	// Say hello!
 	command: hello: {
-		// whom to say hello to
-		var: who: *"World" | string
-
-		task: print: exec.Run & {
-			cmd: "echo Hello \(var.who)! Welcome to \(city)."
+		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 hello -who you  # Setting arguments is not supported yet by cue
-	Hello you! Welcome to Amsterdam.
+	$ cue cmd --inject who=Jan hello
+	Hello Jan! Welcome to Amsterdam.
 
 
-An example using pipes:
+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/exec"
+	import (
+		"tool/cli"
+		"tool/exec"
+		"tool/file"
+	)
 
 	city: "Amsterdam"
 
 	// Say hello!
-	command: hello: {
-		var: file: "out.txt" | string // save transcript to this file
+	command: prompter: {
+		// save transcript to this file
+		var: file: *"out.txt" | string @tag(file)
 
-		task: ask: cli.Ask & {
+		ask: cli.Ask & {
 			prompt:   "What is your name?"
 			response: string
 		}
 
 		// starts after ask
-		task: echo: exec.Run & {
-			cmd:    ["echo", "Hello", task.ask.response + "!"]
+		echo: exec.Run & {
+			cmd:    ["echo", "Hello", ask.response + "!"]
 			stdout: string // capture stdout
 		}
 
 		// starts after echo
-		task: write: file.Append & {
+		file.Append & {
 			filename: var.file
-			contents: task.echo.stdout
+			contents: echo.stdout
 		}
 
 		// also starts after echo
-		task: print: cli.Print & {
-			contents: task.echo.stdout
+		print: cli.Print & {
+			contents: echo.stdout
 		}
 	}
 
+Run "cue help commands" for more details on tasks and commands.
 `,
 		RunE: mkRunE(c, func(cmd *Command, args []string) error {
 			w := cmd.Stderr()
diff --git a/cmd/cue/cmd/help.go b/cmd/cue/cmd/help.go
index 68e4d21..5a8de6c 100644
--- a/cmd/cue/cmd/help.go
+++ b/cmd/cue/cmd/help.go
@@ -300,6 +300,165 @@
 `,
 }
 
+var commandsHelp = &cobra.Command{
+	Use:   "commands",
+	Short: "user-defined commands",
+	Long: `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
+
+More on tasks can be found in the commands help topic.
+
+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
+		file.Append & {
+			filename: var.file
+			contents: echo.stdout
+		}
+
+		// also starts after echo
+		print: cli.Print & {
+			contents: echo.stdout
+		}
+	}
+
+The types of the commands and tasks are defined in CUE itself at
+cuelang.org/go/pkg/tool/tool.cue.
+
+	command: [Name]: Command
+
+	Command :: {
+		// Tasks specifies the things to run to complete a command. Tasks are
+		// typically underspecified and completed by the particular internal
+		// handler that is running them. Tasks can be a single task, or a full
+		// hierarchy of tasks.
+		//
+		// Tasks that depend on the output of other tasks are run after such tasks.
+		// Use $after if a task needs to run after another task but does not
+		// otherwise depend on its output.
+		Tasks
+
+		//
+		// Example:
+		//     mycmd [-n] names
+		$usage?: string
+
+		// short is short description of what the command does.
+		$short?: string
+
+		// long is a longer description that spans multiple lines and
+		// likely contain examples of usage of the command.
+		$long?: string
+	}
+
+	// Tasks defines a hierarchy of tasks. A command completes if all
+	// tasks have run to completion.
+	Tasks: Task | {
+		[name=Name]: Tasks
+	}
+
+	// Name defines a valid task or command name.
+	Name :: =~#"^\PL([-](\PL|\PN))*$"#
+
+	// A Task defines a step in the execution of a command.
+	Task: {
+		$type: "tool.Task" // legacy field 'kind' still supported for now.
+
+		// kind indicates the operation to run. It must be of the form
+		// packagePath.Operation.
+		$id: =~#"\."#
+
+		// $after can be used to specify a task is run after another one, when
+		// it does not otherwise refer to an output of that task.
+		$after?: Task | [...Task]
+	}
+`,
+}
+
 // TODO: tags
 // - doc/nodoc
 // - attr/noattr
diff --git a/cmd/cue/cmd/testdata/script/help_cmd.txt b/cmd/cue/cmd/testdata/script/help_cmd.txt
index 3a2db1c..427164d 100644
--- a/cmd/cue/cmd/testdata/script/help_cmd.txt
+++ b/cmd/cue/cmd/testdata/script/help_cmd.txt
@@ -26,131 +26,36 @@
 -- expect-stdout --
 cmd executes defined 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 top of the module root so that they apply to all
-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 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 are
-filled out by the task implementation as the task completes.
+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.
-
-Commands are defined at the top-level of the configuration:
-
-	command: [Name=string]: { // from tool.Command
-		// usage gives a short usage pattern of the command.
-		// Example:
-		//    fmt [-s] [inputs]
-		usage?: Name | string
-
-		// short gives a brief on-line description of the command.
-		// Example:
-		//    reformat package sources
-		short?: string
-
-		// long gives a detailed description of the command, including a
-		// description of flags usage and examples.
-		long?: string
-
-		// A task defines a single action to be run as part of this command.
-		// Each task can have inputs and outputs, depending on the type
-		// task. The outputs are initially unspecified, but are filled out
-		// by the tooling
-		task: [string]: { // from "tool".Task
-			// supported fields depend on type
-		}
-
-		VarValue = string | bool | int | float | [...string|int|float]
-
-		// var declares values that can be set by command line flags or
-		// environment variables.
-		//
-		// Example:
-		//   // environment to run in
-		//   var env: "test" | "prod"
-		// The tool would print documentation of this flag as:
-		//   Flags:
-		//      --env string    environment to run in: test(default) or prod
-		var: [string]: VarValue
-
-		// flag defines a command line flag.
-		//
-		// Example:
-		//   var env: "test" | "prod"
-		//
-		//   // augment the flag information for var
-		//   flag env: {
-		//       shortFlag:   "e"
-		//       description: "environment to run in"
-		//   }
-		//
-		// The tool would print documentation of this flag as:
-		//   Flags:
-		//     -e, --env string    environment to run in: test(default), staging, or prod
-		//
-		flag [Name=_]: { // from "tool".Flag
-			// value defines the possible values for this flag.
-			// The default is string. Users can define default values by
-			// using disjunctions.
-			value: *env[Name].value | VarValue
-
-			// name, if set, allows var to be set with the command-line flag
-			// of the given name. null disables the command line flag.
-			name?: *Name | string
-
-			// short defines an abbreviated version of the flag.
-			// Disabled by default.
-			short?: string
-		}
-
-		// populate flag with the default values for
-		for k, v in var {
-			flag: { "\(k)": { value: v } | null  }
-		}
-
-		// env defines environment variables. It is populated with values
-		// for var.
-		//
-		// To specify a var without an equivalent environment variable,
-		// either specify it as a flag directly or disable the equally
-		// named env entry explicitly:
-		//
-		//     var foo: string
-		//     env foo: null  // don't use environment variables for foo
-		//
-		env: [Name=_]: {
-			// name defines the environment variable that sets this flag.
-			name?: *"CUE_VAR_" + strings.Upper(Name) | string
-
-			// The value retrieved from the environment variable or null
-			// if not set.
-			value?: string | bytes
-		}
-		env: {
-			for k, v in var {
-				"\(k)": { value: v } | null
-			}
-		}
-	}
+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://godoc.org/cuelang.org/go/pkg/tool
-
-More on tasks can be found in the tasks topic.
+	https://pkg.go.dev/cuelang.org/go/pkg/tool?tab=subdirectories
 
 Examples:
 
-A simple file using command line execution:
+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
@@ -158,60 +63,72 @@
 	import "tool/exec"
 
 	city: "Amsterdam"
+	who: *"World" | string @tag(who)
 
 	// Say hello!
 	command: hello: {
-		// whom to say hello to
-		var: who: *"World" | string
-
-		task: print: exec.Run & {
-			cmd: "echo Hello \(var.who)! Welcome to \(city)."
+		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 hello -who you  # Setting arguments is not supported yet by cue
-	Hello you! Welcome to Amsterdam.
+	$ cue cmd --inject who=Jan hello
+	Hello Jan! Welcome to Amsterdam.
 
 
-An example using pipes:
+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/exec"
+	import (
+		"tool/cli"
+		"tool/exec"
+		"tool/file"
+	)
 
 	city: "Amsterdam"
 
 	// Say hello!
-	command: hello: {
-		var: file: "out.txt" | string // save transcript to this file
+	command: prompter: {
+		// save transcript to this file
+		var: file: *"out.txt" | string @tag(file)
 
-		task: ask: cli.Ask & {
+		ask: cli.Ask & {
 			prompt:   "What is your name?"
 			response: string
 		}
 
 		// starts after ask
-		task: echo: exec.Run & {
-			cmd:    ["echo", "Hello", task.ask.response + "!"]
+		echo: exec.Run & {
+			cmd:    ["echo", "Hello", ask.response + "!"]
 			stdout: string // capture stdout
 		}
 
 		// starts after echo
-		task: write: file.Append & {
+		file.Append & {
 			filename: var.file
-			contents: task.echo.stdout
+			contents: echo.stdout
 		}
 
 		// also starts after echo
-		task: print: cli.Print & {
-			contents: task.echo.stdout
+		print: cli.Print & {
+			contents: echo.stdout
 		}
 	}
 
+Run "cue help commands" for more details on tasks and commands.
+
 Usage:
   cue cmd <name> [inputs] [flags]
   cue cmd [command]
diff --git a/pkg/tool/tool.cue b/pkg/tool/tool.cue
index 87a1318..ed0bf2f 100644
--- a/pkg/tool/tool.cue
+++ b/pkg/tool/tool.cue
@@ -58,7 +58,7 @@
 	[name=Name]: Tasks
 }
 
-// Name defines a valid task or command sname.
+// Name defines a valid task or command name.
 Name :: =~#"^\PL([-](\PL|\PN))*$"#
 
 // A Task defines a step in the execution of a command.