pkg/tool: update documentation and remove $before

$before is redundant and seems like it may cause
limitations down the road. Removed as a precaution.
Documentation has been updated to reflect current
features.

Closes #223.

Note that environment variables will now be
implemented as `tool/env` and as an option to
`tool/exec.Run`. Flags will likely be a task type
end be refereneable as, say, `tool/flags.Set`.

Change-Id: Ic87766b6af2e546c25b30ada3f8a75e3c796b70d
Reviewed-on: https://cue-review.googlesource.com/c/cue/+/4740
Reviewed-by: Marcel van Lohuizen <mpvl@golang.org>
diff --git a/cmd/cue/cmd/custom.go b/cmd/cue/cmd/custom.go
index 4835153..6f592c9 100644
--- a/cmd/cue/cmd/custom.go
+++ b/cmd/cue/cmd/custom.go
@@ -224,28 +224,9 @@
 			if dep, ok := cr.referredTask(after); ok {
 				t.dep[dep] = true
 			}
-			iter, err := after.List()
-			if err == nil {
-				for iter.Next() {
-					if dep, ok := cr.referredTask(iter.Value()); ok {
-						t.dep[dep] = true
-					}
-				}
-			}
-		}
-
-		// Inject reverse dependency in `$before` field
-		before := task.Lookup("$before")
-		if before.Err() == nil {
-			if dep, ok := cr.referredTask(before); ok {
-				dep.dep[t] = true
-			}
-			iter, err := before.List()
-			if err == nil {
-				for iter.Next() {
-					if dep, ok := cr.referredTask(iter.Value()); ok {
-						dep.dep[t] = true
-					}
+			for iter, _ := after.List(); iter.Next(); {
+				if dep, ok := cr.referredTask(iter.Value()); ok {
+					t.dep[dep] = true
 				}
 			}
 		}
@@ -254,7 +235,7 @@
 			if v == task {
 				return true
 			}
-			if (after.Err() == nil && v.Equals(after)) || (before.Err() == nil && v.Equals(before)) {
+			if after.Err() == nil && v.Equals(after) {
 				return false
 			}
 			for _, r := range appendReferences(nil, cr.root, v) {
diff --git a/cmd/cue/cmd/testdata/script/cmd_before.txt b/cmd/cue/cmd/testdata/script/cmd_before.txt
deleted file mode 100644
index 813bb77..0000000
--- a/cmd/cue/cmd/testdata/script/cmd_before.txt
+++ /dev/null
@@ -1,43 +0,0 @@
-cue cmd before
-cmp stdout expect-stdout
-
--- expect-stdout --
-true
-
--- before_tool.cue --
-package home
-
-import (
-	"tool/exec"
-	"tool/cli"
-	"strings"
-)
-
-command: before: {
-	t1: exec.Run & {
-		cmd: ["sh", "-c", "sleep 2; date +%s"]
-		stdout: string
-		$before: [t2, t3]
-	}
-	t2: exec.Run & {
-		cmd: ["sh", "-c", "date +%s"]
-		stdout: string
-		$before: t4
-	}
-	t3: exec.Run & {
-		cmd: ["sh", "-c", "date +%s"]
-		stdout: string
-	}
-	t4: exec.Run & {
-		cmd: ["sh", "-c", "a=\(strings.TrimSpace(t1.stdout));b=\(strings.TrimSpace(t2.stdout));if [ $a -le $b ]; then echo 'true'; fi"]
-		stdout: string
-	}
-	t5: cli.Print & {
-			text: t4.stdout
-	}
-}
-
--- task.cue --
-package home
-
--- cue.mod --
diff --git a/pkg/tool/doc.go b/pkg/tool/doc.go
index a220c93..51e62b2 100644
--- a/pkg/tool/doc.go
+++ b/pkg/tool/doc.go
@@ -31,14 +31,20 @@
 //     //    // long description covering the remainder of the doc comment.
 //     //
 //     Command: {
-//     	$type: "tool.Command"
-//
-//     	$name: !=""
+//     	// 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?: =~"^\($name) "
+//     	$usage?: string
 //
 //     	// short is short description of what the command does.
 //     	$short?: string
@@ -48,19 +54,24 @@
 //     	$long?: string
 //
 //     	// TODO: child commands.
-//
-//     	// tasks specifies the list of things to do to run command. Tasks are
-//     	// typically underspecified and completed by the particular internal
-//     	// handler that is running them. Task de
-//     	tasks: [name=string]: Task
 //     }
 //
+//     // 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 sname.
+//     Name :: =~#"^\PL(\PL|\PN|-(\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:   =~#"\."#
-//     	$type: "tool.Task" // legacy field 'kind' still supported for now.
+//     	$id: =~#"\."#
 //     }
 //
 package tool
diff --git a/pkg/tool/generate.go b/pkg/tool/generate.go
index ba77048..0e16bb7 100644
--- a/pkg/tool/generate.go
+++ b/pkg/tool/generate.go
@@ -15,3 +15,4 @@
 package tool
 
 //go:generate go run gen.go
+//go:generate go fmt
diff --git a/pkg/tool/tool.cue b/pkg/tool/tool.cue
index 298b233..87a1318 100644
--- a/pkg/tool/tool.cue
+++ b/pkg/tool/tool.cue
@@ -26,14 +26,20 @@
 //    // long description covering the remainder of the doc comment.
 //
 Command: {
-	$type: "tool.Command"
-
-	$name: !=""
+	// 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?: =~"^\($name) "
+	$usage?: string
 
 	// short is short description of what the command does.
 	$short?: string
@@ -41,19 +47,34 @@
 	// long is a longer description that spans multiple lines and
 	// likely contain examples of usage of the command.
 	$long?: string
-
-	// TODO: child commands.
-
-	// tasks specifies the list of things to do to run command. Tasks are
-	// typically underspecified and completed by the particular internal
-	// handler that is running them. Task de
-	tasks: [name=string]: Task
 }
 
+// TODO:
+// - child commands?
+
+// 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 sname.
+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:   =~#"\."#
-	$type: "tool.Task" // legacy field 'kind' still supported for now.
+	$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: consider these options:
+//   $success: bool
+//   $runif: a.b.$success or $guard: a.b.$success
+// With this `$after: a.b` would just be a shorthand for `$guard: a.b.$success`.