diff options
author | Jim MacArthur <jim.macarthur@codethink.co.uk> | 2018-10-23 17:57:16 +0100 |
---|---|---|
committer | Jim MacArthur <jim.macarthur@codethink.co.uk> | 2018-10-23 17:57:16 +0100 |
commit | a8c76395365fa51ec0068fa1bc736554cd1bb3f6 (patch) | |
tree | 4a39140ced1b1c37b5992b54c386984351997b7c | |
parent | e1b047ef61cd3727355915868f6cd546b6a4205f (diff) | |
download | buildstream-a8c76395365fa51ec0068fa1bc736554cd1bb3f6.tar.gz |
casbaseddirectory: Various fixes.
-rw-r--r-- | buildstream/storage/_casbaseddirectory.py | 44 |
1 files changed, 41 insertions, 3 deletions
diff --git a/buildstream/storage/_casbaseddirectory.py b/buildstream/storage/_casbaseddirectory.py index cc28fbd98..1a078b225 100644 --- a/buildstream/storage/_casbaseddirectory.py +++ b/buildstream/storage/_casbaseddirectory.py @@ -288,9 +288,12 @@ class CasBasedDirectory(Directory): return entry.descend(subdirectory_spec[1:], create) else: # May be a symlink + target = self._resolve(subdirectory_spec[0]) + if isinstance(target, CasBasedDirectory): + return target error = "Cannot descend into {}, which is a '{}' in the directory {}" raise VirtualDirectoryError(error.format(subdirectory_spec[0], - type(entry).__name__, + type(self.index[subdirectory_spec[0]].pb_object).__name__, self)) else: if create: @@ -328,6 +331,7 @@ class CasBasedDirectory(Directory): return self.index[name].buildstream_object # OK then, it's a symlink symlink = self._find_pb2_entry(name) + assert isinstance(symlink, remote_execution_pb2.SymlinkNode) absolute = symlink.target.startswith(CasBasedDirectory._pb2_absolute_path_prefix) if absolute: root = self.find_root() @@ -344,6 +348,16 @@ class CasBasedDirectory(Directory): directory = directory.descend(c, create=True) return directory + def _is_followable(self, name): + """ Returns true if this is a directory or symlink to a valid directory. """ + if name not in self.index: + return False + if isinstance(self.index[name].buildstream_object, Directory): + return True + target = self._resolve(name) + print("Is {} followable? Resolved to {}".format(name, target)) + return isinstance(target, CasBasedDirectory) or target is None + def _resolve_symlink(self, node): """Same as _resolve_symlink_or_directory but takes a SymlinkNode. """ @@ -476,7 +490,13 @@ class CasBasedDirectory(Directory): """ _import_directory_recursively and _import_files_from_directory will be called alternately as a directory tree is descended. """ if directory_name in self.index: - subdir = self._resolve_symlink_or_directory(directory_name) + if self._is_followable(directory_name): + subdir = self._resolve_symlink_or_directory(directory_name) + else: + print("Overwriting unfollowable thing {}".format(directory_name)) + self.delete_entry(directory_name) + subdir = self._add_directory(directory_name) + # TODO: Add this to the list of overwritten things. else: subdir = self._add_directory(directory_name) new_path_prefix = os.path.join(path_prefix, directory_name) @@ -607,6 +627,12 @@ class CasBasedDirectory(Directory): if dirname not in processed_directories: # Now strip off the first directory name and import files recursively. subcomponents = CasBasedDirectory.files_in_subdir(files, dirname) + # We will fail at this point if there is a file or symlink to file called 'dirname'. + if dirname in self.index: + x = self._resolve(dirname) + if isinstance(x, remote_execution_pb2.FileNode): + self.delete_entry(dirname) + result.overwritten.append(f) self.create_directory(dirname) print("Creating destination in {}: {}".format(self, dirname)) dest_subdir = self._resolve_symlink_or_directory(dirname) @@ -688,6 +714,18 @@ class CasBasedDirectory(Directory): print("Extracted all files from source directory '{}': {}".format(source_directory, files)) return self._partial_import_cas_into_cas(source_directory, list(files)) + def _describe(self, thing): + # Describes protocol buffer objects + if isinstance(thing, remote_execution_pb2.DirectoryNode): + return "directory called {}".format(thing.name) + elif isinstance(thing, remote_execution_pb2.SymlinkNode): + return "symlink called {} pointing to {}".format(thing.name, thing.target) + elif isinstance(thing, remote_execution_pb2.FileNode): + return "file called {}".format(thing.name) + else: + return "strange thing" + + def showdiff(self, other): print("Diffing {} and {}:".format(self, other)) @@ -701,7 +739,7 @@ class CasBasedDirectory(Directory): return False item2 = l2[index] if item1.name != item2.name: - print("Items do not match: {} in l1, {} in l2".format(item1.name, item2.name)) + print("Items do not match: {}, a {} in l1, vs {}, a {} in l2".format(item1.name, self._describe(item1), item2.name, self._describe(item2))) return False index += 1 if index != len(l2): |