diff options
author | Valentin David <valentin.david@codethink.co.uk> | 2018-08-06 17:13:21 +0200 |
---|---|---|
committer | Tristan Van Berkom <tristan.van.berkom@gmail.com> | 2018-08-12 05:54:36 +0000 |
commit | ccf6e479df23c2f28ea56f237459d32086af1406 (patch) | |
tree | a95c10de452a25d7bfe7d3517600f744fed999a3 /buildstream | |
parent | 48c715e3f5eb06372f75dcf778f0278273569812 (diff) | |
download | buildstream-ccf6e479df23c2f28ea56f237459d32086af1406.tar.gz |
buildstream/plugins/sources/local.py: Make staging deterministic.
Instead of copying metadata on files staged by local, we manually set
mode to 0755 or 0644 depending on whether user execution was enabled
on source file.
This makes file modes deterministic independently on the way source
was distributed.
Non-deterministic mode copying all metadata can still be enabled by
disable 'deterministic' Boolean configuration on the plugin.
Fixes #527.
Diffstat (limited to 'buildstream')
-rw-r--r-- | buildstream/plugins/sources/local.py | 26 |
1 files changed, 25 insertions, 1 deletions
diff --git a/buildstream/plugins/sources/local.py b/buildstream/plugins/sources/local.py index 058553424..7c19e1f90 100644 --- a/buildstream/plugins/sources/local.py +++ b/buildstream/plugins/sources/local.py @@ -37,6 +37,7 @@ local - stage local files and directories """ import os +import stat from buildstream import Source, Consistency from buildstream import utils @@ -94,12 +95,35 @@ class LocalSource(Source): # 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): - utils.copy_files(self.fullpath, directory) + files = list(utils.list_relative_paths(self.fullpath, list_dirs=True)) + utils.copy_files(self.fullpath, directory, files=files) 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) + # Create a unique key for a file def unique_key(filename): |