def update_from_single_version(self, is_new: IS_NEW_TEST, single_version_fs: FS) -> bool: # TODO This import is circular; that's why I have it here # inside the function. But there must be a better way to # structure. from pdart.fs.multiversioned.version_view import ( is_segment, strip_segment, vv_lid_path, ) # TODO Note that this makes assumptions about the source # filesystem format. Document them. def update_from_lid(lid: LID) -> LIDVID: # Find the path corresponding to this LID. path = vv_lid_path(lid) # First, update all the children recursively. Get their # LIDs by extending this LID with the names of the # subdirectories of path. That handles directories. child_lidvids: Set[LIDVID] = { update_from_lid(lid.extend_lid(strip_segment(name))) for name in single_version_fs.listdir(path) if is_segment(name) } # Now look at files. We create a VersionContents object # from the set of new LIDVIDs and all the files contained # in the component's directory. contents = VersionContents.create_from_lidvids_and_dirpath( child_lidvids, single_version_fs, path) # Now we ask the Multiversioned to insert these contents # as a new version if needed. It returns the new LIDVID # if a new LIDVID is needed, otherwise it returns the old # one. return self.add_contents_if(is_new, lid, contents, False) bundle_segs = [ strip_segment(name) for name in single_version_fs.listdir("/") if is_segment(name) ] # TODO I can't see any reason why there wouldn't be exactly a # single segment, but I'm throwing in an assert to let me know # if I'm wrong. if len(bundle_segs) != 1: raise ValueError(f"bundle_segs: {bundle_segs} is more than 1.") changed = False for bundle_seg in bundle_segs: lid = LID.create_from_parts([str(bundle_seg)]) orig_lidvid: Optional[LIDVID] = self.latest_lidvid(lid) new_lidvid: LIDVID = update_from_lid(lid) changed = changed or new_lidvid != orig_lidvid return changed
def categorize_filesystem(fs: FS) -> str: top_level_listing = fs.listdir("/") if not top_level_listing: return EMPTY_FS_TYPE elif any(name[-1] == "$" for name in top_level_listing): return SINGLE_VERSIONED_FS_TYPE elif any(is_version_dir(dir) for dir in fs.walk.dirs()): return MULTIVERSIONED_FS_TYPE else: return UNKNOWN_FS_TYPE
def get_module_version(module_name: str, directory: FS) -> str: """ Get the version of the module in the given directory :param module_name: name of the module :param directory: FS object pointing to the parent directory of the module :return: version of the module or None if it is not present in the directory """ version = None if module_name in directory.listdir("."): manifest = directory.readtext(join(module_name, "__manifest__.py")) version = ast.literal_eval(manifest)["version"] return version
def install_from_fs(self, name: str, source_fs: FS, path: str = ".", output_name: str = None): """ Copy a module directory from where it is located to the installation directory. :param name: Name of the module :param source_fs: FS object pointing to the source location :param path: Path to the module directory from the source location root :param output_name: Name to give to the module's directory at installation """ path_to_module = join(path, name) if name not in source_fs.listdir(path): raise InvalidModuleError( name, "Module directory not found - Given path should be the parent directory" ) if "__manifest__.py" not in source_fs.listdir(path_to_module): raise InvalidModuleError( name, "Manifest not found - Given path should be the parent directory" ) self.pretty_print(output_name, "Copying from {}".format( source_fs.desc(path_to_module)), level=VERBOSE_FULL) copy_dir(source_fs, path_to_module, self.install_dir, output_name or name) self.pretty_print(output_name, "Installed and up to date.", status=LOG_STATUS_OK, level=VERBOSE_NORMAL)