diff options
author | bst-marge-bot <marge-bot@buildstream.build> | 2020-11-04 07:18:54 +0000 |
---|---|---|
committer | bst-marge-bot <marge-bot@buildstream.build> | 2020-11-04 07:18:54 +0000 |
commit | 5d51b8d00ff5de466521cdecb42dda1550e787d8 (patch) | |
tree | 7e91551d8aa972ade689a30fec705209f25b741f | |
parent | 7fee0e64ffd2b5dcfd1766df8ed3a692e86a640d (diff) | |
parent | 6bf78c0734f0ff22fe0eef090b794f0a1b1a3fb8 (diff) | |
download | buildstream-5d51b8d00ff5de466521cdecb42dda1550e787d8.tar.gz |
Merge branch 'tristan/override-elements' into 'master'
Support overrides semantic for elements
See merge request BuildStream/buildstream!2094
37 files changed, 456 insertions, 46 deletions
diff --git a/src/buildstream/_loader/loadelement.pyx b/src/buildstream/_loader/loadelement.pyx index 60de948c8..210869e51 100644 --- a/src/buildstream/_loader/loadelement.pyx +++ b/src/buildstream/_loader/loadelement.pyx @@ -238,6 +238,7 @@ cdef class LoadElement: # TODO: if/when pyroaring exports symbols, we could type this statically cdef object _dep_cache cdef readonly list dependencies + cdef readonly bint fully_loaded # This is True if dependencies were also loaded def __cinit__(self, MappingNode node, str filename, object loader): @@ -250,6 +251,7 @@ cdef class LoadElement: self.full_name = None # The element full name (with associated junction) self.node_id = _next_synthetic_counter() self.link_target = None # The target of a link element (ScalarNode) + self.fully_loaded = False # Whether we entered the loop to load dependencies or not # # Private members @@ -338,6 +340,21 @@ cdef class LoadElement: self._ensure_depends_cache() return other.node_id in self._dep_cache + # mark_fully_loaded() + # + # Sets the fully loaded state on this load element + # + # This state bit is used by the Loader to distinguish + # between an element which has only been shallow loaded + # and an element which has entered the loop which loads + # it's dependencies. + # + # Args: + # element (LoadElement): The resolved LoadElement + # + def mark_fully_loaded(self): + self.fully_loaded = True + ########################################### # Private Methods # ########################################### diff --git a/src/buildstream/_loader/loader.py b/src/buildstream/_loader/loader.py index 46e8884c0..54efd27ae 100644 --- a/src/buildstream/_loader/loader.py +++ b/src/buildstream/_loader/loader.py @@ -392,6 +392,66 @@ class Loader: return path + # _load_one_file(): + # + # A helper function to load a single file within the _load_file() process, + # this allows us to handle redirections more consistently. + # + # Args: + # filename (str): The element-path relative bst file + # provenance_node (Node): The location from where the file was referred to, or None + # load_subprojects (bool): Whether to load subprojects + # + # Returns: + # (LoadElement): A LoadElement, which might be shallow loaded or fully loaded. + # + def _load_one_file(self, filename, provenance_node, *, load_subprojects=True): + + element = None + + # First check the cache, the cache might contain shallow loaded + # elements. + # + try: + element = self._elements[filename] + + # If the cached element has already entered the loop which loads + # it's dependencies, it is fully loaded and any further checks in + # this function are expected to have already been performed. + # + if element.fully_loaded: + return element + + except KeyError: + + # Shallow load if it's not yet loaded. + element = self._load_file_no_deps(filename, provenance_node) + + # Check if there was an override for this element + # + override = self._search_for_override_element(filename) + if override: + # + # If there was an override for the element, then it was + # implicitly fully loaded by _search_for_override_element(), + # + return override + + # If this element is a link then we need to resolve it, and return + # the linked element instead of this one. + # + if element.link_target is not None: + link_target = element.link_target.as_str() # pylint: disable=no-member + _, filename, loader = self._parse_name(link_target, element.link_target, load_subprojects=load_subprojects) + + # + # Redirect the loading of the file and it's dependencies to the appropriate loader, + # which might or might not be the same loader. + # + return loader._load_file(filename, element.link_target, load_subprojects=load_subprojects) + + return element + # _load_file(): # # Semi-Iteratively load bst files @@ -402,32 +462,26 @@ class Loader: # # Args: # filename (str): The element-path relative bst file - # load_subprojects (bool): Whether to load subprojects # provenance_node (Node): The location from where the file was referred to, or None + # load_subprojects (bool): Whether to load subprojects # # Returns: # (LoadElement): A loaded LoadElement # def _load_file(self, filename, provenance_node, *, load_subprojects=True): - # Silently ignore already loaded files - with suppress(KeyError): - return self._elements[filename] - - top_element = self._load_file_no_deps(filename, provenance_node) + top_element = self._load_one_file(filename, provenance_node, load_subprojects=load_subprojects) - # If this element is a link then we need to resolve it - # and replace the dependency we've processed with this one - if top_element.link_target is not None: - link_target = top_element.link_target.as_str() # pylint: disable=no-member - _, filename, loader = self._parse_name( - link_target, top_element.link_target, load_subprojects=load_subprojects - ) + # Already loaded dependencies for a fully loaded element, early return. + # + if top_element.fully_loaded: + return top_element - # Early return, redirect the loading of the file and it's dependencies to the - # appropriate loader. - # - return loader._load_file(filename, top_element.link_target, load_subprojects=load_subprojects) + # + # Mark the top element here as "fully loaded", so that we will avoid trying to + # load it's dependencies more than once. + # + top_element.mark_fully_loaded() dependencies = extract_depends_from_node(top_element.node) # The loader queue is a stack of tuples @@ -449,14 +503,18 @@ class Loader: if dep.junction: loader = self.get_loader(dep.junction, dep.node) dep_element = loader._load_file(dep.name, dep.node) + else: - dep_element = self._elements.get(dep.name) - if dep_element is None: - # The loader does not have this available so we need to - # either recursively cause it to be loaded, or else we - # need to push this onto the loader queue in this loader - dep_element = self._load_file_no_deps(dep.name, dep.node) + dep_element = self._load_one_file(dep.name, dep.node, load_subprojects=load_subprojects) + + # If the loaded element is not fully loaded, queue up the dependencies to be loaded in this loop. + # + if not dep_element.fully_loaded: + + # Mark the dep_element as fully_loaded, as we're already queueing it's deps + dep_element.mark_fully_loaded() + dep_deps = extract_depends_from_node(dep_element.node) loader_queue.append((dep_element, list(reversed(dep_deps)), [])) @@ -467,12 +525,6 @@ class Loader: LoadErrorReason.INVALID_DATA, ) - # If this dependency is a link then we need to resolve it - # and replace the dependency we've processed with this one - if dep_element.link_target: - _, filename, loader = self._parse_name(dep_element.link_target.as_str(), dep_element.link_target) - dep_element = loader._load_file(filename, dep_element.link_target) - # We've now resolved the element for this dependency, lets set the resolved # LoadElement on the dependency and append the dependency to the owning # LoadElement dependency list. @@ -572,19 +624,19 @@ class Loader: return None - # _search_for_override(): + # _search_for_overrides(): # - # Search parent projects for an overridden subproject to replace this junction. - # - # This function is called once for each direct child while looking up - # child loaders, after which point the child loader is cached in the `_loaders` - # table. This function also has the side effect of recording alternative parents - # of a child loader in the case that the child loader is overridden. + # Search for parent loaders which have an override for the specified element, + # returning a list of loaders with the highest level overriding loader at the + # end of the list, and the closest ancestor being at the beginning of the list. # # Args: - # filename (str): Junction name + # filename (str): The local element name + # + # Returns: + # (list): A list of loaders which override this element # - def _search_for_override(self, filename): + def _search_for_overrides(self, filename): loader = self override_path = filename @@ -600,6 +652,29 @@ class Loader: override_path = junction.name + ":" + override_path loader = loader._parent + return overriding_loaders + + # _search_for_override_loader(): + # + # Search parent projects an override of the junction specified by @filename, + # returning the loader object which should be used in place of the local + # junction specified by @filename. + # + # This function is called once for each direct child while looking up + # child loaders, after which point the child loader is cached in the `_loaders` + # table. This function also has the side effect of recording alternative parents + # of a child loader in the case that the child loader is overridden. + # + # Args: + # filename (str): Junction name + # + # Returns: + # (Loader): The loader to use, in case @filename was overridden, otherwise None. + # + def _search_for_override_loader(self, filename): + + overriding_loaders = self._search_for_overrides(filename) + # If there are any overriding loaders, use the highest one in # the ancestry to lookup the loader for this project. # @@ -630,6 +705,34 @@ class Loader: # return None + # _search_for_override_element(): + # + # Search parent projects an override of the element specified by @filename, + # returning the loader object which should be used in place of the local + # element specified by @filename. + # + # Args: + # filename (str): Junction name + # + # Returns: + # (Loader): The loader to use, in case @filename was overridden, otherwise None. + # + def _search_for_override_element(self, filename): + element = None + + # If there are any overriding loaders, use the highest one in + # the ancestry to lookup the element which should be used in place + # of @filename. + # + overriding_loaders = self._search_for_overrides(filename) + if overriding_loaders: + overriding_loader, override_node = overriding_loaders[-1] + + _, filename, loader = overriding_loader._parse_name(override_node.as_str(), override_node) + element = loader._load_file(filename, override_node) + + return element + # _get_loader(): # # Return loader for specified junction @@ -660,7 +763,7 @@ class Loader: # Search the ancestry for an overridden loader to use in place # of using the locally defined junction. # - override_loader = self._search_for_override(filename) + override_loader = self._search_for_override_loader(filename) if override_loader: self._loaders[filename] = override_loader return override_loader diff --git a/src/buildstream/plugins/elements/junction.py b/src/buildstream/plugins/elements/junction.py index 8693313af..cc980bec3 100644 --- a/src/buildstream/plugins/elements/junction.py +++ b/src/buildstream/plugins/elements/junction.py @@ -48,8 +48,7 @@ Overview # Optionally look in a subpath of the source repository for the project path: projects/hello - # Optionally override junction configurations in the subproject - # with a junction declaration in this project. + # Optionally override elements in subprojects, including junctions. # overrides: subproject-junction.bst: local-junction.bst @@ -138,6 +137,79 @@ configuration in a subproject which matches the toplevel project's configuration. +Overriding elements +------------------- +It is possible to override elements in subprojects. This can be useful if for +example, you need to work with a custom variant or fork of some software in the +subproject. This is a better strategy than overlapping and overwriting shared +libraries built by the subproject later on, as we can ensure that reverse dependencies +in the subproject are built against the overridden element. + +Overridding elements allows you to build on top of an existing project +and benefit from updates and releases for the vast majority of the upstream project, +even when there are some parts of the upstream project which need to be customized +for your own applications. + +Even junction elements in subprojects can be overridden, this is sometimes important +in order to reconcile conflicts when multiple projects depend on the same subproject, +as :ref:`discussed below <core_junction_nested_overrides>`. + +.. code:: yaml + + kind: junction + + ... + + config: + + # Override elements in a junctioned project + # + overrides: + subproject-element.bst: local-element.bst + +It is also possible to override elements in deeply nested subprojects, using +project relative :ref:`junction paths <format_element_names>`: + +.. code:: yaml + + kind: junction + + ... + + config: + + # Override deeply nested elements + # + overrides: + subproject.bst:subsubproject-element.bst: local-element.bst + +.. attention:: + + Overriding an element causes your project to completely define the + element being overridden, which means you will no longer receive updates + or security patches to the element in question when updating to newer + versions and releases of the upstream project. + + As such, overriding elements is only recommended in cases where the + element is very significantly redefined. + + Such cases include cases when you need a newer version of the element than + the one maintained by the upstream project you are using as a subproject, + or when you have significanly modified the code in your own custom ways. + + If you only need to introduce a security patch, then it is recommended that + you create your own downstream branch of the upstream project, not only will + this allow you to more easily consume updates with VCS tools like ``git rebase``, + but it will also be more convenient for submitting your security patches + to the upstream project so that you can drop them in a future update. + + Similarly, if you only need to enable/disable a specific feature of a module, + it is also preferrable to use a downstream branch of the upstream project. + In such a case, it is also worth trying to convince the upstream project to + support a :ref:`project option <project_options>` for your specific element + configuration, if it would be of use to other users too. + + .. _core_junction_nested: Nested Junctions @@ -152,6 +224,8 @@ the user to resolve conflicting nested junctions, and will provide an error message whenever a conflict is detected. +.. _core_junction_nested_overrides: + Overriding subproject junctions ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ If your project and a subproject share a subproject in common, then one way diff --git a/tests/format/junctions.py b/tests/format/junctions.py index c4eea2d1c..5c65a5534 100644 --- a/tests/format/junctions.py +++ b/tests/format/junctions.py @@ -388,11 +388,48 @@ def test_full_path_not_found(cli, tmpdir, datafiles, target, provenance): # -# Test the overrides feature. +# Test overridding elements # -# Here we reuse the `nested` project since it already has deep -# nesting, and add to it a couple of additional junctions to -# test overriding of junctions at various depts +@pytest.mark.datafiles(DATA_DIR) +@pytest.mark.parametrize( + "target,expected", + [ + # Override an element in a subproject, this dependency will depend on + # the same element in the subproject as the overridden element did. + ("override-subproject-element.bst", ["element.txt", "subelement-override.txt", "subdep.txt"]), + # Override an element in a subproject while depending on an element which depends + # on the overridden element, in this case we ensure that the reverse dependencies + # of the replaced element are built against the replacement. + ("override-subproject-dep.bst", ["element.txt", "sub.txt", "subdep-override.txt"]), + # Override an element in a subproject with a local link element which points to another + # element in the same subproject. + ("override-subproject-element-with-link.bst", ["element.txt", "sub-alternative.txt", "subdep.txt"]), + # Override a link to an element in a subproject with an alternative element + # in the same subproject. + ("override-subproject-element-using-link.bst", ["element.txt", "sub-alternative.txt", "subdep.txt"]), + # Override an element in a nested subsubproject, where the intermediate project also overrides + # the same element + ("override-subsubproject.bst", ["element.txt", "subsub.txt", "subdep-override.txt"]), + ], + ids=["element-with-deps", "dependency-of-element", "with-link", "using-link", "priority",], +) +def test_override_element(cli, tmpdir, datafiles, target, expected): + project = os.path.join(str(datafiles), "override-element") + checkoutdir = os.path.join(str(tmpdir), "checkout") + + # Build, checkout + result = cli.run(project=project, args=["build", target]) + result.assert_success() + result = cli.run(project=project, args=["artifact", "checkout", target, "--directory", checkoutdir]) + result.assert_success() + + # Check that the checkout contains the expected file(s) + for expect in expected: + assert os.path.exists(os.path.join(checkoutdir, expect)) + + +# +# Test overridding junctions # @pytest.mark.datafiles(DATA_DIR) @pytest.mark.parametrize( @@ -420,7 +457,7 @@ def test_full_path_not_found(cli, tmpdir, datafiles, target, provenance): "override-subproject-with-subsubproject", ], ) -def test_overrides(cli, tmpdir, datafiles, target, expected): +def test_override_junction(cli, tmpdir, datafiles, target, expected): project = os.path.join(str(datafiles), "overrides") checkoutdir = os.path.join(str(tmpdir), "checkout") diff --git a/tests/format/junctions/override-element/element.txt b/tests/format/junctions/override-element/element.txt new file mode 100644 index 000000000..e69de29bb --- /dev/null +++ b/tests/format/junctions/override-element/element.txt diff --git a/tests/format/junctions/override-element/override-subproject-dep.bst b/tests/format/junctions/override-element/override-subproject-dep.bst new file mode 100644 index 000000000..814afc1d4 --- /dev/null +++ b/tests/format/junctions/override-element/override-subproject-dep.bst @@ -0,0 +1,11 @@ +kind: import +sources: +- kind: local + path: element.txt + +# +# Depend on the subproject using a junction which overrides the dependency +# of the element we're depending on. +# +depends: +- subproject-override-dep.bst:subelement.bst diff --git a/tests/format/junctions/override-element/override-subproject-element-using-link.bst b/tests/format/junctions/override-element/override-subproject-element-using-link.bst new file mode 100644 index 000000000..ed196f568 --- /dev/null +++ b/tests/format/junctions/override-element/override-subproject-element-using-link.bst @@ -0,0 +1,12 @@ +kind: import +sources: +- kind: local + path: element.txt + +# +# Depend on the subproject using a junction which overrides the +# element we're depending on, using a link to address the element +# we are overridding. +# +depends: +- subproject-override-element-using-link.bst:subelement.bst diff --git a/tests/format/junctions/override-element/override-subproject-element-with-link.bst b/tests/format/junctions/override-element/override-subproject-element-with-link.bst new file mode 100644 index 000000000..d58a59bf1 --- /dev/null +++ b/tests/format/junctions/override-element/override-subproject-element-with-link.bst @@ -0,0 +1,12 @@ +kind: import +sources: +- kind: local + path: element.txt + +# +# Depend on the subproject using a junction which overrides the +# element we're depending on, with a local link to an alternative +# element in that same subproject. +# +depends: +- subproject-override-element-with-link.bst:subelement.bst diff --git a/tests/format/junctions/override-element/override-subproject-element.bst b/tests/format/junctions/override-element/override-subproject-element.bst new file mode 100644 index 000000000..74782110a --- /dev/null +++ b/tests/format/junctions/override-element/override-subproject-element.bst @@ -0,0 +1,11 @@ +kind: import +sources: +- kind: local + path: element.txt + +# +# Depend on the subproject using a junction which overrides the +# element we're depending on. +# +depends: +- subproject-override-element.bst:subelement.bst diff --git a/tests/format/junctions/override-element/override-subsubproject.bst b/tests/format/junctions/override-element/override-subsubproject.bst new file mode 100644 index 000000000..8d26dc19d --- /dev/null +++ b/tests/format/junctions/override-element/override-subsubproject.bst @@ -0,0 +1,12 @@ +kind: import +sources: +- kind: local + path: element.txt + +# +# Depend on the subsubproject element, and override it's dependency, the intermediate +# project also overrides the same subsubproject element, and this test ensures +# that the toplevel override takes precedence. +# +depends: +- subproject-override-subsubproject-element.bst:subsubproject-override-dep.bst:subsubelement.bst diff --git a/tests/format/junctions/override-element/project.conf b/tests/format/junctions/override-element/project.conf new file mode 100644 index 000000000..20636c446 --- /dev/null +++ b/tests/format/junctions/override-element/project.conf @@ -0,0 +1,2 @@ +name: test +min-version: 2.0 diff --git a/tests/format/junctions/override-element/subdep-override.bst b/tests/format/junctions/override-element/subdep-override.bst new file mode 100644 index 000000000..93d4a5402 --- /dev/null +++ b/tests/format/junctions/override-element/subdep-override.bst @@ -0,0 +1,4 @@ +kind: import +sources: +- kind: local + path: subdep-override.txt diff --git a/tests/format/junctions/override-element/subdep-override.txt b/tests/format/junctions/override-element/subdep-override.txt new file mode 100644 index 000000000..e69de29bb --- /dev/null +++ b/tests/format/junctions/override-element/subdep-override.txt diff --git a/tests/format/junctions/override-element/subelement-alternative-link.bst b/tests/format/junctions/override-element/subelement-alternative-link.bst new file mode 100644 index 000000000..bd43d0750 --- /dev/null +++ b/tests/format/junctions/override-element/subelement-alternative-link.bst @@ -0,0 +1,8 @@ +kind: link + +# +# This link replaces subelement.bst in the same project, use the +# same junction to access the alternative in the subproject. +# +config: + target: subproject-override-element-with-link.bst:subelement-alternative.bst diff --git a/tests/format/junctions/override-element/subelement-override.bst b/tests/format/junctions/override-element/subelement-override.bst new file mode 100644 index 000000000..99715e098 --- /dev/null +++ b/tests/format/junctions/override-element/subelement-override.bst @@ -0,0 +1,14 @@ +kind: import +sources: +- kind: local + path: subelement-override.txt + +# We override the subproject direct dependency with this element, +# and this element explicitly depends on it's dependency in that +# subproject. +# +# The dependency we depend on happens to be the same dependency +# as the element we are overridding. +# +depends: +- subproject-override-element.bst:subdependency.bst diff --git a/tests/format/junctions/override-element/subelement-override.txt b/tests/format/junctions/override-element/subelement-override.txt new file mode 100644 index 000000000..e69de29bb --- /dev/null +++ b/tests/format/junctions/override-element/subelement-override.txt diff --git a/tests/format/junctions/override-element/subproject-override-dep.bst b/tests/format/junctions/override-element/subproject-override-dep.bst new file mode 100644 index 000000000..f39b7393b --- /dev/null +++ b/tests/format/junctions/override-element/subproject-override-dep.bst @@ -0,0 +1,8 @@ +kind: junction +sources: +- kind: local + path: subproject + +config: + overrides: + subdependency.bst: subdep-override.bst diff --git a/tests/format/junctions/override-element/subproject-override-element-using-link.bst b/tests/format/junctions/override-element/subproject-override-element-using-link.bst new file mode 100644 index 000000000..f4d36d7ea --- /dev/null +++ b/tests/format/junctions/override-element/subproject-override-element-using-link.bst @@ -0,0 +1,8 @@ +kind: junction +sources: +- kind: local + path: subproject + +config: + overrides: + subelement-link.bst: subproject-override-element-using-link.bst:subelement-alternative.bst diff --git a/tests/format/junctions/override-element/subproject-override-element-with-link.bst b/tests/format/junctions/override-element/subproject-override-element-with-link.bst new file mode 100644 index 000000000..1a8a5fc53 --- /dev/null +++ b/tests/format/junctions/override-element/subproject-override-element-with-link.bst @@ -0,0 +1,8 @@ +kind: junction +sources: +- kind: local + path: subproject + +config: + overrides: + subelement.bst: subelement-alternative-link.bst diff --git a/tests/format/junctions/override-element/subproject-override-element.bst b/tests/format/junctions/override-element/subproject-override-element.bst new file mode 100644 index 000000000..cc9fa80a4 --- /dev/null +++ b/tests/format/junctions/override-element/subproject-override-element.bst @@ -0,0 +1,8 @@ +kind: junction +sources: +- kind: local + path: subproject + +config: + overrides: + subelement.bst: subelement-override.bst diff --git a/tests/format/junctions/override-element/subproject-override-subsubproject-element.bst b/tests/format/junctions/override-element/subproject-override-subsubproject-element.bst new file mode 100644 index 000000000..be8b900ad --- /dev/null +++ b/tests/format/junctions/override-element/subproject-override-subsubproject-element.bst @@ -0,0 +1,8 @@ +kind: junction +sources: +- kind: local + path: subproject + +config: + overrides: + subsubproject-override-dep.bst:subsubdependency.bst: subdep-override.bst diff --git a/tests/format/junctions/override-element/subproject/project.conf b/tests/format/junctions/override-element/subproject/project.conf new file mode 100644 index 000000000..39a53e2ab --- /dev/null +++ b/tests/format/junctions/override-element/subproject/project.conf @@ -0,0 +1,2 @@ +name: subtest +min-version: 2.0 diff --git a/tests/format/junctions/override-element/subproject/sub-alternative.txt b/tests/format/junctions/override-element/subproject/sub-alternative.txt new file mode 100644 index 000000000..e69de29bb --- /dev/null +++ b/tests/format/junctions/override-element/subproject/sub-alternative.txt diff --git a/tests/format/junctions/override-element/subproject/sub.txt b/tests/format/junctions/override-element/subproject/sub.txt new file mode 100644 index 000000000..e69de29bb --- /dev/null +++ b/tests/format/junctions/override-element/subproject/sub.txt diff --git a/tests/format/junctions/override-element/subproject/subdep.txt b/tests/format/junctions/override-element/subproject/subdep.txt new file mode 100644 index 000000000..e69de29bb --- /dev/null +++ b/tests/format/junctions/override-element/subproject/subdep.txt diff --git a/tests/format/junctions/override-element/subproject/subdependency.bst b/tests/format/junctions/override-element/subproject/subdependency.bst new file mode 100644 index 000000000..59e549210 --- /dev/null +++ b/tests/format/junctions/override-element/subproject/subdependency.bst @@ -0,0 +1,4 @@ +kind: import +sources: +- kind: local + path: subdep.txt diff --git a/tests/format/junctions/override-element/subproject/subelement-alternative.bst b/tests/format/junctions/override-element/subproject/subelement-alternative.bst new file mode 100644 index 000000000..51a063799 --- /dev/null +++ b/tests/format/junctions/override-element/subproject/subelement-alternative.bst @@ -0,0 +1,7 @@ +kind: import +sources: +- kind: local + path: sub-alternative.txt + +depends: +- subdependency.bst diff --git a/tests/format/junctions/override-element/subproject/subelement-link.bst b/tests/format/junctions/override-element/subproject/subelement-link.bst new file mode 100644 index 000000000..874969cee --- /dev/null +++ b/tests/format/junctions/override-element/subproject/subelement-link.bst @@ -0,0 +1,8 @@ +kind: link + +# +# A link to the subelement, used by the override in +# the subproject-override-element-using-link.bst junction +# +config: + target: subelement.bst diff --git a/tests/format/junctions/override-element/subproject/subelement.bst b/tests/format/junctions/override-element/subproject/subelement.bst new file mode 100644 index 000000000..aff3b3f6e --- /dev/null +++ b/tests/format/junctions/override-element/subproject/subelement.bst @@ -0,0 +1,7 @@ +kind: import +sources: +- kind: local + path: sub.txt + +depends: +- subdependency.bst diff --git a/tests/format/junctions/override-element/subproject/subsubdep-override.bst b/tests/format/junctions/override-element/subproject/subsubdep-override.bst new file mode 100644 index 000000000..9ab11a2f8 --- /dev/null +++ b/tests/format/junctions/override-element/subproject/subsubdep-override.bst @@ -0,0 +1,4 @@ +kind: import +sources: +- kind: local + path: subsubdep-override.txt diff --git a/tests/format/junctions/override-element/subproject/subsubdep-override.txt b/tests/format/junctions/override-element/subproject/subsubdep-override.txt new file mode 100644 index 000000000..e69de29bb --- /dev/null +++ b/tests/format/junctions/override-element/subproject/subsubdep-override.txt diff --git a/tests/format/junctions/override-element/subproject/subsubproject-override-dep.bst b/tests/format/junctions/override-element/subproject/subsubproject-override-dep.bst new file mode 100644 index 000000000..6b2379d7c --- /dev/null +++ b/tests/format/junctions/override-element/subproject/subsubproject-override-dep.bst @@ -0,0 +1,8 @@ +kind: junction +sources: +- kind: local + path: subsubproject + +config: + overrides: + subsubdependency.bst: subsubdep-override.bst diff --git a/tests/format/junctions/override-element/subproject/subsubproject/project.conf b/tests/format/junctions/override-element/subproject/subsubproject/project.conf new file mode 100644 index 000000000..d11bcbb30 --- /dev/null +++ b/tests/format/junctions/override-element/subproject/subsubproject/project.conf @@ -0,0 +1,2 @@ +name: subsubtest +min-version: 2.0 diff --git a/tests/format/junctions/override-element/subproject/subsubproject/subsub.txt b/tests/format/junctions/override-element/subproject/subsubproject/subsub.txt new file mode 100644 index 000000000..e69de29bb --- /dev/null +++ b/tests/format/junctions/override-element/subproject/subsubproject/subsub.txt diff --git a/tests/format/junctions/override-element/subproject/subsubproject/subsubdep.txt b/tests/format/junctions/override-element/subproject/subsubproject/subsubdep.txt new file mode 100644 index 000000000..e69de29bb --- /dev/null +++ b/tests/format/junctions/override-element/subproject/subsubproject/subsubdep.txt diff --git a/tests/format/junctions/override-element/subproject/subsubproject/subsubdependency.bst b/tests/format/junctions/override-element/subproject/subsubproject/subsubdependency.bst new file mode 100644 index 000000000..d235791b5 --- /dev/null +++ b/tests/format/junctions/override-element/subproject/subsubproject/subsubdependency.bst @@ -0,0 +1,4 @@ +kind: import +sources: +- kind: local + path: subsubdep.txt diff --git a/tests/format/junctions/override-element/subproject/subsubproject/subsubelement.bst b/tests/format/junctions/override-element/subproject/subsubproject/subsubelement.bst new file mode 100644 index 000000000..087a562b6 --- /dev/null +++ b/tests/format/junctions/override-element/subproject/subsubproject/subsubelement.bst @@ -0,0 +1,7 @@ +kind: import +sources: +- kind: local + path: subsub.txt + +depends: +- subsubdependency.bst |