Bug 1229178: modify --json output to contain a single object draft
authorDustin J. Mitchell <dustin@mozilla.com>
Thu, 09 Jun 2016 11:15:23 -0500
changeset 383246 f95ebfde7b73d871ca9c309eedc7dfcbe6406364
parent 383245 e405b8a20f4a642369f72c030f62a2f9c80ec632
child 524419 a187decd85436842c2156f196db5f84cc7562252
push id21963
push userdmitchell@mozilla.com
push dateFri, 01 Jul 2016 19:54:18 +0000
bugs1229178
milestone50.0a1
Bug 1229178: modify --json output to contain a single object MozReview-Commit-ID: DNlxPfQh3o0
taskcluster/docs/taskgraph.rst
taskcluster/mach_commands.py
--- a/taskcluster/docs/taskgraph.rst
+++ b/taskcluster/docs/taskgraph.rst
@@ -158,18 +158,22 @@ parameter file.  The parameter keys and 
 Finally, the ``mach taskgraph decision`` subcommand performs the entire
 task-graph generation process, then creates the tasks.  This command should
 only be used within a decision task, as it assumes it is running in that
 context.
 
 Taskgraph JSON Format
 ---------------------
 
-Each task in the graph is represented as a JSON object.  The output is suitable
-for processing with the `jq <https://stedolan.github.io/jq/>`_ utility.
+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.
 
 Each task has the following properties:
 
 ``task_id``
    The task's taskId (only for optimized task graphs)
 
 ``label``
    The task's label
@@ -197,12 +201,16 @@ in the content:
   That is, just collections of tasks without any dependencies indicated.
 
 * 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.
 
-The graph artifacts produced by the decision task are JSON objects, keyed by
-label (``full-task-graph.json`` and ``target-tasks``) or by taskId
-(``task-graph.json``).  For convenience, the decision task also writes out
-``label-to-taskid.json`` containing a mapping from label to taskId.
+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})'
+
--- a/taskcluster/mach_commands.py
+++ b/taskcluster/mach_commands.py
@@ -32,17 +32,17 @@ class ShowTaskGraphSubCommand(SubCommand
             CommandArgument('--root', '-r', default='taskcluster/ci',
                             help="root of the taskgraph definition relative to topsrcdir"),
             CommandArgument('--quiet', '-q', action="store_true",
                             help="suppress all logging output"),
             CommandArgument('--verbose', '-v', action="store_true",
                             help="include debug-level logging output"),
             CommandArgument('--json', '-J', action="store_const",
                             dest="format", const="json",
-                            help="Output each task in the task graph as a JSON object"),
+                            help="Output task graph as a JSON object"),
             CommandArgument('--labels', '-L', action="store_const",
                             dest="format", const="labels",
                             help="Output the label for each task in the task graph (default)"),
             CommandArgument('--parameters', '-p', required=True,
                             help="parameters file (.yml or .json; see "
                                  "`taskcluster/docs/parameters.rst`)`"),
             CommandArgument('--no-optimize', dest="optimize", action="store_false",
                             default="true",
@@ -194,20 +194,18 @@ class MachCommands(MachCommandBase):
             traceback.print_exc()
             sys.exit(1)
 
     def show_taskgraph_labels(self, taskgraph):
         for label in taskgraph.graph.visit_postorder():
             print(label)
 
     def show_taskgraph_json(self, taskgraph):
-        # JSON output is a sequence of JSON objects, rather than a single object, so
-        # disassemble the dictionary
-        for task in taskgraph.to_json().itervalues():
-            print(json.dumps(task))
+        print(json.dumps(taskgraph.to_json(),
+              sort_keys=True, indent=2, separators=(',', ': ')))
 
 
 @CommandProvider
 class LoadImage(object):
     @Command('taskcluster-load-image', category="ci",
              description="Load a pre-built Docker image")
     @CommandArgument('--task-id',
                      help="Load the image at public/image.tar in this task,"