summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSam Thursfield <sam.thursfield@codethink.co.uk>2017-11-06 16:57:32 +0000
committerSam Thursfield <sam.thursfield@codethink.co.uk>2017-11-06 16:57:32 +0000
commite187ec0e25b398619ede835df614dadf69618423 (patch)
tree4cbebc4da710aa2057c2dadabe8e3b30e9a49ccf
parent0f134712d3efb31cd1e3d53d464a8e66ee92a5f1 (diff)
downloadbuildstream-sam/bst-checkout-metadata.tar.gz
Allow checking out artifact metadata with `bst checkout`sam/bst-checkout-metadata
This commit adds a new `bst checkout --metadata` mode which checks out the artifact's build logs and metadata into a user specified directory. This is instead of the normal mode which checks out and optionally integrates the artifact's contents.
-rw-r--r--buildstream/_frontend/main.py9
-rw-r--r--buildstream/_pipeline.py32
-rw-r--r--buildstream/element.py18
3 files changed, 57 insertions, 2 deletions
diff --git a/buildstream/_frontend/main.py b/buildstream/_frontend/main.py
index 3ac6b5222..91fc750ac 100644
--- a/buildstream/_frontend/main.py
+++ b/buildstream/_frontend/main.py
@@ -504,16 +504,21 @@ def shell(app, element, sysroot, build, command):
help="Overwrite files existing in checkout directory")
@click.option('--integrate/--no-integrate', default=True, is_flag=True,
help="Whether to run integration commands")
+@click.option('--metadata', '-m', default=False, is_flag=True,
+ help="Check out the artifact's metadata, instead of the contents")
@click.argument('element',
type=click.Path(dir_okay=False, readable=True))
@click.argument('directory', type=click.Path(file_okay=False))
@click.pass_obj
-def checkout(app, element, directory, force, integrate):
+def checkout(app, element, directory, force, integrate, metadata):
"""Checkout a built artifact to the specified directory
"""
app.initialize([element])
try:
- app.pipeline.checkout(directory, force, integrate)
+ if metadata:
+ app.pipeline.checkout_metadata(directory, force)
+ else:
+ app.pipeline.checkout(directory, force, integrate)
click.echo("")
except BstError as e:
click.echo("")
diff --git a/buildstream/_pipeline.py b/buildstream/_pipeline.py
index 90ed899ea..aa0299c52 100644
--- a/buildstream/_pipeline.py
+++ b/buildstream/_pipeline.py
@@ -490,6 +490,38 @@ class Pipeline():
except OSError as e:
raise PipelineError("Failed to copy files: {}".format(e)) from e
+ # checkout_metadata()
+ #
+ # Checkout the metadata from the pipeline target artifact to the specified directory
+ #
+ # Args:
+ # directory (str): The directory to checkout the artifact to
+ # force (bool): Force overwrite files which exist in `directory`
+ #
+ def checkout_metadata(self, directory, force):
+ # We only have one target in a checkout command
+ target = self.targets[0]
+
+ try:
+ os.makedirs(directory, exist_ok=True)
+ except OSError as e:
+ raise PipelineError("Failed to create metadata checkout directory: {}".format(e)) from e
+
+ if not os.access(directory, os.W_OK):
+ raise PipelineError("Directory {} not writable".format(directory))
+
+ if not force and os.listdir(directory):
+ raise PipelineError("Checkout directory is not empty: {}"
+ .format(directory))
+
+ metadata_dirs = target.metadata_dirs()
+ with target.timed_activity("Copying metadata files to {}".format(directory)):
+ for metadata_type, metadata_dir in metadata_dirs.items():
+ try:
+ utils.copy_files(metadata_dir, os.path.join(directory, metadata_type))
+ except OSError as e:
+ raise PipelineError("Failed to copy files: {}".format(e)) from e
+
# open_workspace
#
# Open a project workspace.
diff --git a/buildstream/element.py b/buildstream/element.py
index 86dd2b8dc..d2976cfe2 100644
--- a/buildstream/element.py
+++ b/buildstream/element.py
@@ -543,6 +543,24 @@ class Element(Plugin):
return None
+ def metadata_dirs(self):
+ """Return a map of the paths that contain the artifact's metadata.
+
+ The paths will point inside the artifact cache and must be treated
+ as read-only.
+
+ Returns:
+ (dict): A dictionary mapping each type of metadata to the
+ location where it is stored.
+ """
+
+ self._assert_cached()
+ artifact_base = self.__artifacts.extract(self)
+ return {
+ 'logs': os.path.join(artifact_base, 'logs'),
+ 'meta': os.path.join(artifact_base, 'meta'),
+ }
+
#############################################################
# Abstract Element Methods #
#############################################################