diff options
author | bst-marge-bot <marge-bot@buildstream.build> | 2019-03-21 14:55:45 +0000 |
---|---|---|
committer | bst-marge-bot <marge-bot@buildstream.build> | 2019-03-21 14:55:45 +0000 |
commit | bc1b971e169f2fc721c61276c071640caee6a3f8 (patch) | |
tree | cd03efcc726e07eb0c33c49d4385b9888c4af803 | |
parent | c74701413ed32d721188b2a7eab8081d4629380c (diff) | |
parent | 65abe0fcc103478ccfeeb38d57ca38be02a15fe6 (diff) | |
download | buildstream-bc1b971e169f2fc721c61276c071640caee6a3f8.tar.gz |
Merge branch 'bschubert/pipeline' into 'master'
Refactor _update_state() to be called only when needed
Closes #703
See merge request BuildStream/buildstream!1070
37 files changed, 311 insertions, 89 deletions
diff --git a/buildstream/_context.py b/buildstream/_context.py index 476032f39..0c7f81264 100644 --- a/buildstream/_context.py +++ b/buildstream/_context.py @@ -35,7 +35,7 @@ from ._artifactcache import ArtifactCache from ._sourcecache import SourceCache from ._cas import CASCache, CASQuota, CASCacheUsage from ._workspaces import Workspaces, WorkspaceProjectCache -from .plugin import _plugin_lookup +from .plugin import Plugin from .sandbox import SandboxRemote @@ -651,7 +651,7 @@ class Context(): plugin_name = "" if message.unique_id: template += " {plugin}" - plugin = _plugin_lookup(message.unique_id) + plugin = Plugin._lookup(message.unique_id) plugin_name = plugin.name template += ": {message}" diff --git a/buildstream/_frontend/app.py b/buildstream/_frontend/app.py index 67fcc8370..a659b202a 100644 --- a/buildstream/_frontend/app.py +++ b/buildstream/_frontend/app.py @@ -531,7 +531,7 @@ class App(): queue = job.queue # Get the last failure message for additional context - failure = self._fail_messages.get(element._get_unique_id()) + failure = self._fail_messages.get(element._unique_id) # XXX This is dangerous, sometimes we get the job completed *before* # the failure message reaches us ?? diff --git a/buildstream/_frontend/widget.py b/buildstream/_frontend/widget.py index 45be6d136..ef31b8ba7 100644 --- a/buildstream/_frontend/widget.py +++ b/buildstream/_frontend/widget.py @@ -32,7 +32,7 @@ from .. import _yaml from .. import __version__ as bst_version from .._exceptions import ImplError from .._message import MessageType -from ..plugin import _plugin_lookup +from ..plugin import Plugin # These messages are printed a bit differently @@ -191,7 +191,7 @@ class ElementName(Widget): action_name = message.action_name element_id = message.task_id or message.unique_id if element_id is not None: - plugin = _plugin_lookup(element_id) + plugin = Plugin._lookup(element_id) name = plugin._get_full_name() name = '{: <30}'.format(name) else: @@ -232,7 +232,7 @@ class CacheKey(Widget): missing = False key = ' ' * self._key_length - plugin = _plugin_lookup(element_id) + plugin = Plugin._lookup(element_id) if isinstance(plugin, Element): _, key, missing = plugin._get_display_key() @@ -621,7 +621,7 @@ class LogLine(Widget): # Track logfiles for later use element_id = message.task_id or message.unique_id if message.message_type in ERROR_MESSAGES and element_id is not None: - plugin = _plugin_lookup(element_id) + plugin = Plugin._lookup(element_id) self._failure_messages[plugin].append(message) return self._render(message) diff --git a/buildstream/_scheduler/jobs/elementjob.py b/buildstream/_scheduler/jobs/elementjob.py index fa0d34fb3..fb5d38e11 100644 --- a/buildstream/_scheduler/jobs/elementjob.py +++ b/buildstream/_scheduler/jobs/elementjob.py @@ -73,7 +73,7 @@ class ElementJob(Job): self._complete_cb = complete_cb # The complete callable function # Set the task wide ID for logging purposes - self.set_task_id(element._get_unique_id()) + self.set_task_id(element._unique_id) @property def element(self): @@ -100,7 +100,7 @@ class ElementJob(Job): args = dict(kwargs) args['scheduler'] = True self._scheduler.context.message( - Message(self._element._get_unique_id(), + Message(self._element._unique_id, message_type, message, **args)) diff --git a/buildstream/_scheduler/queues/buildqueue.py b/buildstream/_scheduler/queues/buildqueue.py index 60ec19ff4..aa489f381 100644 --- a/buildstream/_scheduler/queues/buildqueue.py +++ b/buildstream/_scheduler/queues/buildqueue.py @@ -70,9 +70,6 @@ class BuildQueue(Queue): return element._assemble() def status(self, element): - # state of dependencies may have changed, recalculate element state - element._update_state() - if not element._is_required(): # Artifact is not currently required but it may be requested later. # Keep it in the queue. diff --git a/buildstream/_scheduler/queues/fetchqueue.py b/buildstream/_scheduler/queues/fetchqueue.py index db5e470f9..546c65b65 100644 --- a/buildstream/_scheduler/queues/fetchqueue.py +++ b/buildstream/_scheduler/queues/fetchqueue.py @@ -45,9 +45,6 @@ class FetchQueue(Queue): element._fetch(fetch_original=self._fetch_original) def status(self, element): - # state of dependencies may have changed, recalculate element state - element._update_state() - if not element._is_required(): # Artifact is not currently required but it may be requested later. # Keep it in the queue. @@ -74,7 +71,7 @@ class FetchQueue(Queue): if status == JobStatus.FAIL: return - element._update_state() + element._fetch_done() # Successful fetch, we must be CACHED now assert element._get_consistency() == Consistency.CACHED diff --git a/buildstream/_scheduler/queues/pullqueue.py b/buildstream/_scheduler/queues/pullqueue.py index dbeb806e5..013ee6489 100644 --- a/buildstream/_scheduler/queues/pullqueue.py +++ b/buildstream/_scheduler/queues/pullqueue.py @@ -39,9 +39,6 @@ class PullQueue(Queue): raise SkipJob(self.action_name) def status(self, element): - # state of dependencies may have changed, recalculate element state - element._update_state() - if not element._is_required(): # Artifact is not currently required but it may be requested later. # Keep it in the queue. diff --git a/buildstream/_scheduler/queues/queue.py b/buildstream/_scheduler/queues/queue.py index 9f0563fa5..1efcffc16 100644 --- a/buildstream/_scheduler/queues/queue.py +++ b/buildstream/_scheduler/queues/queue.py @@ -316,7 +316,7 @@ class Queue(): # a message for the element they are processing def _message(self, element, message_type, brief, **kwargs): context = element._get_context() - message = Message(element._get_unique_id(), message_type, brief, **kwargs) + message = Message(element._unique_id, message_type, brief, **kwargs) context.message(message) def _element_log_path(self, element): diff --git a/buildstream/_scheduler/queues/trackqueue.py b/buildstream/_scheduler/queues/trackqueue.py index 245b528e6..d7e6546f3 100644 --- a/buildstream/_scheduler/queues/trackqueue.py +++ b/buildstream/_scheduler/queues/trackqueue.py @@ -19,7 +19,7 @@ # Jürg Billeter <juerg.billeter@codethink.co.uk> # BuildStream toplevel imports -from ...plugin import _plugin_lookup +from ...plugin import Plugin # Local imports from . import Queue, QueueStatus @@ -55,7 +55,7 @@ class TrackQueue(Queue): # Set the new refs in the main process one by one as they complete for unique_id, new_ref in result: - source = _plugin_lookup(unique_id) + source = Plugin._lookup(unique_id) source._save_ref(new_ref) element._tracking_done() diff --git a/buildstream/_stream.py b/buildstream/_stream.py index 3276b4081..262b38852 100644 --- a/buildstream/_stream.py +++ b/buildstream/_stream.py @@ -32,7 +32,7 @@ from contextlib import contextmanager, suppress from fnmatch import fnmatch from ._artifactelement import verify_artifact_ref -from ._exceptions import StreamError, ImplError, BstError, ArtifactElementError, CASCacheError, set_last_task_error +from ._exceptions import StreamError, ImplError, BstError, ArtifactElementError, CASCacheError from ._message import Message, MessageType from ._scheduler import Scheduler, SchedStatus, TrackQueue, FetchQueue, BuildQueue, PullQueue, PushQueue from ._pipeline import Pipeline, PipelineSelection @@ -1172,17 +1172,6 @@ class Stream(): _, status = self._scheduler.run(self.queues) - # Force update element states after a run, such that the summary - # is more coherent - try: - for element in self.total_elements: - element._update_state() - except BstError as e: - self._message(MessageType.ERROR, "Error resolving final state", detail=str(e)) - set_last_task_error(e.domain, e.reason) - except Exception as e: # pylint: disable=broad-except - self._message(MessageType.BUG, "Unhandled exception while resolving final state", detail=str(e)) - if status == SchedStatus.ERROR: raise StreamError() elif status == SchedStatus.TERMINATED: diff --git a/buildstream/element.py b/buildstream/element.py index 35f656fca..88f6863d6 100644 --- a/buildstream/element.py +++ b/buildstream/element.py @@ -99,7 +99,7 @@ from . import _site from ._platform import Platform from .sandbox._config import SandboxConfig from .sandbox._sandboxremote import SandboxRemote -from .types import _KeyStrength, CoreWarnings +from .types import _KeyStrength, CoreWarnings, _UniquePriorityQueue from ._artifact import Artifact from .storage.directory import Directory @@ -204,6 +204,8 @@ class Element(Plugin): self.__runtime_dependencies = [] # Direct runtime dependency Elements self.__build_dependencies = [] # Direct build dependency Elements + self.__reverse_dependencies = set() # Direct reverse dependency Elements + self.__ready_for_runtime = False # Wether the element has all its dependencies ready and has a cache key self.__sources = [] # List of Sources self.__weak_cache_key = None # Our cached weak cache key self.__strict_cache_key = None # Our cached cache key for strict builds @@ -975,9 +977,12 @@ class Element(Plugin): for meta_dep in meta.dependencies: dependency = Element._new_from_meta(meta_dep) element.__runtime_dependencies.append(dependency) + dependency.__reverse_dependencies.add(element) + for meta_dep in meta.build_dependencies: dependency = Element._new_from_meta(meta_dep) element.__build_dependencies.append(dependency) + dependency.__reverse_dependencies.add(element) return element @@ -1259,6 +1264,10 @@ class Element(Plugin): # Strong cache key could not be calculated yet return + if not self.__ready_for_runtime and self.__cache_key is not None: + self.__ready_for_runtime = all( + dep.__ready_for_runtime for dep in self.__runtime_dependencies) + # _get_display_key(): # # Returns cache keys for display purposes @@ -1373,7 +1382,7 @@ class Element(Plugin): source = sources.pop() source._generate_key(sources) - self._update_state() + self.__update_state_recursively() # _track(): # @@ -1390,7 +1399,7 @@ class Element(Plugin): for index, source in enumerate(self.__sources): old_ref = source.get_ref() new_ref = source._track(self.__sources[0:index]) - refs.append((source._get_unique_id(), new_ref)) + refs.append((source._unique_id, new_ref)) # Complimentary warning that the new ref will be unused. if old_ref != new_ref and self._get_workspace(): @@ -1580,7 +1589,7 @@ class Element(Plugin): self.__assemble_scheduled = False self.__assemble_done = True - self._update_state() + self.__update_state_recursively() if self._get_workspace() and self._cached_success(): assert utils._is_main_process(), \ @@ -1765,6 +1774,15 @@ class Element(Plugin): def _get_build_log(self): return self._build_log_path + # _fetch_done() + # + # Indicates that fetching the sources for this element has been done. + # + def _fetch_done(self): + # We are not updating the state recursively here since fetching can + # never end up in updating them. + self._update_state() + # _pull_pending() # # Check whether the artifact will be pulled. If the pull operation is to @@ -1807,7 +1825,7 @@ class Element(Plugin): def _pull_done(self): self.__pull_done = True - self._update_state() + self.__update_state_recursively() # _pull(): # @@ -2915,6 +2933,24 @@ class Element(Plugin): if not sourcecache.contains(sources[-1]): sources[-1]._cache(sources[:-1]) + # __update_state_recursively() + # + # Update the state of all reverse dependencies, recursively. + # + def __update_state_recursively(self): + queue = _UniquePriorityQueue() + queue.push(self._unique_id, self) + + while queue: + element = queue.pop() + + old_ready_for_runtime = element.__ready_for_runtime + element._update_state() + + if element.__ready_for_runtime != old_ready_for_runtime: + for rdep in element.__reverse_dependencies: + queue.push(rdep._unique_id, rdep) + def _overlap_error_detail(f, forbidden_overlap_elements, elements): if forbidden_overlap_elements: diff --git a/buildstream/plugin.py b/buildstream/plugin.py index f5daf31bf..c139c8cb7 100644 --- a/buildstream/plugin.py +++ b/buildstream/plugin.py @@ -109,6 +109,7 @@ Class Reference --------------- """ +import itertools import os import subprocess import sys @@ -183,6 +184,23 @@ class Plugin(): """ + # Unique id generator for Plugins + # + # Each plugin gets a unique id at creation. + # Ids are a monotically increasing integer + __id_generator = itertools.count() + + # Hold on to a lookup table by counter of all instantiated plugins. + # We use this to send the id back from child processes so we can lookup + # corresponding element/source in the master process. + # + # Use WeakValueDictionary() so the map we use to lookup objects does not + # keep the plugins alive after pipeline destruction. + # + # Note that Plugins can only be instantiated in the main process before + # scheduling tasks. + __TABLE = WeakValueDictionary() + def __init__(self, name, context, project, provenance, type_tag): self.name = name @@ -195,11 +213,24 @@ class Plugin(): For sources this is for display purposes only. """ + # Unique ID + # + # This id allows to uniquely identify a plugin. + # + # /!\ the unique id must be an increasing value /!\ + # This is because we are depending on it in buildstream.element.Element + # to give us a topological sort over all elements. + # Modifying how we handle ids here will modify the behavior of the + # Element's state handling. + self._unique_id = next(self.__id_generator) + + # register ourself in the table containing all existing plugins + self.__TABLE[self._unique_id] = self + self.__context = context # The Context object self.__project = project # The Project object self.__provenance = provenance # The Provenance information self.__type_tag = type_tag # The type of plugin (element or source) - self.__unique_id = _plugin_register(self) # Unique ID self.__configuring = False # Whether we are currently configuring # Infer the kind identifier @@ -577,7 +608,7 @@ class Plugin(): self.call(... command which takes time ...) """ with self.__context.timed_activity(activity_name, - unique_id=self.__unique_id, + unique_id=self._unique_id, detail=detail, silent_nested=silent_nested): yield @@ -669,6 +700,23 @@ class Plugin(): # Private Methods used in BuildStream # ############################################################# + # _lookup(): + # + # Fetch a plugin in the current process by its + # unique identifier + # + # Args: + # unique_id: The unique identifier as returned by + # plugin._unique_id + # + # Returns: + # (Plugin): The plugin for the given ID, or None + # + @classmethod + def _lookup(cls, unique_id): + assert unique_id in cls.__TABLE, "Could not find plugin with ID {}".format(unique_id) + return cls.__TABLE[unique_id] + # _get_context() # # Fetches the invocation context @@ -683,13 +731,6 @@ class Plugin(): def _get_project(self): return self.__project - # _get_unique_id(): - # - # Fetch the plugin's unique identifier - # - def _get_unique_id(self): - return self.__unique_id - # _get_provenance(): # # Fetch bst file, line and column of the entity @@ -774,7 +815,7 @@ class Plugin(): return (exit_code, output) def __message(self, message_type, brief, **kwargs): - message = Message(self.__unique_id, message_type, brief, **kwargs) + message = Message(self._unique_id, message_type, brief, **kwargs) self.__context.message(message) def __note_command(self, output, *popenargs, **kwargs): @@ -806,45 +847,6 @@ class Plugin(): return self.get_kind() in silenced_warnings -# Hold on to a lookup table by counter of all instantiated plugins. -# We use this to send the id back from child processes so we can lookup -# corresponding element/source in the master process. -# -# Use WeakValueDictionary() so the map we use to lookup objects does not -# keep the plugins alive after pipeline destruction. -# -# Note that Plugins can only be instantiated in the main process before -# scheduling tasks. -__PLUGINS_UNIQUE_ID = 0 -__PLUGINS_TABLE = WeakValueDictionary() - - -# _plugin_lookup(): -# -# Fetch a plugin in the current process by its -# unique identifier -# -# Args: -# unique_id: The unique identifier as returned by -# plugin._get_unique_id() -# -# Returns: -# (Plugin): The plugin for the given ID, or None -# -def _plugin_lookup(unique_id): - assert unique_id in __PLUGINS_TABLE, "Could not find plugin with ID {}".format(unique_id) - return __PLUGINS_TABLE[unique_id] - - -# No need for unregister, WeakValueDictionary() will remove entries -# in itself when the referenced plugins are garbage collected. -def _plugin_register(plugin): - global __PLUGINS_UNIQUE_ID # pylint: disable=global-statement - __PLUGINS_UNIQUE_ID += 1 - __PLUGINS_TABLE[__PLUGINS_UNIQUE_ID] = plugin - return __PLUGINS_UNIQUE_ID - - # A local table for _prefix_warning() # __CORE_WARNINGS = [ diff --git a/buildstream/sandbox/sandbox.py b/buildstream/sandbox/sandbox.py index f11ddea1d..93db2f8ca 100644 --- a/buildstream/sandbox/sandbox.py +++ b/buildstream/sandbox/sandbox.py @@ -122,7 +122,7 @@ class Sandbox(): # Plugin ID for logging plugin = kwargs.get('plugin', None) if plugin: - self.__plugin_id = plugin._get_unique_id() + self.__plugin_id = plugin._unique_id else: self.__plugin_id = None diff --git a/buildstream/types.py b/buildstream/types.py index ba4b99eb7..d54bf0b6e 100644 --- a/buildstream/types.py +++ b/buildstream/types.py @@ -17,6 +17,7 @@ # Authors: # Tristan Van Berkom <tristan.vanberkom@codethink.co.uk> # Jim MacArthur <jim.macarthur@codethink.co.uk> +# Benjamin Schubert <bschubert15@bloomberg.net> """ Foundation types @@ -25,6 +26,7 @@ Foundation types """ from enum import Enum +import heapq class Scope(Enum): @@ -124,3 +126,52 @@ class _KeyStrength(Enum): # Includes names of direct build dependencies but does not include # cache keys of dependencies. WEAK = 2 + + +# _UniquePriorityQueue(): +# +# Implements a priority queue that adds only each key once. +# +# The queue will store and priority based on a tuple (key, item). +# +class _UniquePriorityQueue: + + def __init__(self): + self._items = set() + self._heap = [] + + # push(): + # + # Push a new item in the queue. + # + # If the item is already present in the queue as identified by the key, + # this is a noop. + # + # Args: + # key (hashable, comparable): unique key to use for checking for + # the object's existence and used for + # ordering + # item (any): item to push to the queue + # + def push(self, key, item): + if key not in self._items: + self._items.add(key) + heapq.heappush(self._heap, (key, item)) + + # pop(): + # + # Pop the next item from the queue, by priority order. + # + # Returns: + # (any): the next item + # + # Throw: + # IndexError: when the list is empty + # + def pop(self): + key, item = heapq.heappop(self._heap) + self._items.remove(key) + return item + + def __len__(self): + return len(self._heap) diff --git a/tests/frontend/workspace.py b/tests/frontend/workspace.py index c47424ec6..e570c2899 100644 --- a/tests/frontend/workspace.py +++ b/tests/frontend/workspace.py @@ -1229,3 +1229,58 @@ def test_external_list(cli, datafiles, tmpdir_factory): result = cli.run(project=project, args=['-C', workspace, 'workspace', 'list']) result.assert_success() + + +# This strange test tests against a regression raised in issue #919, +# where opening a workspace on a runtime dependency of a build only +# dependency causes `bst build` to not build the specified target +# but just successfully builds the workspaced element and happily +# exits without completing the build. +# +TEST_DIR = os.path.join( + os.path.dirname(os.path.realpath(__file__)) +) + + +@pytest.mark.datafiles(TEST_DIR) +@pytest.mark.parametrize( + ["case", "non_workspaced_elements_state"], + [ + ("workspaced-build-dep", ["waiting", "waiting", "waiting", "waiting", "waiting"]), + ("workspaced-runtime-dep", ["buildable", "buildable", "waiting", "waiting", "waiting"]) + ], +) +@pytest.mark.parametrize("strict", [("strict"), ("non-strict")]) +def test_build_all(cli, tmpdir, datafiles, case, strict, non_workspaced_elements_state): + project = os.path.join(str(datafiles), case) + workspace = os.path.join(str(tmpdir), 'workspace') + non_leaf_elements = ["elem2.bst", "elem3.bst", "stack.bst", "elem4.bst", "elem5.bst"] + all_elements = ["elem1.bst", *non_leaf_elements] + + # Configure strict mode + strict_mode = True + if strict != 'strict': + strict_mode = False + cli.configure({ + 'projects': { + 'test': { + 'strict': strict_mode + } + } + }) + + # First open the workspace + result = cli.run(project=project, args=['workspace', 'open', '--directory', workspace, 'elem1.bst']) + result.assert_success() + + # Ensure all elements are waiting build the first + assert cli.get_element_states(project, all_elements) == \ + dict(zip(all_elements, ['buildable', *non_workspaced_elements_state])) + + # Now build the targets elem4.bst and elem5.bst + result = cli.run(project=project, args=['build', 'elem4.bst', 'elem5.bst']) + result.assert_success() + + # Assert that the target is built + assert cli.get_element_states(project, all_elements) == \ + {elem: "cached" for elem in all_elements} diff --git a/tests/frontend/workspaced-build-dep/elements/elem1.bst b/tests/frontend/workspaced-build-dep/elements/elem1.bst new file mode 100644 index 000000000..eed39a95a --- /dev/null +++ b/tests/frontend/workspaced-build-dep/elements/elem1.bst @@ -0,0 +1,5 @@ +kind: import + +sources: +- kind: local + path: files/file1 diff --git a/tests/frontend/workspaced-build-dep/elements/elem2.bst b/tests/frontend/workspaced-build-dep/elements/elem2.bst new file mode 100644 index 000000000..78af3ba44 --- /dev/null +++ b/tests/frontend/workspaced-build-dep/elements/elem2.bst @@ -0,0 +1,8 @@ +kind: import + +build-depends: +- elem1.bst + +sources: +- kind: local + path: files/file2 diff --git a/tests/frontend/workspaced-build-dep/elements/elem3.bst b/tests/frontend/workspaced-build-dep/elements/elem3.bst new file mode 100644 index 000000000..6e1de0de4 --- /dev/null +++ b/tests/frontend/workspaced-build-dep/elements/elem3.bst @@ -0,0 +1,8 @@ +kind: import + +build-depends: +- elem2.bst + +sources: +- kind: local + path: files/file3 diff --git a/tests/frontend/workspaced-build-dep/elements/elem4.bst b/tests/frontend/workspaced-build-dep/elements/elem4.bst new file mode 100644 index 000000000..a04f509a6 --- /dev/null +++ b/tests/frontend/workspaced-build-dep/elements/elem4.bst @@ -0,0 +1,8 @@ +kind: import + +build-depends: +- stack.bst + +sources: +- kind: local + path: files/file4 diff --git a/tests/frontend/workspaced-build-dep/elements/elem5.bst b/tests/frontend/workspaced-build-dep/elements/elem5.bst new file mode 100644 index 000000000..4fb3af822 --- /dev/null +++ b/tests/frontend/workspaced-build-dep/elements/elem5.bst @@ -0,0 +1,8 @@ +kind: import + +build-depends: +- elem3.bst + +sources: +- kind: local + path: files/file4 diff --git a/tests/frontend/workspaced-build-dep/elements/stack.bst b/tests/frontend/workspaced-build-dep/elements/stack.bst new file mode 100644 index 000000000..b4c6002f0 --- /dev/null +++ b/tests/frontend/workspaced-build-dep/elements/stack.bst @@ -0,0 +1,4 @@ +kind: stack + +depends: +- elem3.bst diff --git a/tests/frontend/workspaced-build-dep/files/file1 b/tests/frontend/workspaced-build-dep/files/file1 new file mode 100644 index 000000000..e69de29bb --- /dev/null +++ b/tests/frontend/workspaced-build-dep/files/file1 diff --git a/tests/frontend/workspaced-build-dep/files/file2 b/tests/frontend/workspaced-build-dep/files/file2 new file mode 100644 index 000000000..e69de29bb --- /dev/null +++ b/tests/frontend/workspaced-build-dep/files/file2 diff --git a/tests/frontend/workspaced-build-dep/files/file3 b/tests/frontend/workspaced-build-dep/files/file3 new file mode 100644 index 000000000..e69de29bb --- /dev/null +++ b/tests/frontend/workspaced-build-dep/files/file3 diff --git a/tests/frontend/workspaced-build-dep/files/file4 b/tests/frontend/workspaced-build-dep/files/file4 new file mode 100644 index 000000000..e69de29bb --- /dev/null +++ b/tests/frontend/workspaced-build-dep/files/file4 diff --git a/tests/frontend/workspaced-build-dep/project.conf b/tests/frontend/workspaced-build-dep/project.conf new file mode 100644 index 000000000..e017957da --- /dev/null +++ b/tests/frontend/workspaced-build-dep/project.conf @@ -0,0 +1,8 @@ +# Unique project name +name: test + +# Required BuildStream format version +format-version: 12 + +# Subdirectory where elements are stored +element-path: elements diff --git a/tests/frontend/workspaced-runtime-dep/elements/elem1.bst b/tests/frontend/workspaced-runtime-dep/elements/elem1.bst new file mode 100644 index 000000000..eed39a95a --- /dev/null +++ b/tests/frontend/workspaced-runtime-dep/elements/elem1.bst @@ -0,0 +1,5 @@ +kind: import + +sources: +- kind: local + path: files/file1 diff --git a/tests/frontend/workspaced-runtime-dep/elements/elem2.bst b/tests/frontend/workspaced-runtime-dep/elements/elem2.bst new file mode 100644 index 000000000..a841b9fd0 --- /dev/null +++ b/tests/frontend/workspaced-runtime-dep/elements/elem2.bst @@ -0,0 +1,8 @@ +kind: import + +runtime-depends: +- elem1.bst + +sources: +- kind: local + path: files/file2 diff --git a/tests/frontend/workspaced-runtime-dep/elements/elem3.bst b/tests/frontend/workspaced-runtime-dep/elements/elem3.bst new file mode 100644 index 000000000..d817f4bb0 --- /dev/null +++ b/tests/frontend/workspaced-runtime-dep/elements/elem3.bst @@ -0,0 +1,8 @@ +kind: import + +runtime-depends: +- elem2.bst + +sources: +- kind: local + path: files/file3 diff --git a/tests/frontend/workspaced-runtime-dep/elements/elem4.bst b/tests/frontend/workspaced-runtime-dep/elements/elem4.bst new file mode 100644 index 000000000..a04f509a6 --- /dev/null +++ b/tests/frontend/workspaced-runtime-dep/elements/elem4.bst @@ -0,0 +1,8 @@ +kind: import + +build-depends: +- stack.bst + +sources: +- kind: local + path: files/file4 diff --git a/tests/frontend/workspaced-runtime-dep/elements/elem5.bst b/tests/frontend/workspaced-runtime-dep/elements/elem5.bst new file mode 100644 index 000000000..4fb3af822 --- /dev/null +++ b/tests/frontend/workspaced-runtime-dep/elements/elem5.bst @@ -0,0 +1,8 @@ +kind: import + +build-depends: +- elem3.bst + +sources: +- kind: local + path: files/file4 diff --git a/tests/frontend/workspaced-runtime-dep/elements/stack.bst b/tests/frontend/workspaced-runtime-dep/elements/stack.bst new file mode 100644 index 000000000..b4c6002f0 --- /dev/null +++ b/tests/frontend/workspaced-runtime-dep/elements/stack.bst @@ -0,0 +1,4 @@ +kind: stack + +depends: +- elem3.bst diff --git a/tests/frontend/workspaced-runtime-dep/files/file1 b/tests/frontend/workspaced-runtime-dep/files/file1 new file mode 100644 index 000000000..e69de29bb --- /dev/null +++ b/tests/frontend/workspaced-runtime-dep/files/file1 diff --git a/tests/frontend/workspaced-runtime-dep/files/file2 b/tests/frontend/workspaced-runtime-dep/files/file2 new file mode 100644 index 000000000..e69de29bb --- /dev/null +++ b/tests/frontend/workspaced-runtime-dep/files/file2 diff --git a/tests/frontend/workspaced-runtime-dep/files/file3 b/tests/frontend/workspaced-runtime-dep/files/file3 new file mode 100644 index 000000000..e69de29bb --- /dev/null +++ b/tests/frontend/workspaced-runtime-dep/files/file3 diff --git a/tests/frontend/workspaced-runtime-dep/files/file4 b/tests/frontend/workspaced-runtime-dep/files/file4 new file mode 100644 index 000000000..e69de29bb --- /dev/null +++ b/tests/frontend/workspaced-runtime-dep/files/file4 diff --git a/tests/frontend/workspaced-runtime-dep/project.conf b/tests/frontend/workspaced-runtime-dep/project.conf new file mode 100644 index 000000000..e017957da --- /dev/null +++ b/tests/frontend/workspaced-runtime-dep/project.conf @@ -0,0 +1,8 @@ +# Unique project name +name: test + +# Required BuildStream format version +format-version: 12 + +# Subdirectory where elements are stored +element-path: elements |