summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTristan Van Berkom <tristan.vanberkom@codethink.co.uk>2018-04-09 19:04:26 +0900
committerTristan Van Berkom <tristan.van.berkom@gmail.com>2018-04-09 10:25:36 +0000
commit67d22d7696d42ef86bac3b3a1bc18e13ffb912a8 (patch)
tree8d4e18a92b08bac66a46d9b3fb7c6544c8c4dd43
parent0fbb550e4d0ddaa96b7d9fa82e848924910939e5 (diff)
downloadbuildstream-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.py2
-rw-r--r--buildstream/element.py54
-rw-r--r--buildstream/source.py50
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