pkg/tool: add constraints for tasks
Updates #39
Change-Id: Ied624912324b773b56ff4f2a1bf85a88c22ecc45
Reviewed-on: https://cue-review.googlesource.com/c/cue/+/1924
Reviewed-by: Marcel van Lohuizen <mpvl@google.com>
diff --git a/pkg/tool/cli/cli.cue b/pkg/tool/cli/cli.cue
new file mode 100644
index 0000000..986f43a
--- /dev/null
+++ b/pkg/tool/cli/cli.cue
@@ -0,0 +1,42 @@
+// Copyright 2018 The CUE Authors
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package cli
+
+// Print sends text to the stdout of the current process.
+Print: {
+ kind: "tool/cli.Print"
+
+ // text is the text to be printed.
+ text: string
+}
+
+// TODO:
+// Ask prompts the current console with a message and waits for input.
+//
+// Example:
+// task ask: cli.Ask({
+// prompt: "Are you okay?"
+// repsonse: bool
+// })
+// Ask: {
+// kind: "tool/cli.Ask"
+
+// // prompt sends this message to the output.
+// prompt: string
+
+// // response holds the user's response. If it is a boolean expression it
+// // will interpret the answer using textual yes/ no.
+// response: string | bool
+// }
diff --git a/pkg/tool/exec/exec.cue b/pkg/tool/exec/exec.cue
new file mode 100644
index 0000000..b286f17
--- /dev/null
+++ b/pkg/tool/exec/exec.cue
@@ -0,0 +1,53 @@
+// Copyright 2018 The CUE Authors
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package exec
+
+// Run executes the given shell command.
+Run: {
+ kind: "tool/exec.Run"
+
+ // cmd is the command to run.
+ cmd: string | [string, ...string]
+
+ // install is an optional command to install the binaries needed
+ // to run the command.
+ install?: string | [string, ...string]
+
+ // env defines the environment variables to use for this system.
+ env <Key>: string
+
+ // stdout captures the output from stdout if it is of type bytes or string.
+ // The default value of null indicates it is redirected to the stdout of the
+ // current process.
+ stdout: *null | string | bytes
+
+ // stderr is like stdout, but for errors.
+ stderr: *null | string | bytes
+
+ // stdin specifies the input for the process.
+ stdin?: string | bytes
+
+ // success is set to true when the process terminates with with a zero exit
+ // code or false otherwise. The user can explicitly specify the value
+ // force a fatal error if the desired success code is not reached.
+ success: bool
+}
+
+// Env collects the environment variables of the current process.
+Env: {
+ kind: "tool/exec.Env"
+
+ env <Name>: string | number
+}
diff --git a/pkg/tool/file/file.cue b/pkg/tool/file/file.cue
new file mode 100644
index 0000000..1275236
--- /dev/null
+++ b/pkg/tool/file/file.cue
@@ -0,0 +1,77 @@
+// Copyright 2018 The CUE Authors
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package os
+
+import "tool"
+
+// Read reads the contents of a file.
+Read: tool.Task & {
+ _kind: "tool/file.Read"
+
+ // filename names the file to read.
+ filename: string
+
+ // contents is the read contents. If the contents are constraint to bytes
+ // (the default), the file is read as is. If it is constraint to a string,
+ // the contents are checked to be valid UTF-8.
+ contents: *bytes | string
+
+ // if body is given, the file contents are parsed as JSON and unified with
+ // the specified CUE value.
+ body?: _
+}
+
+// Create writes contents to the given file.
+Create: tool.Task & {
+ _kind: "tool/file.Create"
+
+ // filename names the file to write.
+ filename: string
+
+ // permissions defines the permissions to use if the file does not yet exist.
+ permissions: int
+
+ // overwrite defines whether an existing file may be overwritten.
+ overwrite: *false | true
+
+ // contents specifies the bytes to be written.
+ contents: bytes | string
+}
+
+// Append writes contents to the given file.
+Append: tool.Task & {
+ // filename names the file to append.
+ filename: string
+
+ // permissions defines the permissions to use if the file does not yet exist.
+ permissions: int
+
+ // contents specifies the bytes to be written.
+ contents: bytes | string
+}
+
+Dir: tool.Task & {
+ _kind: "tool/file.Dir"
+
+ path: string
+ dir: [...string]
+}
+
+Glob: tool.Task & {
+ _kind: "tool/file.Glob"
+
+ glob: string
+ files <Filename>: string
+}
diff --git a/pkg/tool/http/http.cue b/pkg/tool/http/http.cue
new file mode 100644
index 0000000..04cee3d
--- /dev/null
+++ b/pkg/tool/http/http.cue
@@ -0,0 +1,54 @@
+// Copyright 2018 The CUE Authors
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package http
+
+Get: Do & {method: "GET"}
+Post: Do & {method: "POST"}
+Put: Do & {method: "PUT"}
+Delete: Do & {method: "DELETE"}
+
+Do: {
+ kind: "tool/http.Do"
+
+ method: string
+ url: string // TODO: make url.URL type
+
+ request: {
+ body: *bytes | string
+ header <Name>: string | [...string]
+ trailer <Name>: string | [...string]
+ }
+ response: {
+ status: string
+ statusCode: int
+
+ body: *bytes | string
+ header <Name>: string | [...string]
+ trailer <Name>: string | [...string]
+ }
+}
+
+/* TODO: support serving once we have the cue serve command.
+Serve: {
+ port: int
+
+ cert: string
+ key: string
+
+ handle <Pattern>: Message & {
+ pattern: Pattern
+ }
+}
+*/
diff --git a/pkg/tool/tool.cue b/pkg/tool/tool.cue
new file mode 100644
index 0000000..c9c1b11
--- /dev/null
+++ b/pkg/tool/tool.cue
@@ -0,0 +1,170 @@
+// Copyright 2018 The CUE Authors
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Package tool defines statefull operation types for cue commands.
+//
+// This package is only visible in cue files with a _tool.cue or _tool_test.cue
+// ending.
+//
+// CUE configuration files are not influenced by and do not influence anything
+// outside the configuration itself: they are hermetic. Tools solve
+// two problems: allow outside values such as environment variables,
+// file or web contents, random generators etc. to influence configuration,
+// and allow configuration to be actionable from within the tooling itself.
+// Separating these concerns makes it clear to user when outside influences are
+// in play and the tool definition can be strict about what is allowed.
+//
+// Tools are defined in files ending with _tool.cue. These files have a
+// top-level map, "command", which defines all the tools made available through
+// the cue command.
+//
+//
+package tool
+
+// A Command specifies a user-defined command.
+Command: {
+ //
+ // 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
+
+ // A var defines a value that can be set by the command line or an
+ // environment variable.
+ //
+ // Example:
+ // var fast: {
+ // description: "run faster than anyone"
+ // value: true | bool
+ // }
+ //
+ var <name>: {
+ value: _
+ description: "" | string
+ }
+
+ // 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>: Task
+
+ // TODO:
+ // timeout?: number // in seconds
+}
+
+// A task defines a step in the execution of a command, server, or fix
+// operation.
+Task: {
+ kind: =~#"\."#
+}
+
+// import "cue/tool"
+//
+// command <Name>: { // from "cue/tool".Command
+// // usage gives a short usage pattern of the command.
+// // Example:
+// // fmt [-n] [-x] [packages]
+// 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 <Name>: { // from "cue/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 <Name>: 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 "cue/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 | null | string
+//
+// // short defines an abbreviated version of the flag.
+// // Disabled by default.
+// short: null | string
+// }
+//
+// // populate flag with the default values for
+// flag: { "\(k)": { value: v } | null for k, v in var }
+//
+// // 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 | null
+//
+// // The value retrieved from the environment variable or null
+// // if not set.
+// value: null | string | bytes
+// }
+// env: { "\(k)": { value: v } | null for k, v in var }
+// }
+//