From b6a206e5e434adf11797f41eae1fc3f0c686f5ce Mon Sep 17 00:00:00 2001 From: Stephen Rosen Date: Thu, 18 Jan 2024 09:29:48 -0600 Subject: [PATCH 1/4] fix: remove "versioning" from jsonschema defs This removes the "3" nested in `definitions` which makes the contents of `definitions` pass JSON Schema metaschema validation even when the contents are not valid subschemas. `definitions` SHOULD contain subschemas as its values, with no intermediate keys. (This is a MUST in later JSON Schema spec versions, in which the key switches from `definitions` to `$defs` as a related change.) The contents are intentionally *not* dedented to make review easier. --- docs/static/schema.json | 80 ++++++++++++++++++++--------------------- 1 file changed, 39 insertions(+), 41 deletions(-) diff --git a/docs/static/schema.json b/docs/static/schema.json index b9d45292b2..c2085d270f 100644 --- a/docs/static/schema.json +++ b/docs/static/schema.json @@ -3,9 +3,8 @@ "title": "Taskfile YAML Schema", "description": "Schema for Taskfile files.", "definitions": { - "3": { "env": { - "$ref": "#/definitions/3/vars" + "$ref": "#/definitions/vars" }, "tasks": { "type": "object", @@ -23,13 +22,13 @@ "type": "string" }, { - "$ref": "#/definitions/3/task_call" + "$ref": "#/definitions/task_call" } ] } }, { - "$ref": "#/definitions/3/task" + "$ref": "#/definitions/task" } ] } @@ -41,11 +40,11 @@ "properties": { "cmds": { "description": "A list of commands to be executed.", - "$ref": "#/definitions/3/cmds" + "$ref": "#/definitions/cmds" }, "cmd": { "description": "The command to be executed.", - "$ref": "#/definitions/3/cmd" + "$ref": "#/definitions/cmd" }, "deps": { "description": "A list of dependencies of this task. Tasks defined here will run in parallel before this task.", @@ -56,7 +55,7 @@ "type": "string" }, { - "$ref": "#/definitions/3/task_call" + "$ref": "#/definitions/task_call" } ] } @@ -88,14 +87,14 @@ "description": "A list of sources to check before running this task. Relevant for `checksum` and `timestamp` methods. Can be file paths or star globs.", "type": "array", "items": { - "$ref": "#/definitions/3/glob" + "$ref": "#/definitions/glob" } }, "generates": { "description": "A list of files meant to be generated by this task. Relevant for `timestamp` method. Can be file paths or star globs.", "type": "array", "items": { - "$ref": "#/definitions/3/glob" + "$ref": "#/definitions/glob" } }, "status": { @@ -109,7 +108,7 @@ "description": "A list of commands to check if this task should run. If a condition is not met, the task will error.", "type": "array", "items": { - "$ref": "#/definitions/3/precondition" + "$ref": "#/definitions/precondition" } }, "dir": { @@ -120,23 +119,23 @@ "description": "Enables POSIX shell options for all of a task's commands. See https://www.gnu.org/software/bash/manual/html_node/The-Set-Builtin.html", "type": "array", "items": { - "$ref": "#/definitions/3/set" + "$ref": "#/definitions/set" } }, "shopt": { "description": "Enables Bash shell options for all of a task's commands. See https://www.gnu.org/software/bash/manual/html_node/The-Shopt-Builtin.html", "type": "array", "items": { - "$ref": "#/definitions/3/shopt" + "$ref": "#/definitions/shopt" } }, "vars": { "description": "A set of variables that can be used in the task.", - "$ref": "#/definitions/3/vars" + "$ref": "#/definitions/vars" }, "env": { "description": "A set of environment variables that will be made available to shell commands.", - "$ref": "#/definitions/3/env" + "$ref": "#/definitions/env" }, "dotenv": { "description": "A list of `.env` file paths to be parsed.", @@ -176,7 +175,7 @@ }, "run": { "description": "Specifies whether the task should run again or not if called more than once. Available options: `always`, `once` and `when_changed`.", - "$ref": "#/definitions/3/run" + "$ref": "#/definitions/run" }, "platforms": { "description": "Specifies which platforms the task should be run on.", @@ -187,7 +186,7 @@ }, "requires": { "description": "A list of variables which should be set if this task is to run, if any of these variables are unset the task will error and not run", - "$ref": "#/definitions/3/requires_obj" + "$ref": "#/definitions/requires_obj" }, "watch": { "description": "Configures a task to run in watch mode automatically.", @@ -199,7 +198,7 @@ "cmds": { "type": "array", "items": { - "$ref": "#/definitions/3/cmd" + "$ref": "#/definitions/cmd" } }, "cmd": { @@ -208,16 +207,16 @@ "type": "string" }, { - "$ref": "#/definitions/3/cmd_call" + "$ref": "#/definitions/cmd_call" }, { - "$ref": "#/definitions/3/task_call" + "$ref": "#/definitions/task_call" }, { - "$ref": "#/definitions/3/defer_call" + "$ref": "#/definitions/defer_call" }, { - "$ref": "#/definitions/3/for_call" + "$ref": "#/definitions/for_call" } ] }, @@ -252,7 +251,7 @@ "type": ["boolean", "integer", "null", "number", "string", "object", "array"] }, { - "$ref": "#/definitions/3/var_subkey" + "$ref": "#/definitions/var_subkey" } ] } @@ -293,7 +292,7 @@ }, "vars": { "description": "Values passed to the task called", - "$ref": "#/definitions/3/vars" + "$ref": "#/definitions/vars" }, "silent": { "description": "Hides task name and command from output. The command's output will still be redirected to `STDOUT` and `STDERR`.", @@ -318,14 +317,14 @@ "description": "Enables POSIX shell options for this command. See https://www.gnu.org/software/bash/manual/html_node/The-Set-Builtin.html", "type": "array", "items": { - "$ref": "#/definitions/3/set" + "$ref": "#/definitions/set" } }, "shopt": { "description": "Enables Bash shell options for this command. See https://www.gnu.org/software/bash/manual/html_node/The-Shopt-Builtin.html", "type": "array", "items": { - "$ref": "#/definitions/3/shopt" + "$ref": "#/definitions/shopt" } }, "ignore_error": { @@ -372,13 +371,13 @@ "for": { "anyOf": [ { - "$ref": "#/definitions/3/for_list" + "$ref": "#/definitions/for_list" }, { - "$ref": "#/definitions/3/for_attribute" + "$ref": "#/definitions/for_attribute" }, { - "$ref": "#/definitions/3/for_var" + "$ref": "#/definitions/for_var" } ] }, @@ -396,7 +395,7 @@ }, "vars": { "description": "Values passed to the task called", - "$ref": "#/definitions/3/vars" + "$ref": "#/definitions/vars" } }, "oneOf": [ @@ -445,7 +444,7 @@ "type": "string" }, { - "$ref": "#/definitions/3/precondition_obj" + "$ref": "#/definitions/precondition_obj" } ] }, @@ -468,7 +467,7 @@ "type": "string" }, { - "$ref": "#/definitions/3/glob_obj" + "$ref": "#/definitions/glob_obj" } ] }, @@ -523,7 +522,6 @@ } } } - } }, "allOf": [ { @@ -545,8 +543,8 @@ "output": { "description": "Defines how the STDOUT and STDERR are printed when running tasks in parallel. The interleaved output prints lines in real time (default). The group output will print the entire output of a command once, after it finishes, so you won't have live feedback for commands that take a long time to run. The prefix output will prefix every line printed by a command with [task-name] as the prefix, but you can customize the prefix for a command with the prefix: attribute.", "anyOf": [ - { "$ref": "#/definitions/3/outputString" }, - { "$ref": "#/definitions/3/outputObject" } + { "$ref": "#/definitions/outputString" }, + { "$ref": "#/definitions/outputObject" } ] }, "method": { @@ -592,7 +590,7 @@ }, "vars": { "description": "A set of variables to apply to the included Taskfile.", - "$ref": "#/definitions/3/vars" + "$ref": "#/definitions/vars" } } } @@ -602,15 +600,15 @@ }, "vars": { "description": "A set of global variables.", - "$ref": "#/definitions/3/vars" + "$ref": "#/definitions/vars" }, "env": { "description": "A set of global environment variables.", - "$ref": "#/definitions/3/env" + "$ref": "#/definitions/env" }, "tasks": { "description": "A set of task definitions.", - "$ref": "#/definitions/3/tasks" + "$ref": "#/definitions/tasks" }, "silent": { "description": "Default 'silent' options for this Taskfile. If `false`, can be overidden with `true` in a task by task basis.", @@ -620,14 +618,14 @@ "description": "Enables POSIX shell options for all commands in the Taskfile. See https://www.gnu.org/software/bash/manual/html_node/The-Set-Builtin.html", "type": "array", "items": { - "$ref": "#/definitions/3/set" + "$ref": "#/definitions/set" } }, "shopt": { "description": "Enables Bash shell options for all commands in the Taskfile. See https://www.gnu.org/software/bash/manual/html_node/The-Shopt-Builtin.html", "type": "array", "items": { - "$ref": "#/definitions/3/shopt" + "$ref": "#/definitions/shopt" } }, "dotenv": { @@ -639,7 +637,7 @@ }, "run": { "description": "Default 'run' option for this Taskfile. Available options: `always`, `once` and `when_changed`.", - "$ref": "#/definitions/3/run" + "$ref": "#/definitions/run" }, "interval": { "description": "Sets a different watch interval when using `--watch`, the default being 5 seconds. This string should be a valid Go duration: https://pkg.go.dev/time#ParseDuration.", From fac484d2dd2552d29a3bbc6e72be8459ab4603e6 Mon Sep 17 00:00:00 2001 From: Stephen Rosen Date: Thu, 18 Jan 2024 12:05:49 -0600 Subject: [PATCH 2/4] refactor: dedent JSON Schema 'definitions' The default git diff algorithm isn't great at showing this because it incorrectly matches some closing blocks against other, distant, closing blocks. But this is all just a two-space dedent. --- docs/static/schema.json | 952 ++++++++++++++++++++-------------------- 1 file changed, 476 insertions(+), 476 deletions(-) diff --git a/docs/static/schema.json b/docs/static/schema.json index c2085d270f..2bb4e469cc 100644 --- a/docs/static/schema.json +++ b/docs/static/schema.json @@ -3,525 +3,525 @@ "title": "Taskfile YAML Schema", "description": "Schema for Taskfile files.", "definitions": { - "env": { - "$ref": "#/definitions/vars" - }, - "tasks": { - "type": "object", - "patternProperties": { - "^.*$": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "array", - "items": { - "oneOf": [ - { - "type": "string" - }, - { - "$ref": "#/definitions/task_call" - } - ] - } - }, - { - "$ref": "#/definitions/task" - } - ] - } - } - }, - "task": { - "type": "object", - "additionalProperties": false, - "properties": { - "cmds": { - "description": "A list of commands to be executed.", - "$ref": "#/definitions/cmds" - }, - "cmd": { - "description": "The command to be executed.", - "$ref": "#/definitions/cmd" - }, - "deps": { - "description": "A list of dependencies of this task. Tasks defined here will run in parallel before this task.", - "type": "array", - "items": { - "oneOf": [ - { - "type": "string" - }, - { - "$ref": "#/definitions/task_call" - } - ] - } - }, - "label": { - "description": "Overrides the name of the task in the output when a task is run. Supports variables.", - "type": "string" - }, - "desc": { - "description": "A short description of the task. This is displayed when calling `task --list`.", - "type": "string" - }, - "prompt": { - "description": "A prompt that will be presented before a task is run. Declining will cancel running the current and any subsequent tasks.", - "type": "string" - }, - "summary": { - "description": "A longer description of the task. This is displayed when calling `task --summary [task]`.", - "type": "string" - }, - "aliases": { - "description": "A list of alternative names by which the task can be called.", - "type": "array", - "items": { - "type": "string" - } - }, - "sources": { - "description": "A list of sources to check before running this task. Relevant for `checksum` and `timestamp` methods. Can be file paths or star globs.", - "type": "array", - "items": { - "$ref": "#/definitions/glob" - } - }, - "generates": { - "description": "A list of files meant to be generated by this task. Relevant for `timestamp` method. Can be file paths or star globs.", - "type": "array", - "items": { - "$ref": "#/definitions/glob" - } - }, - "status": { - "description": "A list of commands to check if this task should run. The task is skipped otherwise. This overrides `method`, `sources` and `generates`.", - "type": "array", - "items": { - "type": "string" - } - }, - "preconditions": { - "description": "A list of commands to check if this task should run. If a condition is not met, the task will error.", - "type": "array", - "items": { - "$ref": "#/definitions/precondition" - } - }, - "dir": { - "description": "The directory in which this task should run. Defaults to the current working directory.", - "type": "string" - }, - "set": { - "description": "Enables POSIX shell options for all of a task's commands. See https://www.gnu.org/software/bash/manual/html_node/The-Set-Builtin.html", - "type": "array", - "items": { - "$ref": "#/definitions/set" - } - }, - "shopt": { - "description": "Enables Bash shell options for all of a task's commands. See https://www.gnu.org/software/bash/manual/html_node/The-Shopt-Builtin.html", - "type": "array", - "items": { - "$ref": "#/definitions/shopt" - } - }, - "vars": { - "description": "A set of variables that can be used in the task.", - "$ref": "#/definitions/vars" - }, - "env": { - "description": "A set of environment variables that will be made available to shell commands.", - "$ref": "#/definitions/env" - }, - "dotenv": { - "description": "A list of `.env` file paths to be parsed.", - "type": "array", - "items": { - "type": "string" - } - }, - "silent": { - "description": "Hides task name and command from output. The command's output will still be redirected to `STDOUT` and `STDERR`. When combined with the `--list` flag, task descriptions will be hidden.", - "type": "boolean", - "default": false - }, - "interactive": { - "description": "Tells task that the command is interactive.", - "type": "boolean", - "default": false - }, - "internal": { - "description": "Stops a task from being callable on the command line. It will also be omitted from the output when used with `--list`.", - "type": "boolean", - "default": false - }, - "method": { - "description": "Defines which method is used to check the task is up-to-date. `timestamp` will compare the timestamp of the sources and generates files. `checksum` will check the checksum (You probably want to ignore the .task folder in your .gitignore file). `none` skips any validation and always run the task.", - "type": "string", - "enum": ["none", "checksum", "timestamp"], - "default": "none" - }, - "prefix": { - "description": "Defines a string to prefix the output of tasks running in parallel. Only used when the output mode is `prefixed`.", - "type": "string" - }, - "ignore_error": { - "description": "Continue execution if errors happen while executing commands.", - "type": "boolean" - }, - "run": { - "description": "Specifies whether the task should run again or not if called more than once. Available options: `always`, `once` and `when_changed`.", - "$ref": "#/definitions/run" - }, - "platforms": { - "description": "Specifies which platforms the task should be run on.", - "type": "array", - "items": { + "env": { + "$ref": "#/definitions/vars" + }, + "tasks": { + "type": "object", + "patternProperties": { + "^.*$": { + "anyOf": [ + { "type": "string" + }, + { + "type": "array", + "items": { + "oneOf": [ + { + "type": "string" + }, + { + "$ref": "#/definitions/task_call" + } + ] + } + }, + { + "$ref": "#/definitions/task" } - }, - "requires": { - "description": "A list of variables which should be set if this task is to run, if any of these variables are unset the task will error and not run", - "$ref": "#/definitions/requires_obj" - }, - "watch": { - "description": "Configures a task to run in watch mode automatically.", - "type": "boolean", - "default": false - } + ] } - }, - "cmds": { - "type": "array", - "items": { + } + }, + "task": { + "type": "object", + "additionalProperties": false, + "properties": { + "cmds": { + "description": "A list of commands to be executed.", + "$ref": "#/definitions/cmds" + }, + "cmd": { + "description": "The command to be executed.", "$ref": "#/definitions/cmd" - } - }, - "cmd": { - "anyOf": [ - { - "type": "string" - }, - { - "$ref": "#/definitions/cmd_call" - }, - { - "$ref": "#/definitions/task_call" - }, - { - "$ref": "#/definitions/defer_call" - }, - { - "$ref": "#/definitions/for_call" - } - ] - }, - "set": { - "type": "string", - "enum": [ - "allexport", - "a", - "errexit", - "e", - "noexec", - "n", - "noglob", - "f", - "nounset", - "u", - "xtrace", - "x", - "pipefail" - ] - }, - "shopt": { - "type": "string", - "enum": ["expand_aliases", "globstar", "nullglob"] - }, - "vars": { - "type": "object", - "patternProperties": { - "^.*$": { - "anyOf": [ + }, + "deps": { + "description": "A list of dependencies of this task. Tasks defined here will run in parallel before this task.", + "type": "array", + "items": { + "oneOf": [ { - "type": ["boolean", "integer", "null", "number", "string", "object", "array"] + "type": "string" }, { - "$ref": "#/definitions/var_subkey" + "$ref": "#/definitions/task_call" } ] } - } - }, - "var_subkey": { - "type": "object", - "properties": { - "sh": { - "type": "string", - "description": "The value will be treated as a command and the output assigned to the variable" - }, - "ref": { - "type": "string", - "description": "The value will be used to lookup the value of another variable which will then be assigned to this variable" - }, - "map": { - "type": "object", - "description": "The value will be treated as a literal map type and stored in the variable" - }, - "json": { - "type": "string", - "description": "The value will parsed as a JSON string and stored in the variable" - }, - "yaml": { - "type": "string", - "description": "The value will parsed as a YAML string and stored in the variable" - }, - "additionalProperties": false - } - }, - "task_call": { - "type": "object", - "properties": { - "task": { - "description": "Name of the task to run", + }, + "label": { + "description": "Overrides the name of the task in the output when a task is run. Supports variables.", + "type": "string" + }, + "desc": { + "description": "A short description of the task. This is displayed when calling `task --list`.", + "type": "string" + }, + "prompt": { + "description": "A prompt that will be presented before a task is run. Declining will cancel running the current and any subsequent tasks.", + "type": "string" + }, + "summary": { + "description": "A longer description of the task. This is displayed when calling `task --summary [task]`.", + "type": "string" + }, + "aliases": { + "description": "A list of alternative names by which the task can be called.", + "type": "array", + "items": { "type": "string" - }, - "vars": { - "description": "Values passed to the task called", - "$ref": "#/definitions/vars" - }, - "silent": { - "description": "Hides task name and command from output. The command's output will still be redirected to `STDOUT` and `STDERR`.", - "type": "boolean" } }, - "additionalProperties": false, - "required": ["task"] - }, - "cmd_call": { - "type": "object", - "properties": { - "cmd": { - "description": "Command to run", - "type": "string" - }, - "silent": { - "description": "Silent mode disables echoing of command before Task runs it", - "type": "boolean" - }, - "set": { - "description": "Enables POSIX shell options for this command. See https://www.gnu.org/software/bash/manual/html_node/The-Set-Builtin.html", - "type": "array", - "items": { - "$ref": "#/definitions/set" - } - }, - "shopt": { - "description": "Enables Bash shell options for this command. See https://www.gnu.org/software/bash/manual/html_node/The-Shopt-Builtin.html", - "type": "array", - "items": { - "$ref": "#/definitions/shopt" - } - }, - "ignore_error": { - "description": "Prevent command from aborting the execution of task even after receiving a status code of 1", - "type": "boolean" - }, - "platforms": { - "description": "Specifies which platforms the command should be run on.", - "type": "array", - "items": { - "type": "string" - } + "sources": { + "description": "A list of sources to check before running this task. Relevant for `checksum` and `timestamp` methods. Can be file paths or star globs.", + "type": "array", + "items": { + "$ref": "#/definitions/glob" } }, - "additionalProperties": false, - "required": ["cmd"] - }, - "defer_call": { - "type": "object", - "properties": { - "defer": { - "description": "Run a command when the task completes. This command will run even when the task fails", - "anyOf": [ - "string", - { - "type": "object", - "properties": { - "task": { - "description": "Name of the task to defer", - "type": "string" - } - }, - "additionalProperties": false - } - ] + "generates": { + "description": "A list of files meant to be generated by this task. Relevant for `timestamp` method. Can be file paths or star globs.", + "type": "array", + "items": { + "$ref": "#/definitions/glob" } }, - "additionalProperties": false, - "required": ["defer"] - }, - "for_call": { - "type": "object", - "properties": { - "for": { - "anyOf": [ - { - "$ref": "#/definitions/for_list" - }, - { - "$ref": "#/definitions/for_attribute" - }, - { - "$ref": "#/definitions/for_var" - } - ] - }, - "cmd": { - "description": "Command to run", - "type": "string" - }, - "silent": { - "description": "Silent mode disables echoing of command before Task runs it", - "type": "boolean" - }, - "task": { - "description": "Task to run", + "status": { + "description": "A list of commands to check if this task should run. The task is skipped otherwise. This overrides `method`, `sources` and `generates`.", + "type": "array", + "items": { "type": "string" - }, - "vars": { - "description": "Values passed to the task called", - "$ref": "#/definitions/vars" } }, - "oneOf": [ - {"required": ["cmd"]}, - {"required": ["task"]} - ], - "additionalProperties": false, - "required": ["for"] - }, - "for_list": { - "description": "A list of values to iterate over", - "type": "array", - "items": { + "preconditions": { + "description": "A list of commands to check if this task should run. If a condition is not met, the task will error.", + "type": "array", + "items": { + "$ref": "#/definitions/precondition" + } + }, + "dir": { + "description": "The directory in which this task should run. Defaults to the current working directory.", "type": "string" - } - }, - "for_attribute": { - "description": "The task attribute to iterate over", - "type": "string", - "enum": ["sources"] - }, - "for_var": { - "description": "Which variables to iterate over. The variable will be split using any whitespace character by default. This can be changed by using the `split` attribute.", - "type": "object", - "properties": { - "var": { - "description": "Name of the variable to iterate over", - "type": "string" - }, - "split": { - "description": "String to split the variable on", - "type": "string" - }, - "as": { - "description": "What the loop variable should be named", - "default": "ITEM", - "type": "string" + }, + "set": { + "description": "Enables POSIX shell options for all of a task's commands. See https://www.gnu.org/software/bash/manual/html_node/The-Set-Builtin.html", + "type": "array", + "items": { + "$ref": "#/definitions/set" } }, - "additionalProperties": false, - "required": ["var"] - }, - "precondition": { - "anyOf": [ - { - "type": "string" - }, - { - "$ref": "#/definitions/precondition_obj" + "shopt": { + "description": "Enables Bash shell options for all of a task's commands. See https://www.gnu.org/software/bash/manual/html_node/The-Shopt-Builtin.html", + "type": "array", + "items": { + "$ref": "#/definitions/shopt" } - ] - }, - "precondition_obj": { - "type": "object", - "properties": { - "sh": { - "description": "Command to run. If that command returns 1, the condition will fail", + }, + "vars": { + "description": "A set of variables that can be used in the task.", + "$ref": "#/definitions/vars" + }, + "env": { + "description": "A set of environment variables that will be made available to shell commands.", + "$ref": "#/definitions/env" + }, + "dotenv": { + "description": "A list of `.env` file paths to be parsed.", + "type": "array", + "items": { "type": "string" - }, - "msg": { - "description": "Failure message to display when the condition fails", + } + }, + "silent": { + "description": "Hides task name and command from output. The command's output will still be redirected to `STDOUT` and `STDERR`. When combined with the `--list` flag, task descriptions will be hidden.", + "type": "boolean", + "default": false + }, + "interactive": { + "description": "Tells task that the command is interactive.", + "type": "boolean", + "default": false + }, + "internal": { + "description": "Stops a task from being callable on the command line. It will also be omitted from the output when used with `--list`.", + "type": "boolean", + "default": false + }, + "method": { + "description": "Defines which method is used to check the task is up-to-date. `timestamp` will compare the timestamp of the sources and generates files. `checksum` will check the checksum (You probably want to ignore the .task folder in your .gitignore file). `none` skips any validation and always run the task.", + "type": "string", + "enum": ["none", "checksum", "timestamp"], + "default": "none" + }, + "prefix": { + "description": "Defines a string to prefix the output of tasks running in parallel. Only used when the output mode is `prefixed`.", + "type": "string" + }, + "ignore_error": { + "description": "Continue execution if errors happen while executing commands.", + "type": "boolean" + }, + "run": { + "description": "Specifies whether the task should run again or not if called more than once. Available options: `always`, `once` and `when_changed`.", + "$ref": "#/definitions/run" + }, + "platforms": { + "description": "Specifies which platforms the task should be run on.", + "type": "array", + "items": { "type": "string" } + }, + "requires": { + "description": "A list of variables which should be set if this task is to run, if any of these variables are unset the task will error and not run", + "$ref": "#/definitions/requires_obj" + }, + "watch": { + "description": "Configures a task to run in watch mode automatically.", + "type": "boolean", + "default": false + } + } + }, + "cmds": { + "type": "array", + "items": { + "$ref": "#/definitions/cmd" + } + }, + "cmd": { + "anyOf": [ + { + "type": "string" + }, + { + "$ref": "#/definitions/cmd_call" + }, + { + "$ref": "#/definitions/task_call" + }, + { + "$ref": "#/definitions/defer_call" + }, + { + "$ref": "#/definitions/for_call" + } + ] + }, + "set": { + "type": "string", + "enum": [ + "allexport", + "a", + "errexit", + "e", + "noexec", + "n", + "noglob", + "f", + "nounset", + "u", + "xtrace", + "x", + "pipefail" + ] + }, + "shopt": { + "type": "string", + "enum": ["expand_aliases", "globstar", "nullglob"] + }, + "vars": { + "type": "object", + "patternProperties": { + "^.*$": { + "anyOf": [ + { + "type": ["boolean", "integer", "null", "number", "string", "object", "array"] + }, + { + "$ref": "#/definitions/var_subkey" + } + ] + } + } + }, + "var_subkey": { + "type": "object", + "properties": { + "sh": { + "type": "string", + "description": "The value will be treated as a command and the output assigned to the variable" + }, + "ref": { + "type": "string", + "description": "The value will be used to lookup the value of another variable which will then be assigned to this variable" + }, + "map": { + "type": "object", + "description": "The value will be treated as a literal map type and stored in the variable" + }, + "json": { + "type": "string", + "description": "The value will parsed as a JSON string and stored in the variable" + }, + "yaml": { + "type": "string", + "description": "The value will parsed as a YAML string and stored in the variable" + }, + "additionalProperties": false + } + }, + "task_call": { + "type": "object", + "properties": { + "task": { + "description": "Name of the task to run", + "type": "string" + }, + "vars": { + "description": "Values passed to the task called", + "$ref": "#/definitions/vars" + }, + "silent": { + "description": "Hides task name and command from output. The command's output will still be redirected to `STDOUT` and `STDERR`.", + "type": "boolean" } }, - "glob": { - "anyOf": [ - { - "type": "string" - }, - { - "$ref": "#/definitions/glob_obj" + "additionalProperties": false, + "required": ["task"] + }, + "cmd_call": { + "type": "object", + "properties": { + "cmd": { + "description": "Command to run", + "type": "string" + }, + "silent": { + "description": "Silent mode disables echoing of command before Task runs it", + "type": "boolean" + }, + "set": { + "description": "Enables POSIX shell options for this command. See https://www.gnu.org/software/bash/manual/html_node/The-Set-Builtin.html", + "type": "array", + "items": { + "$ref": "#/definitions/set" } - ] - }, - "glob_obj": { - "type": "object", - "properties": { - "exclude": { - "description": "File or glob patter to exclude from the list", + }, + "shopt": { + "description": "Enables Bash shell options for this command. See https://www.gnu.org/software/bash/manual/html_node/The-Shopt-Builtin.html", + "type": "array", + "items": { + "$ref": "#/definitions/shopt" + } + }, + "ignore_error": { + "description": "Prevent command from aborting the execution of task even after receiving a status code of 1", + "type": "boolean" + }, + "platforms": { + "description": "Specifies which platforms the command should be run on.", + "type": "array", + "items": { "type": "string" } } }, - "run": { - "type": "string", - "enum": ["always", "once", "when_changed"] - }, - "outputString": { - "type": "string", - "enum": ["interleaved", "prefixed", "group"], - "default": "interleaved" - }, - "outputObject": { - "type": "object", - "properties": { - "group": { - "type": "object", - "properties": { - "begin": { - "type": "string" - }, - "end": { - "type": "string" + "additionalProperties": false, + "required": ["cmd"] + }, + "defer_call": { + "type": "object", + "properties": { + "defer": { + "description": "Run a command when the task completes. This command will run even when the task fails", + "anyOf": [ + "string", + { + "type": "object", + "properties": { + "task": { + "description": "Name of the task to defer", + "type": "string" + } }, - "error_only": { - "description": "Swallows command output on zero exit code", - "type": "boolean", - "default": false - } + "additionalProperties": false } - } + ] + } + }, + "additionalProperties": false, + "required": ["defer"] + }, + "for_call": { + "type": "object", + "properties": { + "for": { + "anyOf": [ + { + "$ref": "#/definitions/for_list" + }, + { + "$ref": "#/definitions/for_attribute" + }, + { + "$ref": "#/definitions/for_var" + } + ] + }, + "cmd": { + "description": "Command to run", + "type": "string" + }, + "silent": { + "description": "Silent mode disables echoing of command before Task runs it", + "type": "boolean" + }, + "task": { + "description": "Task to run", + "type": "string" + }, + "vars": { + "description": "Values passed to the task called", + "$ref": "#/definitions/vars" } }, - "requires_obj": { - "type": "object", - "properties": { - "vars": { - "description": "List of variables that must be defined for the task to run", - "type": "array", - "items": { + "oneOf": [ + {"required": ["cmd"]}, + {"required": ["task"]} + ], + "additionalProperties": false, + "required": ["for"] + }, + "for_list": { + "description": "A list of values to iterate over", + "type": "array", + "items": { + "type": "string" + } + }, + "for_attribute": { + "description": "The task attribute to iterate over", + "type": "string", + "enum": ["sources"] + }, + "for_var": { + "description": "Which variables to iterate over. The variable will be split using any whitespace character by default. This can be changed by using the `split` attribute.", + "type": "object", + "properties": { + "var": { + "description": "Name of the variable to iterate over", + "type": "string" + }, + "split": { + "description": "String to split the variable on", + "type": "string" + }, + "as": { + "description": "What the loop variable should be named", + "default": "ITEM", + "type": "string" + } + }, + "additionalProperties": false, + "required": ["var"] + }, + "precondition": { + "anyOf": [ + { + "type": "string" + }, + { + "$ref": "#/definitions/precondition_obj" + } + ] + }, + "precondition_obj": { + "type": "object", + "properties": { + "sh": { + "description": "Command to run. If that command returns 1, the condition will fail", + "type": "string" + }, + "msg": { + "description": "Failure message to display when the condition fails", + "type": "string" + } + } + }, + "glob": { + "anyOf": [ + { + "type": "string" + }, + { + "$ref": "#/definitions/glob_obj" + } + ] + }, + "glob_obj": { + "type": "object", + "properties": { + "exclude": { + "description": "File or glob patter to exclude from the list", + "type": "string" + } + } + }, + "run": { + "type": "string", + "enum": ["always", "once", "when_changed"] + }, + "outputString": { + "type": "string", + "enum": ["interleaved", "prefixed", "group"], + "default": "interleaved" + }, + "outputObject": { + "type": "object", + "properties": { + "group": { + "type": "object", + "properties": { + "begin": { "type": "string" + }, + "end": { + "type": "string" + }, + "error_only": { + "description": "Swallows command output on zero exit code", + "type": "boolean", + "default": false } } } } + }, + "requires_obj": { + "type": "object", + "properties": { + "vars": { + "description": "List of variables that must be defined for the task to run", + "type": "array", + "items": { + "type": "string" + } + } + } + } }, "allOf": [ { From 3b6f99631ae9f2b8043359b593d280bab6a4778b Mon Sep 17 00:00:00 2001 From: Stephen Rosen Date: Thu, 18 Jan 2024 12:07:49 -0600 Subject: [PATCH 3/4] fix: malformed `defer` definition in JSON Schema The `defer` definition listed `"string"` where `{"type":"string"}` was wanted. --- docs/static/schema.json | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/docs/static/schema.json b/docs/static/schema.json index 2bb4e469cc..3026c24ae4 100644 --- a/docs/static/schema.json +++ b/docs/static/schema.json @@ -348,7 +348,9 @@ "defer": { "description": "Run a command when the task completes. This command will run even when the task fails", "anyOf": [ - "string", + { + "type": "string" + }, { "type": "object", "properties": { From 2dd909b46879d1dab714bc5f10dce620deb9ebfb Mon Sep 17 00:00:00 2001 From: Stephen Rosen Date: Thu, 18 Jan 2024 12:29:45 -0600 Subject: [PATCH 4/4] chore: add linting CI step for the JSON Schema This is written to use `check-jsonschema` on the (current) latest version (0.27.3). It checks that the JSON Schema published in the docs is valid under its declared metaschema (`$schema`). --- .github/workflows/lint.yml | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index 6edc843a18..089706d737 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -22,3 +22,18 @@ jobs: uses: golangci/golangci-lint-action@v3 with: version: v1.55.2 + + lint-jsonschema: + runs-on: ubuntu-latest + steps: + - uses: actions/setup-python@v5 + with: + python-version: 3.12 + + - uses: actions/checkout@v3 + + - name: install check-jsonschema + run: python -m pip install 'check-jsonschema==0.27.3' + + - name: check-jsonschema (metaschema) + run: check-jsonschema --check-metaschema docs/static/schema.json