diff options
author | Tristan Van Berkom <tristan.vanberkom@codethink.co.uk> | 2018-04-09 19:04:26 +0900 |
---|---|---|
committer | Tristan Van Berkom <tristan.van.berkom@gmail.com> | 2018-04-09 10:25:36 +0000 |
commit | 67d22d7696d42ef86bac3b3a1bc18e13ffb912a8 (patch) | |
tree | 8d4e18a92b08bac66a46d9b3fb7c6544c8c4dd43 | |
parent | 0fbb550e4d0ddaa96b7d9fa82e848924910939e5 (diff) | |
download | buildstream-67d22d7696d42ef86bac3b3a1bc18e13ffb912a8.tar.gz |
element.py, source.py: Element consumes the rest of workspace logic.
And Source no longer has any __workspace handle.
-rw-r--r-- | buildstream/_workspaces.py | 2 | ||||
-rw-r--r-- | buildstream/element.py | 54 | ||||
-rw-r--r-- | buildstream/source.py | 50 |
3 files changed, 45 insertions, 61 deletions
diff --git a/buildstream/_workspaces.py b/buildstream/_workspaces.py index 8b7458771..127d2a66e 100644 --- a/buildstream/_workspaces.py +++ b/buildstream/_workspaces.py @@ -92,8 +92,6 @@ class Workspace(): # def init(self, element): self._element = element - for source in element.sources(): - source._set_workspace(self) # invalidate_key() # diff --git a/buildstream/element.py b/buildstream/element.py index 13d13a861..0b0588aa4 100644 --- a/buildstream/element.py +++ b/buildstream/element.py @@ -162,6 +162,7 @@ class Element(Plugin): self.__log_path = None # Path to dedicated log file or None self.__splits = None self.__whitelist_regex = None + self.__workspace = None # The associated Workspace, if any # Ensure we have loaded this class's defaults self.__init_defaults(plugin_conf) @@ -987,6 +988,17 @@ class Element(Plugin): context = self._get_context() project = self._get_project() + workspace = self._get_workspace() + + # Use the workspace key in source cache key calculations. + # + # This is only done this way to retain backwards compatibility + # of the cache key after making workspaces element wide instead + # of being source specific. + # + workspace_key = None + if workspace: + workspace_key = workspace.get_key() self.__cache_key_dict = { 'artifact-version': "{}.{}".format(BST_CORE_ARTIFACT_VERSION, @@ -996,7 +1008,7 @@ class Element(Plugin): 'element': self.get_unique_key(), 'execution-environment': self.__sandbox_config.get_unique_key(), 'environment': cache_env, - 'sources': [s._get_unique_key() for s in self.__sources], + 'sources': [s._get_unique_key(workspace_key) for s in self.__sources], 'public': self.__public, 'cache': type(self.__artifacts).__name__ } @@ -1103,9 +1115,16 @@ class Element(Plugin): def _track(self): refs = [] for source in self.__sources: + old_ref = source.get_ref() new_ref = source._track() refs.append((source._get_unique_id(), new_ref)) + # Complimentary warning that the new ref will be unused. + if old_ref != new_ref and self._get_workspace(): + detail = "This source has an open workspace.\n" \ + + "To start using the new reference, please close the existing workspace." + source.warn("Updated reference will be ignored as source has open workspace", detail=detail) + return refs # _assemble(): @@ -1332,12 +1351,6 @@ class Element(Plugin): os.makedirs(directory, exist_ok=True) return os.path.join(directory, logfile) - # Set a source's workspace - # - def _set_source_workspaces(self, path): - for source in self.sources(): - source._set_workspace(path) - # _get_workspace(): # # Returns: @@ -1537,13 +1550,8 @@ class Element(Plugin): # perform incremental builds. if mount_workspaces and self._can_build_incrementally(): workspace = self._get_workspace() - # First, mount sources that have an open workspace - sources_to_mount = [source for source in self.sources() if source._has_workspace()] - for source in sources_to_mount: - mount_point = source._get_staging_path(directory) - mount_source = workspace.get_absolute_path() - sandbox.mark_directory(mount_point) - sandbox._set_mount_source(mount_point, mount_source) + sandbox.mark_directory(directory) + sandbox._set_mount_source(directory, workspace.get_absolute_path()) # Stage all sources that need to be copied sandbox_root = sandbox.get_directory() @@ -1564,15 +1572,17 @@ class Element(Plugin): if os.path.isdir(directory) and os.listdir(directory): raise ElementError("Staging directory '{}' is not empty".format(directory)) - # If mount_workspaces is set, sources with workspace are mounted - # directly inside the sandbox so no need to stage them here. - if mount_workspaces and self._can_build_incrementally(): - sources = [source for source in self.sources() if not source._has_workspace()] + workspace = self._get_workspace() + if workspace: + # If mount_workspaces is set and we're doing incremental builds, + # the workspace is already mounted into the sandbox. + if not (mount_workspaces and self._can_build_incrementally()): + with self.timed_activity("Staging local files at {}".format(workspace.path)): + workspace.stage(directory) else: - sources = self.sources() - - for source in sources: - source._stage(directory) + # No workspace, stage directly + for source in self.sources(): + source._stage(directory) # Ensure deterministic mtime of sources at build time utils._set_deterministic_mtime(directory) diff --git a/buildstream/source.py b/buildstream/source.py index e6ca99735..2c1b8445e 100644 --- a/buildstream/source.py +++ b/buildstream/source.py @@ -88,7 +88,6 @@ class Source(Plugin): self.__element_index = meta.element_index # The index of the source in the owning element's source list self.__directory = meta.directory # Staging relative directory self.__consistency = Consistency.INCONSISTENT # Cached consistency state - self.__workspace = None # Directory of the currently active workspace # Collect the composited element configuration and # ask the element to configure itself. @@ -327,15 +326,12 @@ class Source(Plugin): def _fetch(self): self.fetch() - # Return the path where this source should be staged under given directory - def _get_staging_path(self, directory): + # Ensures a fully constructed path and returns it + def _ensure_directory(self, directory): + if self.__directory is not None: directory = os.path.join(directory, self.__directory.lstrip(os.sep)) - return directory - # Ensures a fully constructed path and returns it - def _ensure_directory(self, directory): - directory = self._get_staging_path(directory) try: os.makedirs(directory, exist_ok=True) except OSError as e: @@ -351,11 +347,7 @@ class Source(Plugin): def _stage(self, directory): staging_directory = self._ensure_directory(directory) - if self._has_workspace(): - with self.timed_activity("Staging local files at {}".format(self.__workspace.path)): - self.__workspace.stage(staging_directory) - else: - self.stage(staging_directory) + self.stage(staging_directory) # Wrapper for init_workspace() def _init_workspace(self, directory): @@ -363,18 +355,24 @@ class Source(Plugin): self.init_workspace(directory) + # _get_unique_key(): + # # Wrapper for get_unique_key() api # + # Args: + # workspace_key: An alternative key to use instead of this + # source's unique key + # # This adds any core attributes to the key and # also calculates something different if workspaces # are active. # - def _get_unique_key(self): + def _get_unique_key(self, workspace_key=None): key = {} key['directory'] = self.__directory - if self._has_workspace(): - key['workspace'] = self.__workspace.get_key() + if workspace_key is not None: + key['workspace'] = workspace_key else: key['unique'] = self.get_unique_key() @@ -546,27 +544,5 @@ class Source(Plugin): if current_ref != new_ref: self.info("Found new revision: {}".format(new_ref)) - if self._has_workspace(): - detail = "This source has an open workspace.\n" \ - + "To start using the new reference, please close the existing workspace." - self.warn("Updated reference will be ignored as source has open workspace", detail=detail) return new_ref - - # Set the current workspace - # - # Note that this invalidates the workspace key. - # - def _set_workspace(self, workspace): - if self._has_workspace(): - self.__workspace.invalidate_key() - self.__workspace = workspace - - # Return the current workspace directory - def _get_workspace(self): - return self.__workspace.path - - # Whether the source has a set workspace - # - def _has_workspace(self): - return self.__workspace is not None |