Tasks
Nova’s Tasks system offer users a freeform, highly-configurable way of running external operations from within the IDE.
The simplest way of using Tasks is by adding a simple “Custom Script” task configuration that is always available from a user’s project settings. This allows the user to define a script that will execute either on the local machine or a remote server when the configuration is run, forwarding its output to an IDE output report.
Extensions can extend this idea further in two ways:
- By offering one or more Task Templates
- By offering one or more Task Assistants
Defining a Task Template
Defining a Task template in your extension adds a new item to the project settings “Add Task” interface of a user’s Project Settings. This allows a user to instantiate your template as one or more new configurations within their project. Each configuration added references the template in your extension for configuration options, allowing the extension to evolve without the need to recreate configurations.
Templates are great for defining a user-customizable task that should persist with their project and is not necessarily reliant on other configuration files within the project.
A template defines what command is executed when the user runs a configuration created from it, along with the arguments it is passed. Arguments are defined a way that allows them to be edited by a user in the configuration editor, much like an extension’s preferences.
The extension’s extension.json
can include a taskTemplates
object defining the templates that are exposed by the extension.
Each item in the object is keyed by the template’s identifier, which should not change once an extension is released: Configurations created from it reference this identifier to determine how the configuration is executed.
The value of each item is an object defining how the template behaves.
Here is an example of a configuration which executes a local PHP development web server:
"taskTemplates": {
"webserver": {
"name": "PHP Webserver",
"description": "Runs the PHP development server.",
"persistent": true,
"tasks": {
"run": {
"shell": true,
"command": "php",
"args": [
"-S", "$(Config:php.host):$(Config:php.port)",
"-t", "$(Config:php.document-root)",
"$(Config:php.custom-args)"
],
"env": {
}
}
},
"config": [
{
"key": "php.host",
"title": "Host",
"type": "string",
"placeholder": "localhost",
"default": "localhost"
},
{
"key": "php.port",
"title": "Port",
"type": "number",
"placeholder": "8000",
"default": 8000,
"min": 1,
"max": 65535
},
{
"key": "php.document-root",
"title": "Document Root",
"type": "path",
"default": "."
},
{
"key": "php.custom-args",
"title": "Additional Arguments",
"description": "Custom arguments to pass to the PHP webserver command.",
"type": "string"
}
]
}
}
Task Actions
The most important details of a template are defined in its tasks
section. This object maps each action, by name, to an object that defines how and what process should be invoked.
Available actions are: build
, run
, clean
.
Value | Description | Notes |
---|---|---|
command | The executable command to invoke | |
shell | If true, the command will be executed within a shell | |
args | An array of interpolated strings passed to the command | |
env | Interpolated environment variables set for the command | |
matchers | An array of Issue Matcher identifiers used to automatically parse task output. | |
resolve | A string representing a task assistant identifier used to resolve the action. | Added in Nova 5. |
data | Arbitrary data that may be provided when resolving the action. | Added in Nova 5. |
buildBeforeRunning | If set to true , then the Run action will automatically invoke Build before it. |
|
persistent | If set to true , then the action will use UI elements that denote it is persistent (an action that will run for a protracted length of time, such as a preview server). |
The command value is the executable name that will be invoked by the IDE. This may be a path to a script, relative to the extension root (such as Scripts/run.sh
), or a command available on the user’s PATH
.
For most cases, be careful when specifying paths for the command. If the path is not valid on all user’s computers it can cause the run to fail. Use absolute paths when the expectation is that the tool being invoked is required to be at this location. Otherwise, use a singular command name allowing it to be resolved against the extension’s container, or use the shell
parameter allowing it to be interpreted against the user’s PATH
.
If the action to be invoked is not known when the task template is defined, a template may use the resolve value to specify a Task Assistant identifier that can resolve the task. When the action is invoked, the assistant’s resolveTaskAction()
method will be invoked to request an action instance, such as TaskProcessAction. If the data property is provided, the JSON object it specifies will be set for the context
parameter’s data
property during resolution.
Note: In previous versions of Nova (before Nova 2), the tasks
value was instead a singular task
value that could only specify one task action (for Run). This was amended to support multiple actions.
Variables
String values provided in an action template’s args and env properties can be interpolated using the Snippets format, meaning the values may contain special string substitutions that are resolved at runtime. These substitutions follow a similar format to shell substitutions: $VariableName
for singular variables, and ${Expression}
for more complex expressions. The former is simply a shorthand subset of the latter which can only contain alphanumeric characters and the underscore. The variables and expressions available include those listed below.
Named Variables
$WorkspaceName
: The name of the current workspace$WorkspaceFolder
: The full (absolute) path of the workspace, if any$WorkspaceFolderBasename
: The folder name of the workspace, if any (which may be different than the workspace name)$WorkingDirname
: The current working directory of the task being executed (effectively the same ascwd
in a shell)$File
: The full (absolute) path of the currently focused file editor, if any$FileRelative
: The relative path of the currently focused file editor against the workspace folder, if any$FileBasename
: The filename of the currently focused file editor, if any$FileDirname
: The full (absolute) path of the folder containing the currently focused file editor, if any$FileExtname
: The file extension of the currently focused file editor, if any$LineNumber
: The line number containing the primary cursor within the currently focused file editor, if any$SelectedText
: The primary selected text within the the currently focused file editor, if any
Configuration Variables
String substitution may reference values stored in the user’s global and project configuration using an expression of the form ${Config:my.config-key}
, where my.config-key
is a key for a configuration item. Expressions of this form will check the most specific configuration available first, falling back if no value is found.
The order of precedence for configurations is:
- The configuration for the task being executed
- The project configuration
- The user’s global configuration
If no value is found within a configuration, the default will be returned (if one is defined) before moving on to the next context. If no value is found, an empty string will be substituted.
Command Variables
For more complex handling of substitution, an extension Command may be invoked. This command need not be defined in an extension’s visible commands
object in its extension.json
file, it only needs to be registered with the extension’s CommandsRegistry.
Commands may be invoked by using an expression of the form ${Command:my.command-name}
, where my.command-name
is the name of the command used to register with the nova.commands.add()
of the commands registry. The command will then be invoked asynchronously by the extension runtime. If it returns a Promise
object, the runtime will wait for the promise to resolve before performing the string substitution, unless the task requesting it is cancelled before the promise resolves.
Configuration
Each template may define a config
section, which uses the same format as Preferences items. These configuration items may be referenced in the string substitution of arguments and environment passed to the template’s executable using the format $(Config:my.config-key)
. The value will be checked against those set for the configuration, as well as the user’s project and global preferences.
Deprecation
If a task template should be replaced with another, or removed entirely, an extension may optionally declare it as deprecated for any amount of time needed to inform the user that the template will be replaced or removed.
To specify a task template as deprecated, use the deprecated
property on the template object. The value of this property may be:
true
, which will show a standard deprecation notice to the user- A string, which will be shown as the deprecation notice to the user
The deprecation notice will be shown in the task template’s edit pane of the project settings.
"taskTemplates": {
"webserver": {
"name": "PHP Webserver",
"description": "Runs the PHP development server.",
"deprecated": "Consider using the other thing instead."
"tasks": {...}
}
}
Defining a Task Assistant
Added in Nova 2.
In many cases, requiring a user to add an instance of a task via a Task Template may be too much overhead. If the task in question is defined by existing files or metadata in the project and can be detected by an extension, a simpler option may be to contribute a Task Assistant.
A Task Assistant is a JavaScript object that is registered with the AssistantRegistry. It allows an extension to dynamically construct and return task objects to be displayed in the IDE interface and invoked by the user.
For more information, see the AssistantRegistry and Task classes.
For tasks that may change over time (such as in response to a user updating a configuration file, or changing configuration values in the extension), an extension may invoke the reloadTasks(identifier)
method on the global Workspace object.