[Notes] [Git][BuildStream/buildstream][jmac/vdir_import_test] 2 commits: _casbaseddirectory: Corrections to list_relative_files, adds _resolve



Title: GitLab

Jim MacArthur pushed to branch jmac/vdir_import_test at BuildStream / buildstream

Commits:

1 changed file:

Changes:

  • buildstream/storage/_casbaseddirectory.py
    ... ... @@ -37,7 +37,7 @@ from .._protos.build.bazel.remote.execution.v2 import remote_execution_pb2
    37 37
     from .._exceptions import BstError
    
    38 38
     from .directory import Directory, VirtualDirectoryError
    
    39 39
     from ._filebaseddirectory import FileBasedDirectory
    
    40
    -from ..utils import FileListResult, safe_copy, list_relative_paths
    
    40
    +from ..utils import FileListResult, safe_copy, list_relative_paths, _relative_symlink_target
    
    41 41
     from .._artifactcache.cascache import CASCache
    
    42 42
     
    
    43 43
     
    
    ... ... @@ -286,6 +286,71 @@ class CasBasedDirectory(Directory):
    286 286
                     directory = directory.descend(c, create=True)
    
    287 287
             return directory
    
    288 288
     
    
    289
    +    def _resolve(self, name, absolute_symlinks_resolve=True):
    
    290
    +        """ Resolves any name to an object. If the name points to a symlink in this 
    
    291
    +        directory, it returns the thing it points to, recursively. Returns a CasBasedDirectory, FileNode or None. Never creates a directory or otherwise alters the directory. """
    
    292
    +        # First check if it's a normal object and return that
    
    293
    +
    
    294
    +        if name not in self.index:
    
    295
    +            return None
    
    296
    +        index_entry = self.index[name]
    
    297
    +        if isinstance(index_entry.buildstream_object, Directory):
    
    298
    +            return index_entry.buildstream_object
    
    299
    +        elif isinstance(index_entry.pb_object, remote_execution_pb2.FileNode):
    
    300
    +            return index_entry.pb_object
    
    301
    +        
    
    302
    +        assert isinstance(index_entry.pb_object, remote_execution_pb2.SymlinkNode)
    
    303
    +        symlink = index_entry.pb_object
    
    304
    +        components = symlink.target.split(CasBasedDirectory._pb2_path_sep)
    
    305
    +
    
    306
    +        absolute = symlink.target.startswith(CasBasedDirectory._pb2_absolute_path_prefix)
    
    307
    +        if absolute:
    
    308
    +            if absolute_symlinks_resolve:
    
    309
    +                start_directory = self.find_root()
    
    310
    +                # Discard the first empty element
    
    311
    +                components.pop(0)
    
    312
    +            else:
    
    313
    +                print("  _resolve: Absolute symlink, which we won't resolve.")
    
    314
    +                return None
    
    315
    +        else:
    
    316
    +            start_directory = self
    
    317
    +        directory = start_directory
    
    318
    +        print("Resolve {}: starting from {}".format(symlink.target, start_directory))
    
    319
    +        while True:
    
    320
    +            if not components:
    
    321
    +                # We ran out of path elements and ended up in a directory
    
    322
    +                return directory
    
    323
    +            c = components.pop(0)
    
    324
    +            if c == "..":
    
    325
    +                print("  resolving {}: up-dir".format(c))
    
    326
    +                # If directory.parent *is* None, this is an attempt to access
    
    327
    +                # '..' from the root, which is valid under POSIX; it just
    
    328
    +                # returns the root.                
    
    329
    +                if directory.parent is not None:
    
    330
    +                    directory = directory.parent
    
    331
    +            else:
    
    332
    +                if c in directory.index:
    
    333
    +                    f = directory._resolve(c, absolute_symlinks_resolve)
    
    334
    +                    # Ultimately f must now be a file or directory
    
    335
    +                    if isinstance(f, CasBasedDirectory):
    
    336
    +                        directory = f
    
    337
    +                        print("  resolving {}: dir".format(c))
    
    338
    +
    
    339
    +                    else:
    
    340
    +                        # This is a file or None (i.e. broken symlink)
    
    341
    +                        print("  resolving {}: file/broken link".format(c))
    
    342
    +                        if components:
    
    343
    +                            # Oh dear. We have components left to resolve, but the one we're trying to resolve points to a file.
    
    344
    +                            raise VirtualDirectoryError("Reached a file called {} while trying to resolve a symlink; cannot proceed".format(c))
    
    345
    +                        else:
    
    346
    +                            return f
    
    347
    +                else:
    
    348
    +                    print("  resolving {}: nonexistent!".format(c))
    
    349
    +                    return None
    
    350
    +
    
    351
    +        # Shouldn't get here.
    
    352
    +        
    
    353
    +
    
    289 354
         def _check_replacement(self, name, path_prefix, fileListResult):
    
    290 355
             """ Checks whether 'name' exists, and if so, whether we can overwrite it.
    
    291 356
             If we can, add the name to 'overwritten_files' and delete the existing entry.
    
    ... ... @@ -542,21 +607,27 @@ class CasBasedDirectory(Directory):
    542 607
             """
    
    543 608
     
    
    544 609
             print("Running list_relative_paths on relpath {}".format(relpath))
    
    545
    -        symlink_list = filter(lambda i: isinstance(i[1].pb_object, remote_execution_pb2.SymlinkNode), self.index.items())
    
    546
    -        file_list = filter(lambda i: isinstance(i[1].pb_object, remote_execution_pb2.FileNode), self.index.items())
    
    610
    +        symlink_list = list(filter(lambda i: isinstance(i[1].pb_object, remote_execution_pb2.SymlinkNode), self.index.items()))
    
    611
    +        file_list = list(filter(lambda i: isinstance(i[1].pb_object, remote_execution_pb2.FileNode), self.index.items()))
    
    612
    +        directory_list = list(filter(lambda i: isinstance(i[1].buildstream_object, CasBasedDirectory), self.index.items()))
    
    547 613
             print("Running list_relative_paths on relpath {}. files={}, symlinks={}".format(relpath, [f[0] for f in file_list], [s[0] for s in symlink_list]))
    
    548 614
     
    
    549 615
             for (k, v) in sorted(symlink_list):
    
    550
    -            print("Yielding symlink {}".format(k))
    
    551
    -            yield os.path.join(relpath, k)
    
    552
    -        for (k, v) in sorted(file_list):
    
    553
    -            print("Yielding file {}".format(k))
    
    554
    -            yield os.path.join(relpath, k)
    
    555
    -        else:
    
    616
    +            target = self._resolve(k, absolute_symlinks_resolve=True)
    
    617
    +            if isinstance(target, CasBasedDirectory):
    
    618
    +                print("Adding the resolved symlink {} which resolves to {} to our directory list".format(k, target))
    
    619
    +                directory_list.append((k,IndexEntry(k, buildstream_object=target)))
    
    620
    +            else:
    
    621
    +                # Broken symlinks are also considered files!
    
    622
    +                file_list.append((k,v))
    
    623
    +        if file_list == [] and relpath != "":
    
    556 624
                 print("Yielding empty directory name {}".format(relpath))
    
    557 625
                 yield relpath
    
    626
    +        else:
    
    627
    +            for (k, v) in sorted(file_list):
    
    628
    +                print("Yielding file {}".format(k))
    
    629
    +                yield os.path.join(relpath, k)
    
    558 630
     
    
    559
    -        directory_list = filter(lambda i: isinstance(i[1].buildstream_object, CasBasedDirectory), self.index.items())
    
    560 631
             for (k, v) in sorted(directory_list):
    
    561 632
                 print("Yielding from subdirectory name {}".format(k))
    
    562 633
                 yield from v.buildstream_object.list_relative_paths(relpath=os.path.join(relpath, k))
    



  • [Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]