in src/buildstream/_cas/cascache.py [0:0]
def checkout(self, dest, tree, *, can_link=False, _fetch=True):
if _fetch:
# We need the files in the local cache
self.ensure_tree(tree)
os.makedirs(dest, exist_ok=True)
directory = remote_execution_pb2.Directory()
with open(self.objpath(tree), "rb") as f:
directory.ParseFromString(f.read())
for filenode in directory.files:
# regular file, create hardlink
fullpath = os.path.join(dest, filenode.name)
node_properties = filenode.node_properties
if node_properties.HasField("mtime"):
mtime = utils._parse_protobuf_timestamp(node_properties.mtime)
else:
mtime = None
if can_link and mtime is None:
utils.safe_link(self.objpath(filenode.digest), fullpath)
else:
utils.safe_copy(self.objpath(filenode.digest), fullpath, copystat=False)
if mtime is not None:
utils._set_file_mtime(fullpath, mtime)
if filenode.is_executable:
st = os.stat(fullpath)
mode = st.st_mode
if mode & stat.S_IRUSR:
mode |= stat.S_IXUSR
if mode & stat.S_IRGRP:
mode |= stat.S_IXGRP
if mode & stat.S_IROTH:
mode |= stat.S_IXOTH
os.chmod(fullpath, mode)
for dirnode in directory.directories:
fullpath = os.path.join(dest, dirnode.name)
self.checkout(fullpath, dirnode.digest, can_link=can_link, _fetch=False)
for symlinknode in directory.symlinks:
# symlink
fullpath = os.path.join(dest, symlinknode.name)
os.symlink(symlinknode.target, fullpath)
node_properties = directory.node_properties
if node_properties.HasField("mtime"):
mtime = utils._parse_protobuf_timestamp(node_properties.mtime)
utils._set_file_mtime(dest, mtime)