def print_status(self, fetch=False): """Print clowder repo status""" repo_path = os.path.join(self.root_directory, '.clowder') if not ProjectRepo.existing_git_repository(repo_path): output = colored('.clowder', 'green') print(output) return if not is_offline() and fetch: print(' - Fetch upstream changes for clowder repo') repo = ProjectRepo(self.clowder_path, self.remote, self.default_ref) repo.fetch(self.remote) project_output = ProjectRepo.format_project_string(repo_path, '.clowder') current_ref_output = ProjectRepo.format_project_ref_string(repo_path) clowder_symlink = os.path.join(self.root_directory, 'clowder.yaml') if not os.path.islink(clowder_symlink): print(project_output + ' ' + current_ref_output) return real_path = os.path.realpath(clowder_symlink) symlink_output = fmt.path('clowder.yaml') clowder_path = fmt.remove_prefix(real_path + '/', self.root_directory) path_output = fmt.path(clowder_path[1:-1]) print(project_output + ' ' + current_ref_output) print(symlink_output + ' -> ' + path_output + '\n')
def link(self, version=None): """Create symlink pointing to clowder.yaml file""" if version is None: yaml_file = os.path.join(self.root_directory, '.clowder', 'clowder.yaml') path_output = fmt.path('.clowder/clowder.yaml') else: relative_path = os.path.join('.clowder', 'versions', version, 'clowder.yaml') path_output = fmt.path(relative_path) yaml_file = os.path.join(self.root_directory, relative_path) if not os.path.isfile(yaml_file): print(path_output + " doesn't seem to exist\n") sys.exit(1) yaml_symlink = os.path.join(self.root_directory, 'clowder.yaml') print(' - Symlink ' + path_output) force_symlink(yaml_file, yaml_symlink)
def print_status(self, fetch: bool = False) -> None: """Print clowder repo status :param bool fetch: Fetch before printing status """ if ENVIRONMENT.clowder_repo_dir is None: return if ENVIRONMENT.clowder_yaml is not None and not ENVIRONMENT.clowder_yaml.is_symlink( ): message = f"Found a {fmt.path(ENVIRONMENT.clowder_yaml.name)} file but it is not a symlink " \ f"to a file stored in the existing {fmt.path(Path('.clowder'))} repo" LOG.error(message) LOG.error() symlink_output: Optional[str] = None if ENVIRONMENT.clowder_yaml is not None and ENVIRONMENT.clowder_yaml.is_symlink( ): target_path = fmt.path(Path(ENVIRONMENT.clowder_yaml.name)) # FIXME: This can cause an error if symlink is pointing to existing file not relative to clowder dir source_path = fmt.path( ENVIRONMENT.clowder_yaml.resolve().relative_to( ENVIRONMENT.clowder_dir)) symlink_output = f"{target_path} -> {source_path}" if ENVIRONMENT.clowder_git_repo_dir is None: CONSOLE.stdout(fmt.green(ENVIRONMENT.clowder_repo_dir.name)) if symlink_output is not None: CONSOLE.stdout(symlink_output) CONSOLE.stdout() return if fetch and not is_offline(): CONSOLE.stdout(' - Fetch upstream changes for clowder repo') self.fetch(self.remote) clowder_git_repo_output = self.format_project_string( ENVIRONMENT.clowder_git_repo_dir.name) CONSOLE.stdout(f"{clowder_git_repo_output} {self.formatted_ref}") if symlink_output is not None: CONSOLE.stdout(symlink_output) CONSOLE.stdout()
def remove_directory(path): """Remove directory at path""" try: shutil.rmtree(path) except shutil.Error: message = colored(" - Failed to remove directory ", 'red') print(message + fmt.path(path)) except (KeyboardInterrupt, SystemExit): sys.exit(1)
def print_yaml(root_directory): """Print current clowder yaml""" yaml_file = os.path.join(root_directory, 'clowder.yaml') parsed_yaml = parse_yaml(yaml_file) yaml_files = [] while True: yaml_files.append(yaml_file) if 'import' not in parsed_yaml: break imported_yaml = parsed_yaml['import'] if imported_yaml == 'default': yaml_file = os.path.join(root_directory, '.clowder', 'clowder.yaml') else: yaml_file = os.path.join(root_directory, '.clowder', 'versions', imported_yaml, 'clowder.yaml') parsed_yaml = parse_yaml(yaml_file) for yaml_file in yaml_files: if os.path.isfile(yaml_file): try: with open(yaml_file) as raw_file: contents = raw_file.read() print('-' * 80) if os.path.islink(yaml_file): path = fmt.symlink_target(yaml_file) path = fmt.remove_prefix(path, root_directory) path = fmt.remove_prefix(path, '/') print() print(fmt.path('clowder.yaml') + ' -> ' + fmt.path(path)) print() else: path = fmt.remove_prefix(yaml_file, root_directory) path = fmt.remove_prefix(path, '/') print('\n' + fmt.path(path) + '\n') print(contents) except IOError as err: fmt.open_file_error(yaml_file) print(err) sys.exit(1) except (KeyboardInterrupt, SystemExit): sys.exit(1)
def has_ambiguous_clowder_yaml_files(self) -> bool: """Check for ambiguous clowder yaml files :return: Whether abmigous clowder yaml files exist """ clowder_yml = self._get_possible_yaml_path('clowder.yml') clowder_yaml = self._get_possible_yaml_path('clowder.yaml') clowder_yml_exists = clowder_yml.is_file() or clowder_yml.is_symlink() clowder_yaml_exists = clowder_yaml.is_file( ) or clowder_yaml.is_symlink() has_ambiguous_clowder_yaml_files = clowder_yml_exists and clowder_yaml_exists if has_ambiguous_clowder_yaml_files: yml_file = fmt.path(Path('clowder.yml')) yaml_file = fmt.path(Path('clowder.yaml')) message = f"Found {yml_file} and {yaml_file} files in same directory" self.ambiguous_yaml_error = AmbiguousYamlError(message) else: self.ambiguous_yaml_error = None return has_ambiguous_clowder_yaml_files
def _repo(self): """Create Repo instance for path""" try: repo = Repo(self.repo_path) return repo except GitError as err: repo_path_output = fmt.path(self.repo_path) message = colored(" - Failed to create Repo instance for ", 'red') + repo_path_output self._print(message) self._print(fmt.error(err)) self._exit(message) except (KeyboardInterrupt, SystemExit): self._exit()
def _set_clowder_yaml(self, yaml_file: Path) -> None: """Set clowder yaml variable if file exists :param Path yaml_file: Path to clowder yaml file """ # Symlink pointing to existing source if yaml_file.is_symlink() and yaml_file.exists(): self.clowder_yaml: Optional[Path] = yaml_file return # Broken symlink pointing to missing source if yaml_file.is_symlink() and not yaml_file.exists(): target = fmt.path(yaml_file) source = fmt.path((yaml_file.resolve())) message = f"Found symlink {target} but source {source} appears to be missing" self.missing_source_error: Optional[ MissingSourceError] = MissingSourceError(message) return # Existing non-symlink file if not yaml_file.is_symlink() and yaml_file.is_file(): self.clowder_yaml: Optional[Path] = yaml_file return
def _init_repo(self): """Initialize repository""" if GitRepo.existing_git_repository(self.repo_path): return try: self._print(' - Initialize repo at ' + fmt.path(self.repo_path)) if not os.path.isdir(self.repo_path): try: os.makedirs(self.repo_path) except OSError as err: if err.errno != os.errno.EEXIST: raise self.repo = Repo.init(self.repo_path) except GitError as err: remove_directory(self.repo_path) message = colored(' - Failed to initialize repository', 'red') self._print(message) self._print(fmt.error(err)) self._exit(message) except (KeyboardInterrupt, SystemExit): remove_directory(self.repo_path) self._exit()