diff options
author | Jürg Billeter <j@bitron.ch> | 2020-04-22 12:20:16 +0200 |
---|---|---|
committer | bst-marge-bot <marge-bot@buildstream.build> | 2020-04-27 08:32:32 +0000 |
commit | 9ce3da0ab8b6a2998b2565864e8234680976f198 (patch) | |
tree | cbcc979a58f92a9918e82dd46483ae99040c83bc /src | |
parent | 047549f45ee9670798f2c32822d7429a819964a1 (diff) | |
download | buildstream-9ce3da0ab8b6a2998b2565864e8234680976f198.tar.gz |
storage: Add Directory.rename() method
Diffstat (limited to 'src')
-rw-r--r-- | src/buildstream/storage/_casbaseddirectory.py | 11 | ||||
-rw-r--r-- | src/buildstream/storage/_filebaseddirectory.py | 11 | ||||
-rw-r--r-- | src/buildstream/storage/directory.py | 10 |
3 files changed, 32 insertions, 0 deletions
diff --git a/src/buildstream/storage/_casbaseddirectory.py b/src/buildstream/storage/_casbaseddirectory.py index e20c1e73a..c83918e4d 100644 --- a/src/buildstream/storage/_casbaseddirectory.py +++ b/src/buildstream/storage/_casbaseddirectory.py @@ -319,6 +319,17 @@ class CasBasedDirectory(Directory): del self.index[name] self.__invalidate_digest() + def rename(self, src, dest): + srcdir = self.descend(*src[:-1]) + entry = srcdir._entry_from_path(src[-1]) + + destdir = self.descend(*dest[:-1]) + self.__validate_path_component(dest[-1]) + + srcdir.remove(src[-1], recursive=True) + entry.name = dest[-1] + destdir._add_entry(entry) + def descend(self, *paths, create=False, follow_symlinks=False): """Descend one or more levels of directory hierarchy and return a new Directory object for that directory. diff --git a/src/buildstream/storage/_filebaseddirectory.py b/src/buildstream/storage/_filebaseddirectory.py index 60d63d567..12312299d 100644 --- a/src/buildstream/storage/_filebaseddirectory.py +++ b/src/buildstream/storage/_filebaseddirectory.py @@ -312,6 +312,17 @@ class FileBasedDirectory(Directory): else: os.unlink(newpath) + def rename(self, src, dest): + # Use descend() to avoid following symlinks (potentially escaping the sandbox) + srcdir = self.descend(*src[:-1]) + destdir = self.descend(*dest[:-1]) + srcpath = os.path.join(srcdir.external_directory, src[-1]) + destpath = os.path.join(destdir.external_directory, dest[-1]) + + if destdir.exists(dest[-1]): + destdir.remove(dest[-1]) + os.rename(srcpath, destpath) + def __iter__(self): yield from os.listdir(self.external_directory) diff --git a/src/buildstream/storage/directory.py b/src/buildstream/storage/directory.py index 2b3a85be3..f9ea4044a 100644 --- a/src/buildstream/storage/directory.py +++ b/src/buildstream/storage/directory.py @@ -306,6 +306,16 @@ class Directory: """ raise NotImplementedError() + def rename(self, src: List[str], dest: List[str]): + """ Rename a file, symlink or directory. If destination path exists + already and is a file or empty directory, it will be replaced. + + Args: + *src: Source path components. + *dest: Destination path components. + """ + raise NotImplementedError() + def _create_empty_file(self, *paths): with self.open_file(*paths, mode="w"): pass |