diff options
-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) |