Skip to content

Commit 69494ab

Browse files
committed
Feature: Add support for generating json from bst show command
This adds a new flag called --json to the `bst show` command which when specified will make bst output a machine readable JSON dump of the dependency state within the current buildstream project. Having JSON support makes it easier to write tools that need to inspect the configuration of a buildstream enabled project.
1 parent d62a313 commit 69494ab

File tree

2 files changed

+58
-4
lines changed

2 files changed

+58
-4
lines changed

src/buildstream/_frontend/cli.py

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
import os
1515
import re
1616
import sys
17+
import json
1718
from functools import partial
1819

1920
import shutil
@@ -434,7 +435,6 @@ def init(app, project_name, min_version, element_path, force, target_directory):
434435
"""
435436
app.init_project(project_name, min_version, element_path, force, target_directory)
436437

437-
438438
##################################################################
439439
# Build Command #
440440
##################################################################
@@ -538,6 +538,7 @@ def build(
538538
@click.option(
539539
"--except", "except_", multiple=True, type=click.Path(readable=False), help="Except certain dependencies"
540540
)
541+
@click.option("--json", "as_json", is_flag=True, help="Output the information as machine readable JSON")
541542
@click.option(
542543
"--deps",
543544
"-d",
@@ -572,7 +573,7 @@ def build(
572573
)
573574
@click.argument("elements", nargs=-1, type=click.Path(readable=False))
574575
@click.pass_obj
575-
def show(app, elements, deps, except_, order, format_):
576+
def show(app, elements, deps, as_json, except_, order, format_):
576577
"""Show elements in the pipeline
577578
578579
Specifying no elements will result in showing the default targets
@@ -657,8 +658,12 @@ def show(app, elements, deps, except_, order, format_):
657658
if order == "alpha":
658659
dependencies = sorted(dependencies)
659660

660-
report = app.logger.show_pipeline(dependencies, format_)
661-
click.echo(report)
661+
if as_json:
662+
serialized = app.logger.dump_pipeline(dependencies)
663+
print(json.dumps(serialized))
664+
else:
665+
report = app.logger.show_pipeline(dependencies, format_)
666+
click.echo(report)
662667

663668

664669
##################################################################

src/buildstream/_frontend/widget.py

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -327,6 +327,55 @@ def __init__(
327327
logfile_tokens = self._parse_logfile_format(context.log_message_format, content_profile, format_profile)
328328
self._columns.extend(logfile_tokens)
329329

330+
# Dump the pipeline as a serializable object
331+
def dump_pipeline(self, dependencies):
332+
333+
elements = []
334+
335+
for element in dependencies:
336+
337+
deps = [e._get_full_name() for e in element._dependencies(_Scope.ALL, recurse=False)]
338+
build_deps = [e._get_full_name() for e in element._dependencies(_Scope.BUILD, recurse=False)]
339+
runtime_deps = [e._get_full_name() for e in element._dependencies(_Scope.RUN, recurse=False)]
340+
341+
# Artifact CAS Digest
342+
serialized_artifact = None
343+
artifact = element._get_artifact()
344+
if artifact.cached():
345+
serialized_artifact = {"files": artifact.get_files(), "digest": artifact_files._get_digest()}
346+
all_source_infos = []
347+
for source in element.sources():
348+
source_infos = source.collect_source_info()
349+
350+
if source_infos is not None:
351+
serialized_sources = []
352+
for s in source_infos:
353+
serialized = s.serialize()
354+
serialized_sources.append(serialized)
355+
356+
all_source_infos += serialized_sources
357+
358+
# assert element._has_all_sources_resolved() == True
359+
description = " ".join(element._description.splitlines())
360+
serialized_element = {
361+
"name": element._get_full_name(),
362+
"description": description,
363+
"key": element._get_display_key().brief,
364+
"key_full": element._get_display_key().full,
365+
"workspace": element._get_workspace(),
366+
"dependencies": deps,
367+
"build-dependencies": build_deps,
368+
"runtime-dependencies": runtime_deps,
369+
"variables": dict(element._Element__variables),
370+
"environment": dict(element._Element__environment),
371+
"sources": all_source_infos,
372+
"artifact": serialized_artifact,
373+
}
374+
375+
elements.append(serialized_element)
376+
377+
return elements
378+
330379
# show_pipeline()
331380
#
332381
# Display a list of elements in the specified format.

0 commit comments

Comments
 (0)