summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJames Ennis <james.ennis@codethink.co.uk>2019-08-01 12:06:02 +0100
committerJames Ennis <james.ennis@codethink.com>2019-08-06 13:03:47 +0000
commitef757b5e8ee7d1bfab8750d4a87cbc374eda295e (patch)
tree1ed88743f0d11200c87ffeaed740f294504568be
parent34529551faf0c1206e5fe887355da882a5c32c9e (diff)
downloadbuildstream-ef757b5e8ee7d1bfab8750d4a87cbc374eda295e.tar.gz
plugins/elements/junction.py: Add 'cache-junction-elements' option
The 'cache-junction-elements' configuration option for junction's is a boolean which enables elements from within the junction to interact with the parent project's remote(s). A test has been added to enforce this behaviour and the BST_FORMAT_VERSION has been bumped.
-rw-r--r--src/buildstream/_project.py6
-rw-r--r--src/buildstream/_versions.py2
-rw-r--r--src/buildstream/plugins/elements/junction.py9
-rw-r--r--tests/artifactcache/junctions.py46
4 files changed, 61 insertions, 2 deletions
diff --git a/src/buildstream/_project.py b/src/buildstream/_project.py
index 8d06c7cef..3a5923f80 100644
--- a/src/buildstream/_project.py
+++ b/src/buildstream/_project.py
@@ -645,6 +645,12 @@ class Project():
# Load artifacts pull/push configuration for this project
self.artifact_cache_specs = ArtifactCache.specs_from_config_node(config, self.directory)
+ # If there is a junction Element which specifies that we want to remotely cache
+ # its elements, append the junction's remotes to the artifact cache specs list
+ if self.junction and self.junction.cache_junction_elements:
+ parent = self.junction._get_project()
+ self.artifact_cache_specs = parent.artifact_cache_specs + self.artifact_cache_specs
+
# Load source caches with pull/push config
self.source_cache_specs = SourceCache.specs_from_config_node(config, self.directory)
diff --git a/src/buildstream/_versions.py b/src/buildstream/_versions.py
index c439f59fb..cbaa52e4f 100644
--- a/src/buildstream/_versions.py
+++ b/src/buildstream/_versions.py
@@ -23,7 +23,7 @@
# This version is bumped whenever enhancements are made
# to the `project.conf` format or the core element format.
#
-BST_FORMAT_VERSION = 24
+BST_FORMAT_VERSION = 25
# The base BuildStream artifact version
diff --git a/src/buildstream/plugins/elements/junction.py b/src/buildstream/plugins/elements/junction.py
index b21ef0777..235702b07 100644
--- a/src/buildstream/plugins/elements/junction.py
+++ b/src/buildstream/plugins/elements/junction.py
@@ -55,10 +55,16 @@ Overview
# Note that this option cannot be used in conjunction with sources.
target: sub-project.bst:sub-sub-project.bst
+ # Optionally declare whether elements within the junction project
+ # should interact with project remotes (default: False).
+ cache-junction-elements: False
+
.. note::
The configuration option to allow specifying junction targets is available
- since :ref:`format version 24 <project_format_version>`.
+ since :ref:`format version 24 <project_format_version>` and the configuration
+ option allowing junction project elements to interact with parent remotes is
+ available since :ref:`format version 25 <project_format_version>`.
.. note::
@@ -180,6 +186,7 @@ class JunctionElement(Element):
self.target = node.get_str('target', default=None)
self.target_element = None
self.target_junction = None
+ self.cache_junction_elements = node.get_bool('cache-junction-elements', default=False)
def preflight(self):
# "target" cannot be used in conjunction with:
diff --git a/tests/artifactcache/junctions.py b/tests/artifactcache/junctions.py
index c93d79c4b..bfddcedac 100644
--- a/tests/artifactcache/junctions.py
+++ b/tests/artifactcache/junctions.py
@@ -87,3 +87,49 @@ def test_push_pull(cli, tmpdir, datafiles):
assert state == 'cached'
state = cli.get_element_state(base_project, 'base-element.bst')
assert state == 'cached'
+
+
+@pytest.mark.datafiles(DATA_DIR)
+def test_caching_junction_elements(cli, tmpdir, datafiles):
+ project = os.path.join(str(datafiles), 'parent')
+ base_project = os.path.join(str(project), 'base')
+
+ # Load the junction element
+ junction_element = os.path.join(project, 'base.bst')
+ junction_data = _yaml.roundtrip_load(junction_element)
+
+ # Add the "cache-junction-elements" boolean to the junction Element
+ junction_data['config'] = {"cache-junction-elements": True}
+ _yaml.roundtrip_dump(junction_data, junction_element)
+
+ with create_artifact_share(os.path.join(str(tmpdir), 'artifactshare-parent')) as share,\
+ create_artifact_share(os.path.join(str(tmpdir), 'artifactshare-base')) as base_share:
+
+ # First build it without the artifact cache configured
+ result = cli.run(project=project, args=['build', 'target.bst'])
+ assert result.exit_code == 0
+
+ # Assert that we are now cached locally
+ state = cli.get_element_state(project, 'target.bst')
+ assert state == 'cached'
+ state = cli.get_element_state(base_project, 'base-element.bst')
+ assert state == 'cached'
+
+ project_set_artifacts(project, share.repo)
+ project_set_artifacts(base_project, base_share.repo)
+
+ # Now try bst artifact push
+ result = cli.run(project=project, args=['artifact', 'push', '--deps', 'all', 'target.bst'])
+ assert result.exit_code == 0
+
+ # And finally assert that the artifacts are in the right shares
+ #
+ # The parent project's cache should *also* contain elements from the junction
+ assert_shared(cli, share, project, 'target.bst', project_name='parent')
+ assert_shared(cli, share, project, 'app.bst', project_name='parent')
+ assert_shared(cli, share, base_project, 'base-element.bst', project_name='base')
+
+ # The junction project's cache should only contain elements in the junction project
+ assert_not_shared(cli, base_share, project, 'target.bst', project_name='parent')
+ assert_not_shared(cli, base_share, project, 'app.bst', project_name='parent')
+ assert_shared(cli, base_share, base_project, 'base-element.bst', project_name='base')