2016-05-17 01:53:22 +03:00
|
|
|
======================
|
|
|
|
TaskGraph Mach Command
|
|
|
|
======================
|
|
|
|
|
|
|
|
The task graph is built by linking different kinds of tasks together, pruning
|
|
|
|
out tasks that are not required, then optimizing by replacing subgraphs with
|
|
|
|
links to already-completed tasks.
|
|
|
|
|
|
|
|
Concepts
|
|
|
|
--------
|
|
|
|
|
|
|
|
* *Task Kind* - Tasks are grouped by kind, where tasks of the same kind do not
|
|
|
|
have interdependencies but have substantial similarities, and may depend on
|
|
|
|
tasks of other kinds. Kinds are the primary means of supporting diversity,
|
|
|
|
in that a developer can add a new kind to do just about anything without
|
|
|
|
impacting other kinds.
|
|
|
|
|
|
|
|
* *Task Attributes* - Tasks have string attributes by which can be used for
|
|
|
|
filtering. Attributes are documented in :doc:`attributes`.
|
|
|
|
|
|
|
|
* *Task Labels* - Each task has a unique identifier within the graph that is
|
|
|
|
stable across runs of the graph generation algorithm. Labels are replaced
|
|
|
|
with TaskCluster TaskIds at the latest time possible, facilitating analysis
|
|
|
|
of graphs without distracting noise from randomly-generated taskIds.
|
|
|
|
|
|
|
|
* *Optimization* - replacement of a task in a graph with an equivalent,
|
|
|
|
already-completed task, or a null task, avoiding repetition of work.
|
|
|
|
|
|
|
|
Kinds
|
|
|
|
-----
|
|
|
|
|
|
|
|
Kinds are the focal point of this system. They provide an interface between
|
|
|
|
the large-scale graph-generation process and the small-scale task-definition
|
|
|
|
needs of different kinds of tasks. Each kind may implement task generation
|
|
|
|
differently. Some kinds may generate task definitions entirely internally (for
|
|
|
|
example, symbol-upload tasks are all alike, and very simple), while other kinds
|
|
|
|
may do little more than parse a directory of YAML files.
|
|
|
|
|
Bug 1281004: Specify test tasks more flexibly; r=gps; r=gbrown
This introduces a completely new way of specifying test task in-tree,
completely replacing the old spider-web of YAML files.
The high-level view is this:
- some configuration files are used to determine which test suites to run
for each test platform, and against which build platforms
- each test suite is then represented by a dictionary, and modified by a
sequence of transforms, duplicating as necessary (e.g., chunks), until
it becomes a task definition
The transforms allow sufficient generality to support just about any desired
configuration, with the advantage that common configurations are "easy" while
unusual configurations are supported but notable for their oddness (they
require a custom transform).
As of this commit, this system produces the same set of test graphs as the
existing YAML, modulo:
- extra.treeherder.groupName -- this was not consistent in the YAML
- extra.treeherder.build -- this is ignored by taskcluster-treeherder anyway
- mozharness command argument order
- boolean True values for environment variables are now the string "true"
- metadata -- this is now much more consistent, with task name being the label
Testing of this commit demonstrates that it produces the same set of test tasks for
the following projects (those which had special cases defined in the YAML):
- autoland
- ash (*)
- willow
- mozilla-inbound
- mozilla-central
- try:
-b do -p all -t all -u all
-b d -p linux64,linux64-asan -u reftest -t none
-b d -p linux64,linux64-asan -u reftest[x64] -t none[x64]
(*) this patch omits the linux64/debug tc-M-e10s(dt) test, which is enabled on
ash; ash will require a small changeset to re-enable this test.
IGNORE BAD COMMIT MESSAGES (because the hook flags try syntax!)
MozReview-Commit-ID: G34dg9f17Hq
--HG--
rename : taskcluster/taskgraph/kind/base.py => taskcluster/taskgraph/task/base.py
rename : taskcluster/taskgraph/kind/docker_image.py => taskcluster/taskgraph/task/docker_image.py
rename : taskcluster/taskgraph/kind/legacy.py => taskcluster/taskgraph/task/legacy.py
extra : rebase_source : 03e70902c2d3a297eb9e3ce852f8737c2550d5a6
extra : histedit_source : d4d9f4b192605af21f41d83495fc3c923759c3cb
2016-07-12 02:27:14 +03:00
|
|
|
A ``kind.yml`` file contains data about the kind, as well as referring to a
|
2016-05-17 01:53:22 +03:00
|
|
|
Python class implementing the kind in its ``implementation`` key. That
|
|
|
|
implementation may rely on lots of code shared with other kinds, or contain a
|
|
|
|
completely unique implementation of some functionality.
|
|
|
|
|
2016-06-28 01:31:06 +03:00
|
|
|
The full list of pre-defined keys in this file is:
|
|
|
|
|
|
|
|
``implementation``
|
|
|
|
Class implementing this kind, in the form ``<module-path>:<object-path>``.
|
|
|
|
This class should be a subclass of ``taskgraph.kind.base:Kind``.
|
|
|
|
|
|
|
|
``kind-dependencies``
|
|
|
|
Kinds which should be loaded before this one. This is useful when the kind
|
|
|
|
will use the list of already-created tasks to determine which tasks to
|
|
|
|
create, for example adding an upload-symbols task after every build task.
|
|
|
|
|
|
|
|
Any other keys are subject to interpretation by the kind implementation.
|
|
|
|
|
2016-05-17 01:53:22 +03:00
|
|
|
The result is a nice segmentation of implementation so that the more esoteric
|
|
|
|
in-tree projects can do their crazy stuff in an isolated kind without making
|
|
|
|
the bread-and-butter build and test configuration more complicated.
|
|
|
|
|
|
|
|
Dependencies
|
|
|
|
------------
|
|
|
|
|
Bug 1281004: Specify test tasks more flexibly; r=gps; r=gbrown
This introduces a completely new way of specifying test task in-tree,
completely replacing the old spider-web of YAML files.
The high-level view is this:
- some configuration files are used to determine which test suites to run
for each test platform, and against which build platforms
- each test suite is then represented by a dictionary, and modified by a
sequence of transforms, duplicating as necessary (e.g., chunks), until
it becomes a task definition
The transforms allow sufficient generality to support just about any desired
configuration, with the advantage that common configurations are "easy" while
unusual configurations are supported but notable for their oddness (they
require a custom transform).
As of this commit, this system produces the same set of test graphs as the
existing YAML, modulo:
- extra.treeherder.groupName -- this was not consistent in the YAML
- extra.treeherder.build -- this is ignored by taskcluster-treeherder anyway
- mozharness command argument order
- boolean True values for environment variables are now the string "true"
- metadata -- this is now much more consistent, with task name being the label
Testing of this commit demonstrates that it produces the same set of test tasks for
the following projects (those which had special cases defined in the YAML):
- autoland
- ash (*)
- willow
- mozilla-inbound
- mozilla-central
- try:
-b do -p all -t all -u all
-b d -p linux64,linux64-asan -u reftest -t none
-b d -p linux64,linux64-asan -u reftest[x64] -t none[x64]
(*) this patch omits the linux64/debug tc-M-e10s(dt) test, which is enabled on
ash; ash will require a small changeset to re-enable this test.
IGNORE BAD COMMIT MESSAGES (because the hook flags try syntax!)
MozReview-Commit-ID: G34dg9f17Hq
--HG--
rename : taskcluster/taskgraph/kind/base.py => taskcluster/taskgraph/task/base.py
rename : taskcluster/taskgraph/kind/docker_image.py => taskcluster/taskgraph/task/docker_image.py
rename : taskcluster/taskgraph/kind/legacy.py => taskcluster/taskgraph/task/legacy.py
extra : rebase_source : 03e70902c2d3a297eb9e3ce852f8737c2550d5a6
extra : histedit_source : d4d9f4b192605af21f41d83495fc3c923759c3cb
2016-07-12 02:27:14 +03:00
|
|
|
Dependencies between tasks are represented as labeled edges in the task graph.
|
|
|
|
For example, a test task must depend on the build task creating the artifact it
|
|
|
|
tests, and this dependency edge is named 'build'. The task graph generation
|
|
|
|
process later resolves these dependencies to specific taskIds.
|
2016-05-17 01:53:22 +03:00
|
|
|
|
|
|
|
Decision Task
|
|
|
|
-------------
|
|
|
|
|
|
|
|
The decision task is the first task created when a new graph begins. It is
|
|
|
|
responsible for creating the rest of the task graph.
|
|
|
|
|
Bug 1281004: Specify test tasks more flexibly; r=gps; r=gbrown
This introduces a completely new way of specifying test task in-tree,
completely replacing the old spider-web of YAML files.
The high-level view is this:
- some configuration files are used to determine which test suites to run
for each test platform, and against which build platforms
- each test suite is then represented by a dictionary, and modified by a
sequence of transforms, duplicating as necessary (e.g., chunks), until
it becomes a task definition
The transforms allow sufficient generality to support just about any desired
configuration, with the advantage that common configurations are "easy" while
unusual configurations are supported but notable for their oddness (they
require a custom transform).
As of this commit, this system produces the same set of test graphs as the
existing YAML, modulo:
- extra.treeherder.groupName -- this was not consistent in the YAML
- extra.treeherder.build -- this is ignored by taskcluster-treeherder anyway
- mozharness command argument order
- boolean True values for environment variables are now the string "true"
- metadata -- this is now much more consistent, with task name being the label
Testing of this commit demonstrates that it produces the same set of test tasks for
the following projects (those which had special cases defined in the YAML):
- autoland
- ash (*)
- willow
- mozilla-inbound
- mozilla-central
- try:
-b do -p all -t all -u all
-b d -p linux64,linux64-asan -u reftest -t none
-b d -p linux64,linux64-asan -u reftest[x64] -t none[x64]
(*) this patch omits the linux64/debug tc-M-e10s(dt) test, which is enabled on
ash; ash will require a small changeset to re-enable this test.
IGNORE BAD COMMIT MESSAGES (because the hook flags try syntax!)
MozReview-Commit-ID: G34dg9f17Hq
--HG--
rename : taskcluster/taskgraph/kind/base.py => taskcluster/taskgraph/task/base.py
rename : taskcluster/taskgraph/kind/docker_image.py => taskcluster/taskgraph/task/docker_image.py
rename : taskcluster/taskgraph/kind/legacy.py => taskcluster/taskgraph/task/legacy.py
extra : rebase_source : 03e70902c2d3a297eb9e3ce852f8737c2550d5a6
extra : histedit_source : d4d9f4b192605af21f41d83495fc3c923759c3cb
2016-07-12 02:27:14 +03:00
|
|
|
The decision task for pushes is defined in-tree, in ``.taskcluster.yml``. That
|
2016-06-20 21:33:05 +03:00
|
|
|
task description invokes ``mach taskcluster decision`` with some metadata about
|
|
|
|
the push. That mach command determines the optimized task graph, then calls
|
|
|
|
the TaskCluster API to create the tasks.
|
2016-05-17 01:53:22 +03:00
|
|
|
|
Bug 1281004: Specify test tasks more flexibly; r=gps; r=gbrown
This introduces a completely new way of specifying test task in-tree,
completely replacing the old spider-web of YAML files.
The high-level view is this:
- some configuration files are used to determine which test suites to run
for each test platform, and against which build platforms
- each test suite is then represented by a dictionary, and modified by a
sequence of transforms, duplicating as necessary (e.g., chunks), until
it becomes a task definition
The transforms allow sufficient generality to support just about any desired
configuration, with the advantage that common configurations are "easy" while
unusual configurations are supported but notable for their oddness (they
require a custom transform).
As of this commit, this system produces the same set of test graphs as the
existing YAML, modulo:
- extra.treeherder.groupName -- this was not consistent in the YAML
- extra.treeherder.build -- this is ignored by taskcluster-treeherder anyway
- mozharness command argument order
- boolean True values for environment variables are now the string "true"
- metadata -- this is now much more consistent, with task name being the label
Testing of this commit demonstrates that it produces the same set of test tasks for
the following projects (those which had special cases defined in the YAML):
- autoland
- ash (*)
- willow
- mozilla-inbound
- mozilla-central
- try:
-b do -p all -t all -u all
-b d -p linux64,linux64-asan -u reftest -t none
-b d -p linux64,linux64-asan -u reftest[x64] -t none[x64]
(*) this patch omits the linux64/debug tc-M-e10s(dt) test, which is enabled on
ash; ash will require a small changeset to re-enable this test.
IGNORE BAD COMMIT MESSAGES (because the hook flags try syntax!)
MozReview-Commit-ID: G34dg9f17Hq
--HG--
rename : taskcluster/taskgraph/kind/base.py => taskcluster/taskgraph/task/base.py
rename : taskcluster/taskgraph/kind/docker_image.py => taskcluster/taskgraph/task/docker_image.py
rename : taskcluster/taskgraph/kind/legacy.py => taskcluster/taskgraph/task/legacy.py
extra : rebase_source : 03e70902c2d3a297eb9e3ce852f8737c2550d5a6
extra : histedit_source : d4d9f4b192605af21f41d83495fc3c923759c3cb
2016-07-12 02:27:14 +03:00
|
|
|
Note that this mach command is *not* designed to be invoked directly by humans.
|
|
|
|
Instead, use the mach commands described below, supplying ``parameters.yml``
|
|
|
|
from a recent decision task. These commands allow testing everything the
|
|
|
|
decision task does except the command-line processing and the
|
|
|
|
``queue.createTask`` calls.
|
|
|
|
|
2016-05-17 01:53:22 +03:00
|
|
|
Graph Generation
|
|
|
|
----------------
|
|
|
|
|
|
|
|
Graph generation, as run via ``mach taskgraph decision``, proceeds as follows:
|
|
|
|
|
|
|
|
#. For all kinds, generate all tasks. The result is the "full task set"
|
2016-08-10 17:37:32 +03:00
|
|
|
#. Create dependency links between tasks using kind-specific mechanisms. The
|
|
|
|
result is the "full task graph".
|
2016-11-18 02:53:30 +03:00
|
|
|
#. Filter the target tasks (based on a series of filters, such as try syntax,
|
|
|
|
tree-specific specifications, etc). The result is the "target task set".
|
2016-05-17 01:53:22 +03:00
|
|
|
#. Based on the full task graph, calculate the transitive closure of the target
|
|
|
|
task set. That is, the target tasks and all requirements of those tasks.
|
|
|
|
The result is the "target task graph".
|
2017-03-10 21:17:43 +03:00
|
|
|
#. Optimize the target task graph using task-specific optimization methods.
|
2016-05-17 01:53:22 +03:00
|
|
|
The result is the "optimized task graph" with fewer nodes than the target
|
2017-03-10 21:17:43 +03:00
|
|
|
task graph. See :ref:`optimization`.
|
2016-05-17 01:53:22 +03:00
|
|
|
#. Create tasks for all tasks in the optimized task graph.
|
|
|
|
|
2016-08-10 17:37:32 +03:00
|
|
|
Transitive Closure
|
|
|
|
..................
|
|
|
|
|
|
|
|
Transitive closure is a fancy name for this sort of operation:
|
|
|
|
|
|
|
|
* start with a set of tasks
|
|
|
|
* add all tasks on which any of those tasks depend
|
|
|
|
* repeat until nothing changes
|
|
|
|
|
|
|
|
The effect is this: imagine you start with a linux32 test job and a linux64 test job.
|
|
|
|
In the first round, each test task depends on the test docker image task, so add that image task.
|
|
|
|
Each test also depends on a build, so add the linux32 and linux64 build tasks.
|
|
|
|
|
|
|
|
Then repeat: the test docker image task is already present, as are the build
|
|
|
|
tasks, but those build tasks depend on the build docker image task. So add
|
|
|
|
that build docker image task. Repeat again: this time, none of the tasks in
|
|
|
|
the set depend on a task not in the set, so nothing changes and the process is
|
|
|
|
complete.
|
|
|
|
|
|
|
|
And as you can see, the graph we've built now includes everything we wanted
|
|
|
|
(the test jobs) plus everything required to do that (docker images, builds).
|
|
|
|
|
2016-06-05 22:49:41 +03:00
|
|
|
|
2016-07-11 20:13:58 +03:00
|
|
|
Action Tasks
|
|
|
|
------------
|
|
|
|
|
|
|
|
Action Tasks are tasks which help you to schedule new jobs via Treeherder's
|
|
|
|
"Add New Jobs" feature. The Decision Task creates a YAML file named
|
|
|
|
``action.yml`` which can be used to schedule Action Tasks after suitably replacing
|
|
|
|
``{{decision_task_id}}`` and ``{{task_labels}}``, which correspond to the decision
|
|
|
|
task ID of the push and a comma separated list of task labels which need to be
|
|
|
|
scheduled.
|
|
|
|
|
|
|
|
This task invokes ``mach taskgraph action-task`` which builds up a task graph of
|
|
|
|
the requested tasks. This graph is optimized using the tasks running initially in
|
|
|
|
the same push, due to the decision task.
|
|
|
|
|
|
|
|
So for instance, if you had already requested a build task in the ``try`` command,
|
|
|
|
and you wish to add a test which depends on this build, the original build task
|
|
|
|
is re-used.
|
|
|
|
|
2016-10-04 22:48:31 +03:00
|
|
|
Action Tasks are currently scheduled by
|
|
|
|
[pulse_actions](https://github.com/mozilla/pulse_actions). This feature is only
|
|
|
|
present on ``try`` pushes for now.
|
2016-07-11 20:13:58 +03:00
|
|
|
|
2016-05-17 01:53:22 +03:00
|
|
|
Mach commands
|
|
|
|
-------------
|
|
|
|
|
|
|
|
A number of mach subcommands are available aside from ``mach taskgraph
|
|
|
|
decision`` to make this complex system more accesssible to those trying to
|
|
|
|
understand or modify it. They allow you to run portions of the
|
|
|
|
graph-generation process and output the results.
|
|
|
|
|
|
|
|
``mach taskgraph tasks``
|
|
|
|
Get the full task set
|
|
|
|
|
|
|
|
``mach taskgraph full``
|
|
|
|
Get the full task graph
|
|
|
|
|
|
|
|
``mach taskgraph target``
|
|
|
|
Get the target task set
|
|
|
|
|
|
|
|
``mach taskgraph target-graph``
|
|
|
|
Get the target task graph
|
|
|
|
|
|
|
|
``mach taskgraph optimized``
|
|
|
|
Get the optimized task graph
|
|
|
|
|
|
|
|
Each of these commands taskes a ``--parameters`` option giving a file with
|
|
|
|
parameters to guide the graph generation. The decision task helpfully produces
|
|
|
|
such a file on every run, and that is generally the easiest way to get a
|
|
|
|
parameter file. The parameter keys and values are described in
|
Bug 1281004: Specify test tasks more flexibly; r=gps; r=gbrown
This introduces a completely new way of specifying test task in-tree,
completely replacing the old spider-web of YAML files.
The high-level view is this:
- some configuration files are used to determine which test suites to run
for each test platform, and against which build platforms
- each test suite is then represented by a dictionary, and modified by a
sequence of transforms, duplicating as necessary (e.g., chunks), until
it becomes a task definition
The transforms allow sufficient generality to support just about any desired
configuration, with the advantage that common configurations are "easy" while
unusual configurations are supported but notable for their oddness (they
require a custom transform).
As of this commit, this system produces the same set of test graphs as the
existing YAML, modulo:
- extra.treeherder.groupName -- this was not consistent in the YAML
- extra.treeherder.build -- this is ignored by taskcluster-treeherder anyway
- mozharness command argument order
- boolean True values for environment variables are now the string "true"
- metadata -- this is now much more consistent, with task name being the label
Testing of this commit demonstrates that it produces the same set of test tasks for
the following projects (those which had special cases defined in the YAML):
- autoland
- ash (*)
- willow
- mozilla-inbound
- mozilla-central
- try:
-b do -p all -t all -u all
-b d -p linux64,linux64-asan -u reftest -t none
-b d -p linux64,linux64-asan -u reftest[x64] -t none[x64]
(*) this patch omits the linux64/debug tc-M-e10s(dt) test, which is enabled on
ash; ash will require a small changeset to re-enable this test.
IGNORE BAD COMMIT MESSAGES (because the hook flags try syntax!)
MozReview-Commit-ID: G34dg9f17Hq
--HG--
rename : taskcluster/taskgraph/kind/base.py => taskcluster/taskgraph/task/base.py
rename : taskcluster/taskgraph/kind/docker_image.py => taskcluster/taskgraph/task/docker_image.py
rename : taskcluster/taskgraph/kind/legacy.py => taskcluster/taskgraph/task/legacy.py
extra : rebase_source : 03e70902c2d3a297eb9e3ce852f8737c2550d5a6
extra : histedit_source : d4d9f4b192605af21f41d83495fc3c923759c3cb
2016-07-12 02:27:14 +03:00
|
|
|
:doc:`parameters`; using that information, you may modify an existing
|
|
|
|
``parameters.yml`` or create your own.
|
|
|
|
|
|
|
|
Task Parameterization
|
|
|
|
---------------------
|
|
|
|
|
|
|
|
A few components of tasks are only known at the very end of the decision task
|
|
|
|
-- just before the ``queue.createTask`` call is made. These are specified
|
|
|
|
using simple parameterized values, as follows:
|
|
|
|
|
|
|
|
``{"relative-datestamp": "certain number of seconds/hours/days/years"}``
|
|
|
|
Objects of this form will be replaced with an offset from the current time
|
|
|
|
just before the ``queue.createTask`` call is made. For example, an
|
|
|
|
artifact expiration might be specified as ``{"relative-timestamp": "1
|
|
|
|
year"}``.
|
|
|
|
|
|
|
|
``{"task-reference": "string containing <dep-name>"}``
|
|
|
|
The task definition may contain "task references" of this form. These will
|
|
|
|
be replaced during the optimization step, with the appropriate taskId for
|
|
|
|
the named dependency substituted for ``<dep-name>`` in the string.
|
|
|
|
Multiple labels may be substituted in a single string, and ``<<>`` can be
|
|
|
|
used to escape a literal ``<``.
|
2016-05-17 01:53:22 +03:00
|
|
|
|
2016-06-05 22:49:41 +03:00
|
|
|
Taskgraph JSON Format
|
|
|
|
---------------------
|
|
|
|
|
2016-06-09 19:15:23 +03:00
|
|
|
Task graphs -- both the graph artifacts produced by the decision task and those
|
|
|
|
output by the ``--json`` option to the ``mach taskgraph`` commands -- are JSON
|
|
|
|
objects, keyed by label, or for optimized task graphs, by taskId. For
|
|
|
|
convenience, the decision task also writes out ``label-to-taskid.json``
|
|
|
|
containing a mapping from label to taskId. Each task in the graph is
|
|
|
|
represented as a JSON object.
|
2016-06-07 06:09:48 +03:00
|
|
|
|
|
|
|
Each task has the following properties:
|
|
|
|
|
2017-03-10 07:14:30 +03:00
|
|
|
``kind``
|
|
|
|
The name of this task's kind
|
|
|
|
|
2016-06-07 06:09:48 +03:00
|
|
|
``task_id``
|
|
|
|
The task's taskId (only for optimized task graphs)
|
2016-06-05 22:49:41 +03:00
|
|
|
|
|
|
|
``label``
|
2016-06-07 06:09:48 +03:00
|
|
|
The task's label
|
2016-06-05 22:49:41 +03:00
|
|
|
|
|
|
|
``attributes``
|
|
|
|
The task's attributes
|
|
|
|
|
|
|
|
``dependencies``
|
2016-06-07 06:09:48 +03:00
|
|
|
The task's in-graph dependencies, represented as an object mapping
|
|
|
|
dependency name to label (or to taskId for optimized task graphs)
|
2016-06-05 22:49:41 +03:00
|
|
|
|
2017-03-10 07:14:30 +03:00
|
|
|
``optimizations``
|
|
|
|
The optimizations to be applied to this task
|
|
|
|
|
2016-06-05 22:49:41 +03:00
|
|
|
``task``
|
|
|
|
The task's TaskCluster task definition.
|
|
|
|
|
|
|
|
The results from each command are in the same format, but with some differences
|
|
|
|
in the content:
|
|
|
|
|
|
|
|
* The ``tasks`` and ``target`` subcommands both return graphs with no edges.
|
|
|
|
That is, just collections of tasks without any dependencies indicated.
|
|
|
|
|
2016-06-07 06:09:48 +03:00
|
|
|
* The ``optimized`` subcommand returns tasks that have been assigned taskIds.
|
|
|
|
The dependencies array, too, contains taskIds instead of labels, with
|
|
|
|
dependencies on optimized tasks omitted. However, the ``task.dependencies``
|
|
|
|
array is populated with the full list of dependency taskIds. All task
|
|
|
|
references are resolved in the optimized graph.
|
|
|
|
|
2016-06-09 19:15:23 +03:00
|
|
|
The output of the ``mach taskgraph`` commands are suitable for processing with
|
|
|
|
the `jq <https://stedolan.github.io/jq/>`_ utility. For example, to extract all
|
|
|
|
tasks' labels and their dependencies:
|
|
|
|
|
|
|
|
.. code-block:: shell
|
|
|
|
|
|
|
|
jq 'to_entries | map({label: .value.label, dependencies: .value.dependencies})'
|
|
|
|
|