summaryrefslogtreecommitdiff
path: root/buildstream
diff options
context:
space:
mode:
authorPhillip Smyth <phillipsmyth@Nexus-x240.dyn.ducie.codethink.co.uk>2018-06-18 14:34:39 +0100
committerTristan van Berkom <tristan.vanberkom@codethink.co.uk>2019-08-04 14:11:13 -0400
commit0a457a720999ad6f3621020ef31f7fff9389fd5d (patch)
tree07f923db570b4c672c4ed0ee9c4b7215883a29a0 /buildstream
parentb2a2c76b70d6ebf32506fb38a207d41bdfec7994 (diff)
downloadbuildstream-0a457a720999ad6f3621020ef31f7fff9389fd5d.tar.gz
Implementing relative workspacestristan/bst-1/relative-workspaces
This fixes #191 A note has been added to NEWS explaining backwards compatibility issues
Diffstat (limited to 'buildstream')
-rw-r--r--buildstream/_frontend/widget.py4
-rw-r--r--buildstream/_stream.py32
-rw-r--r--buildstream/_workspaces.py41
-rw-r--r--buildstream/element.py7
4 files changed, 41 insertions, 43 deletions
diff --git a/buildstream/_frontend/widget.py b/buildstream/_frontend/widget.py
index a772f3248..80fffd201 100644
--- a/buildstream/_frontend/widget.py
+++ b/buildstream/_frontend/widget.py
@@ -416,7 +416,9 @@ class LogLine(Widget):
if "%{workspace-dirs" in format_:
workspace = element._get_workspace()
if workspace is not None:
- path = workspace.path.replace(os.getenv('HOME', '/root'), '~')
+ path = workspace.get_absolute_path()
+ if path.startswith("~/"):
+ path = os.path.join(os.getenv('HOME', '/root'), path[2:])
line = p.fmt_subst(line, 'workspace-dirs', "Workspace: {}".format(path))
else:
line = p.fmt_subst(
diff --git a/buildstream/_stream.py b/buildstream/_stream.py
index 19c73b85e..dd33c6a62 100644
--- a/buildstream/_stream.py
+++ b/buildstream/_stream.py
@@ -476,7 +476,7 @@ class Stream():
selection=PipelineSelection.REDIRECT,
track_selection=PipelineSelection.REDIRECT)
target = elements[0]
- workdir = os.path.abspath(directory)
+ directory = os.path.abspath(directory)
if not list(target.sources()):
build_depends = [x.name for x in target.dependencies(Scope.BUILD, recurse=False)]
@@ -492,7 +492,7 @@ class Stream():
workspace = workspaces.get_workspace(target._get_full_name())
if workspace and not force:
raise StreamError("Workspace '{}' is already defined at: {}"
- .format(target.name, workspace.path))
+ .format(target.name, workspace.get_absolute_path()))
# If we're going to checkout, we need at least a fetch,
# if we were asked to track first, we're going to fetch anyway.
@@ -518,7 +518,7 @@ class Stream():
except OSError as e:
raise StreamError("Failed to create workspace directory: {}".format(e)) from e
- workspaces.create_workspace(target._get_full_name(), workdir)
+ workspaces.create_workspace(target._get_full_name(), directory)
if not no_checkout:
with target.timed_activity("Staging sources to {}".format(directory)):
@@ -542,12 +542,12 @@ class Stream():
# Remove workspace directory if prompted
if remove_dir:
with self._context.timed_activity("Removing workspace directory {}"
- .format(workspace.path)):
+ .format(workspace.get_absolute_path())):
try:
- shutil.rmtree(workspace.path)
+ shutil.rmtree(workspace.get_absolute_path())
except OSError as e:
raise StreamError("Could not remove '{}': {}"
- .format(workspace.path, e)) from e
+ .format(workspace.get_absolute_path(), e)) from e
# Delete the workspace and save the configuration
workspaces.delete_workspace(element_name)
@@ -590,28 +590,30 @@ class Stream():
for element in elements:
workspace = workspaces.get_workspace(element._get_full_name())
-
+ workspace_path = workspace.get_absolute_path()
if soft:
workspace.prepared = False
self._message(MessageType.INFO, "Reset workspace state for {} at: {}"
- .format(element.name, workspace.path))
+ .format(element.name, workspace_path))
continue
with element.timed_activity("Removing workspace directory {}"
- .format(workspace.path)):
+ .format(workspace_path)):
try:
- shutil.rmtree(workspace.path)
+ shutil.rmtree(workspace_path)
except OSError as e:
raise StreamError("Could not remove '{}': {}"
- .format(workspace.path, e)) from e
+ .format(workspace_path, e)) from e
workspaces.delete_workspace(element._get_full_name())
- workspaces.create_workspace(element._get_full_name(), workspace.path)
+ workspaces.create_workspace(element._get_full_name(), workspace_path)
- with element.timed_activity("Staging sources to {}".format(workspace.path)):
+ with element.timed_activity("Staging sources to {}".format(workspace_path)):
element._open_workspace()
- self._message(MessageType.INFO, "Reset workspace for {} at: {}".format(element.name, workspace.path))
+ self._message(MessageType.INFO,
+ "Reset workspace for {} at: {}".format(element.name,
+ workspace_path))
workspaces.save_config()
@@ -648,7 +650,7 @@ class Stream():
for element_name, workspace_ in self._context.get_workspaces().list():
workspace_detail = {
'element': element_name,
- 'directory': workspace_.path,
+ 'directory': workspace_.get_absolute_path(),
}
workspaces.append(workspace_detail)
diff --git a/buildstream/_workspaces.py b/buildstream/_workspaces.py
index 3f474b8ca..adffaa694 100644
--- a/buildstream/_workspaces.py
+++ b/buildstream/_workspaces.py
@@ -26,14 +26,6 @@ from ._exceptions import LoadError, LoadErrorReason
BST_WORKSPACE_FORMAT_VERSION = 3
-# Hold on to a list of members which get serialized
-_WORKSPACE_MEMBERS = [
- 'prepared',
- 'path',
- 'last_successful',
- 'running_files'
-]
-
# Workspace()
#
@@ -56,7 +48,7 @@ class Workspace():
def __init__(self, toplevel_project, *, last_successful=None, path=None, prepared=False, running_files=None):
self.prepared = prepared
self.last_successful = last_successful
- self.path = path
+ self._path = path
self.running_files = running_files if running_files is not None else {}
self._toplevel_project = toplevel_project
@@ -64,14 +56,20 @@ class Workspace():
# to_dict()
#
- # Convert this object to a dict for serialization purposes
+ # Convert a list of members which get serialized to a dict for serialization purposes
#
# Returns:
# (dict) A dict representation of the workspace
#
def to_dict(self):
- return {key: val for key, val in self.__dict__.items()
- if key in _WORKSPACE_MEMBERS and val is not None}
+ ret = {
+ 'prepared': self.prepared,
+ 'path': self._path,
+ 'running_files': self.running_files
+ }
+ if self.last_successful is not None:
+ ret["last_successful"] = self.last_successful
+ return ret
# from_dict():
#
@@ -103,15 +101,7 @@ class Workspace():
# True if the workspace differs from 'other', otherwise False
#
def differs(self, other):
-
- for member in _WORKSPACE_MEMBERS:
- member_a = getattr(self, member)
- member_b = getattr(other, member)
-
- if member_a != member_b:
- return True
-
- return False
+ return self.to_dict() != other.to_dict()
# invalidate_key()
#
@@ -133,7 +123,7 @@ class Workspace():
if os.path.isdir(fullpath):
utils.copy_files(fullpath, directory)
else:
- destfile = os.path.join(directory, os.path.basename(self.path))
+ destfile = os.path.join(directory, os.path.basename(self.get_absolute_path()))
utils.safe_copy(fullpath, destfile)
# add_running_files()
@@ -189,7 +179,7 @@ class Workspace():
filelist = utils.list_relative_paths(fullpath)
filelist = [(relpath, os.path.join(fullpath, relpath)) for relpath in filelist]
else:
- filelist = [(self.path, fullpath)]
+ filelist = [(self.get_absolute_path(), fullpath)]
self._key = [(relpath, unique_key(fullpath)) for relpath, fullpath in filelist]
@@ -200,7 +190,7 @@ class Workspace():
# Returns: The absolute path of the element's workspace.
#
def get_absolute_path(self):
- return os.path.join(self._toplevel_project.directory, self.path)
+ return os.path.join(self._toplevel_project.directory, self._path)
# Workspaces()
@@ -236,6 +226,9 @@ class Workspaces():
# path (str) - The path in which the workspace should be kept
#
def create_workspace(self, element_name, path):
+ if path.startswith(self._toplevel_project.directory):
+ path = os.path.relpath(path, self._toplevel_project.directory)
+
self._workspaces[element_name] = Workspace(self._toplevel_project, path=path)
return self._workspaces[element_name]
diff --git a/buildstream/element.py b/buildstream/element.py
index 370eb7547..0ef7f09be 100644
--- a/buildstream/element.py
+++ b/buildstream/element.py
@@ -1385,7 +1385,8 @@ class Element(Plugin):
# 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)):
+ with self.timed_activity("Staging local files at {}"
+ .format(workspace.get_absolute_path())):
workspace.stage(directory)
else:
# No workspace, stage directly
@@ -1559,7 +1560,7 @@ class Element(Plugin):
sandbox_path = os.path.join(sandbox_root,
self.__staged_sources_directory.lstrip(os.sep))
try:
- utils.copy_files(workspace.path, sandbox_path)
+ utils.copy_files(workspace.get_absolute_path(), sandbox_path)
except UtilError as e:
self.warn("Failed to preserve workspace state for failed build sysroot: {}"
.format(e))
@@ -1864,7 +1865,7 @@ class Element(Plugin):
source._init_workspace(temp)
# Now hardlink the files into the workspace target.
- utils.link_files(temp, workspace.path)
+ utils.link_files(temp, workspace.get_absolute_path())
# _get_workspace():
#