diff options
author | Richard Maw <richard.maw@codethink.co.uk> | 2018-11-01 15:24:32 +0000 |
---|---|---|
committer | Richard Maw <richard.maw@codethink.co.uk> | 2018-12-12 16:32:41 +0000 |
commit | ba08a0cdb6b9f7b1a09821c88cde510056c51ec6 (patch) | |
tree | 2894794fc6a878a13a22c8389a74e4f4d80e59e3 /buildstream/_frontend/cli.py | |
parent | b3dceb16cc56bd8d1c43a7d14e2c0e98d39769c4 (diff) | |
download | buildstream-ba08a0cdb6b9f7b1a09821c88cde510056c51ec6.tar.gz |
cli: Add artifact log command
Diffstat (limited to 'buildstream/_frontend/cli.py')
-rw-r--r-- | buildstream/_frontend/cli.py | 59 |
1 files changed, 59 insertions, 0 deletions
diff --git a/buildstream/_frontend/cli.py b/buildstream/_frontend/cli.py index 67958385c..84133f608 100644 --- a/buildstream/_frontend/cli.py +++ b/buildstream/_frontend/cli.py @@ -1,6 +1,8 @@ import os import sys +from contextlib import ExitStack from fnmatch import fnmatch +from tempfile import TemporaryDirectory import click from .. import _yaml @@ -976,3 +978,60 @@ def _classify_artifacts(names, cas, project_directory): def artifact(): """Manipulate cached artifacts""" pass + + +################################################################ +# Artifact Log Command # +################################################################ +@artifact.command(name='log', short_help="Show logs of an artifact") +@click.argument('artifacts', type=click.Path(), nargs=-1) +@click.pass_obj +def artifact_log(app, artifacts): + """Show logs of all artifacts""" + from .._exceptions import CASError + from .._message import MessageType + from .._pipeline import PipelineSelection + from ..storage._casbaseddirectory import CasBasedDirectory + + with ExitStack() as stack: + stack.enter_context(app.initialized()) + cache = app.context.artifactcache + + elements, artifacts = _classify_artifacts(artifacts, cache.cas, + app.project.directory) + + vdirs = [] + extractdirs = [] + if artifacts: + for ref in artifacts: + try: + cache_id = cache.cas.resolve_ref(ref, update_mtime=True) + vdir = CasBasedDirectory(cache.cas, cache_id) + vdirs.append(vdir) + except CASError as e: + app._message(MessageType.WARN, "Artifact {} is not cached".format(ref), detail=str(e)) + continue + if elements: + elements = app.stream.load_selection(elements, selection=PipelineSelection.NONE) + for element in elements: + if not element._cached(): + app._message(MessageType.WARN, "Element {} is not cached".format(element)) + continue + ref = cache.get_artifact_fullname(element, element._get_cache_key()) + cache_id = cache.cas.resolve_ref(ref, update_mtime=True) + vdir = CasBasedDirectory(cache.cas, cache_id) + vdirs.append(vdir) + + for vdir in vdirs: + # NOTE: If reading the logs feels unresponsive, here would be a good place to provide progress information. + logsdir = vdir.descend(["logs"]) + td = stack.enter_context(TemporaryDirectory()) + logsdir.export_files(td, can_link=True) + extractdirs.append(td) + + for extractdir in extractdirs: + for log in (os.path.join(extractdir, log) for log in os.listdir(extractdir)): + # NOTE: Should click gain the ability to pass files to the pager this can be optimised. + with open(log) as f: + data = f.read() + click.echo_via_pager(data) |