From 821fd8962bc63c9a3b435ea36058eb9fda7771f1 Mon Sep 17 00:00:00 2001 From: James Ennis Date: Thu, 29 Aug 2019 12:32:21 +0100 Subject: cli.py: Allow pull to handle artifact refs This patch adds support for the handling of artifact refs in bst artifact pull. A test for this has also been added. --- src/buildstream/_frontend/cli.py | 10 +++++----- tests/frontend/pull.py | 42 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 47 insertions(+), 5 deletions(-) diff --git a/src/buildstream/_frontend/cli.py b/src/buildstream/_frontend/cli.py index c492254ce..132f7f71a 100644 --- a/src/buildstream/_frontend/cli.py +++ b/src/buildstream/_frontend/cli.py @@ -1135,10 +1135,10 @@ def artifact_checkout(app, force, deps, integrate, hardlinks, tar, compression, help='The dependency artifacts to pull') @click.option('--remote', '-r', default=None, help="The URL of the remote cache (defaults to the first configured cache)") -@click.argument('elements', nargs=-1, +@click.argument('artifacts', nargs=-1, type=click.Path(readable=False)) @click.pass_obj -def artifact_pull(app, elements, deps, remote): +def artifact_pull(app, artifacts, deps, remote): """Pull a built artifact from the configured remote artifact cache. Specifying no elements will result in pulling the default targets @@ -1162,12 +1162,12 @@ def artifact_pull(app, elements, deps, remote): with app.initialized(session_name="Pull"): ignore_junction_targets = False - if not elements: - elements = app.project.get_default_targets() + if not artifacts: + artifacts = app.project.get_default_targets() # Junction elements cannot be pulled, exclude them from default targets ignore_junction_targets = True - app.stream.pull(elements, selection=deps, remote=remote, + app.stream.pull(artifacts, selection=deps, remote=remote, ignore_junction_targets=ignore_junction_targets) diff --git a/tests/frontend/pull.py b/tests/frontend/pull.py index fd49ff1ef..f978258f1 100644 --- a/tests/frontend/pull.py +++ b/tests/frontend/pull.py @@ -558,3 +558,45 @@ def test_pull_access_rights(cli, tmpdir, datafiles): st = os.lstat(os.path.join(checkout, 'usr/share/big-file')) assert stat.S_ISREG(st.st_mode) assert stat.S_IMODE(st.st_mode) == 0o0644 + + +# Tests `bst artifact pull $artifact_ref` +@pytest.mark.datafiles(DATA_DIR) +def test_pull_artifact(cli, tmpdir, datafiles): + project = str(datafiles) + element = 'target.bst' + + # Configure a local cache + local_cache = os.path.join(str(tmpdir), 'cache') + cli.configure({'cachedir': local_cache}) + + with create_artifact_share(os.path.join(str(tmpdir), 'artifactshare')) as share: + + # First build the target element and push to the remote. + cli.configure({ + 'artifacts': {'url': share.repo, 'push': True} + }) + + result = cli.run(project=project, args=['build', element]) + result.assert_success() + + # Assert that the *artifact* is cached locally + cache_key = cli.get_element_key(project, element) + artifact_ref = os.path.join('test', os.path.splitext(element)[0], cache_key) + assert os.path.exists(os.path.join(local_cache, 'artifacts', 'refs', artifact_ref)) + + # Assert that the target is shared (note that assert shared will use the artifact name) + assert_shared(cli, share, project, element) + + # Now we've pushed, remove the local cache + shutil.rmtree(os.path.join(local_cache, 'artifacts')) + + # Assert that nothing is cached locally anymore + assert not os.path.exists(os.path.join(local_cache, 'artifacts', 'refs', artifact_ref)) + + # Now try bst artifact pull + result = cli.run(project=project, args=['artifact', 'pull', artifact_ref]) + result.assert_success() + + # And assert that it's again in the local cache, without having built + assert os.path.exists(os.path.join(local_cache, 'artifacts', 'refs', artifact_ref)) -- cgit v1.2.1