You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@buildstream.apache.org by tv...@apache.org on 2021/02/04 07:47:35 UTC
[buildstream] 10/13: cli: Add artifact diff subcommand
This is an automated email from the ASF dual-hosted git repository.
tvb pushed a commit to branch richardmaw/artifact-subcommands
in repository https://gitbox.apache.org/repos/asf/buildstream.git
commit 145722b692a5757c649e197591986c78d26f6603
Author: Richard Maw <ri...@codethink.co.uk>
AuthorDate: Wed Dec 12 18:47:52 2018 +0000
cli: Add artifact diff subcommand
---
buildstream/_frontend/cli.py | 47 +++++++++++++++++++++++++++++++++++++++++++-
1 file changed, 46 insertions(+), 1 deletion(-)
diff --git a/buildstream/_frontend/cli.py b/buildstream/_frontend/cli.py
index 139d902..8cfe638 100644
--- a/buildstream/_frontend/cli.py
+++ b/buildstream/_frontend/cli.py
@@ -146,7 +146,7 @@ def override_completions(cmd, cmd_param, args, incomplete):
cmd_param.opts == ['--track'] or
cmd_param.opts == ['--track-except']):
return complete_target(args, incomplete)
- if cmd_param.name == 'artifacts':
+ if cmd_param.name in ('artifacts', 'artifact_orig', 'artifact_new'):
complete_list = complete_target(args, incomplete)
complete_list.extend(complete_artifact(args, incomplete))
return complete_list
@@ -1243,6 +1243,51 @@ def artifact_list_contents(app, null, artifacts):
print(sentinel.join(vdir.list_relative_paths()), end=sentinel)
+#################################################################
+# Artifact Diff Command #
+#################################################################
+@artifact.command(name='diff', short_help="Compute the difference between two artifacts")
+@click.option('--null', '-z', default=False, is_flag=True,
+ help="Separate tokens with NUL bytes instead of newlines")
+@click.argument('artifact_orig', type=click.Path(), nargs=1)
+@click.argument('artifact_new', type=click.Path(), nargs=1)
+@click.pass_obj
+def artifact_diff(app, null, artifact_orig, artifact_new):
+ """List the differences between artifacts"""
+ from .._pipeline import PipelineSelection
+
+ sentinel = '\0' if null else '\n'
+
+ with app.initialized():
+ cache = app.context.artifactcache
+
+ def parse_artifact_ref(artifact_ref):
+ elements, artifacts = _classify_artifacts((artifact_ref,), cache.cas,
+ app.project.directory)
+ if len(elements) + len(artifacts) > 1:
+ raise AppError("{} expanded to multiple artifacts".format(artifact_ref))
+
+ if artifacts:
+ return artifacts[0]
+
+ elements = app.stream.load_selection(elements, selection=PipelineSelection.NONE)
+ element = elements[0]
+ if not element._cached():
+ raise AppError("Element {} is not cached".format(artifact_ref))
+ return cache.get_artifact_fullname(element, element._get_cache_key())
+
+ orig = parse_artifact_ref(artifact_orig)
+ new = parse_artifact_ref(artifact_new)
+
+ modified, removed, added = cache.cas.diff(orig, new, subdir="files")
+ if modified:
+ print(sentinel.join('modified ' + path for path in modified), end=sentinel)
+ if removed:
+ print(sentinel.join('removed ' + path for path in removed), end=sentinel)
+ if added:
+ print(sentinel.join('added ' + path for path in added), end=sentinel)
+
+
##################################################################
# DEPRECATED Commands #
##################################################################