diff options
author | Raoul Hidalgo Charman <raoul.hidalgocharman@codethink.co.uk> | 2019-05-01 15:43:17 +0100 |
---|---|---|
committer | Raoul Hidalgo Charman <raoul.hidalgocharman@codethink.co.uk> | 2019-05-22 14:09:23 +0100 |
commit | e7dee9ed0049188f9541e36316c22d0e10a55818 (patch) | |
tree | 2db1d75ff1b73a6f2d87d1dbe98dee51ee3c761e | |
parent | 1cc15b44376a4022ab464f26e92f209bad9fa254 (diff) | |
download | buildstream-e7dee9ed0049188f9541e36316c22d0e10a55818.tar.gz |
local.py: Support staging directly into CAS
Part of #983
-rw-r--r-- | src/buildstream/plugins/sources/local.py | 48 |
1 files changed, 15 insertions, 33 deletions
diff --git a/src/buildstream/plugins/sources/local.py b/src/buildstream/plugins/sources/local.py index 50df85427..fba8af604 100644 --- a/src/buildstream/plugins/sources/local.py +++ b/src/buildstream/plugins/sources/local.py @@ -37,14 +37,16 @@ details on common configuration options for sources. """ import os -import stat -from buildstream import Source, Consistency +from buildstream.storage.directory import Directory +from buildstream import Source, SourceError, Consistency from buildstream import utils class LocalSource(Source): # pylint: disable=attribute-defined-outside-init + BST_STAGE_VIRTUAL_DIRECTORY = True + def __init__(self, context, project, meta): super().__init__(context, project, meta) @@ -91,38 +93,18 @@ class LocalSource(Source): pass # pragma: nocover def stage(self, directory): - - # Dont use hardlinks to stage sources, they are not write protected - # in the sandbox. - with self.timed_activity("Staging local files at {}".format(self.path)): - - if os.path.isdir(self.fullpath): - files = list(utils.list_relative_paths(self.fullpath)) - utils.copy_files(self.fullpath, directory) + # directory should always be a Directory object + assert isinstance(directory, Directory) + with self.timed_activity("Staging local files into CAS"): + if os.path.isdir(self.fullpath) and not os.path.islink(self.fullpath): + result = directory.import_files(self.fullpath) else: - destfile = os.path.join(directory, os.path.basename(self.path)) - files = [os.path.basename(self.path)] - utils.safe_copy(self.fullpath, destfile) - - for f in files: - # Non empty directories are not listed by list_relative_paths - dirs = f.split(os.sep) - for i in range(1, len(dirs)): - d = os.path.join(directory, *(dirs[:i])) - assert os.path.isdir(d) and not os.path.islink(d) - os.chmod(d, stat.S_IRWXU | stat.S_IRGRP | stat.S_IXGRP | stat.S_IROTH | stat.S_IXOTH) - - path = os.path.join(directory, f) - if os.path.islink(path): - pass - elif os.path.isdir(path): - os.chmod(path, stat.S_IRWXU | stat.S_IRGRP | stat.S_IXGRP | stat.S_IROTH | stat.S_IXOTH) - else: - st = os.stat(path) - if st.st_mode & stat.S_IXUSR: - os.chmod(path, stat.S_IRWXU | stat.S_IRGRP | stat.S_IXGRP | stat.S_IROTH | stat.S_IXOTH) - else: - os.chmod(path, stat.S_IRUSR | stat.S_IWUSR | stat.S_IRGRP | stat.S_IROTH) + result = directory.import_single_file(self.fullpath) + + if result.overwritten or result.ignored: + raise SourceError( + "Failed to stage source: files clash with existing directory", + reason='ensure-stage-dir-fail') def _get_local_path(self): return self.fullpath |