def get_yaml(self, resolved=False): """Return python object representation for saving yaml .. py:function:: get_yaml(resolved=False) :param Optional[bool] resolved: Return default ref rather than current commit sha :return: YAML python object :rtype: dict """ if resolved: ref = self.ref else: repo = ProjectRepo(self.full_path(), self.remote, self.ref) ref = repo.sha() project = { 'name': self.name, 'path': self.path, 'depth': self.depth, 'recursive': self.recursive, 'ref': ref, 'remote': self.remote, 'source': self.source.name } if self.fork: fork_yaml = self.fork.get_yaml() project['fork'] = fork_yaml if self._timestamp_author: project['timestamp_author'] = self._timestamp_author return project
def _prune_remote(self, branch): """Prune remote branch""" remote = self._remote if self.fork is None else self.fork.remote_name repo = ProjectRepo(self.full_path(), remote, self._ref) if repo.existing_remote_branch(branch, remote): repo.prune_branch_remote(branch, remote)
def get_yaml(self, resolved=False): """Return python object representation for saving yaml""" if resolved: ref = self._ref else: repo = ProjectRepo(self.full_path(), self._remote, self._ref) ref = repo.sha() project = { 'name': self.name, 'path': self.path, 'depth': self._depth, 'recursive': self._recursive, 'ref': ref, 'remote': self._remote, 'source': self._source.name } if self.fork: fork_yaml = self.fork.get_yaml() project['fork'] = fork_yaml if self._timestamp_author: project['timestamp_author'] = self._timestamp_author return project
def _validate_groups(self): """Validate status of clowder repo""" clowder = ProjectRepo(self.clowder_path, self.remote, self.default_ref) if not clowder.validate_repo(): ProjectRepo.validation(self.clowder_path) print() sys.exit(1)
def init(self, url, branch): """Clone clowder repo from url""" # Register exit handler to remove files if cloning repo fails atexit.register(self.init_exit_handler) repo = ProjectRepo(self.clowder_path, self.remote, self.default_ref) repo.create_clowder_repo(url, branch) self.link()
def diff(self): """Show git diff for project""" if not os.path.isdir(self.full_path()): print(colored(" - Project is missing\n", 'red')) return repo = ProjectRepo(self.full_path(), self._remote, self._ref) repo.status_verbose()
def existing_branch(self, branch, is_remote): """Check if branch exists""" repo = ProjectRepo(self.full_path(), self._remote, self._ref) if not is_remote: return repo.existing_local_branch(branch) rem = self._remote if self.fork is None else self.fork.remote_name return repo.existing_remote_branch(branch, rem)
def status(self): """Return formatted fork status""" if not ProjectRepo.existing_git_repository(self.path): return colored(self.path, 'green') project_output = ProjectRepo.format_project_string(self.path, self.path) current_ref_output = ProjectRepo.format_project_ref_string(self.full_path()) return project_output + ' ' + current_ref_output
def get_current_timestamp(self): """Return timestamp of current HEAD commit :return: HEAD commit timestamp :rtype: str """ repo = ProjectRepo(self.full_path(), self.remote, self.ref) return repo.get_current_timestamp()
def clean(self): """Discard changes in clowder repo""" repo = ProjectRepo(self.clowder_path, self.remote, self.default_ref) if self.is_dirty(): print(' - Discard current changes') repo.clean(args='fdx') return print(' - No changes to discard')
def __init__(self, repo_path, remote, default_ref, parallel=False): """ProjectRepoRecursive __init__ :param str repo_path: Absolute path to repo :param str remote: Default remote name :param str default_ref: Default ref :param Optional[bool] parallel: Whether command is being run in parallel, affects output. Defaults to False """ ProjectRepo.__init__(self, repo_path, remote, default_ref, parallel=parallel)
def start(self, branch, tracking): """Start a new feature branch :param str branch: Local branch name to create :param bool tracking: Whether to create a remote branch with tracking relationship """ remote = self.remote if self.fork is None else self.fork.remote_name depth = self.depth if self.fork is None else 0 repo = ProjectRepo(self.full_path(), self.remote, self.ref) repo.start(remote, branch, depth, tracking)
def sync(self, fork_remote, rebase=False): """Sync fork with upstream remote .. py:function:: sync(fork_remote, rebase=False) :param str fork_remote: Fork remote name :param Optional[bool] rebase: Whether to use rebase instead of pulling latest changes """ ProjectRepo.sync(self, fork_remote, rebase=rebase) self.submodule_update_recursive()
def __init__(self, repo_path, remote, default_ref, parallel=False, print_output=True): ProjectRepo.__init__(self, repo_path, remote, default_ref, parallel=parallel, print_output=print_output)
def start(self, branch, tracking): """Start a new feature branch""" if not ProjectRepo.existing_git_repository(self.full_path()): print(colored(" - Directory doesn't exist", 'red')) return remote = self._remote if self.fork is None else self.fork.remote_name depth = self._depth if self.fork is None else 0 repo = ProjectRepo(self.full_path(), self._remote, self._ref) repo.start(remote, branch, depth, tracking)
def clean(self, args=None): """Discard changes for repo and submodules""" ProjectRepo.clean(self, args=args) self._print(' - Clean submodules recursively') self._submodules_clean() self._print(' - Reset submodules recursively') self._submodules_reset() self._print(' - Update submodules recursively') self._submodules_update()
def existing_branch(self, branch, is_remote): """Check if branch exists :param str branch: Branch to check for :param bool is_remote: Check for remote branch :return: True, if branch exists :rtype: bool """ repo = ProjectRepo(self.full_path(), self.remote, self.ref) if not is_remote: return repo.existing_local_branch(branch) remote = self.remote if self.fork is None else self.fork.remote_name return repo.existing_remote_branch(branch, remote)
def herd_branch(self, url, branch, depth=0, rebase=False, fork_remote=None): """Herd branch""" ProjectRepo.herd_branch(self, url, branch, depth=depth, rebase=rebase, fork_remote=fork_remote) self.submodule_update_recursive(depth)
def status(self, padding=None): """Return formatted status for project""" if not ProjectRepo.existing_git_repository(self.full_path()): print(colored(self.name, 'green')) return project_output = ProjectRepo.format_project_string( self.full_path(), self.path) current_ref_output = ProjectRepo.format_project_ref_string( self.full_path()) if padding: project_output = project_output.ljust(padding) return project_output + ' ' + current_ref_output
def diff(self): """Show git diff for project Equivalent to: ``git status -vv`` """ ProjectRepo(self.full_path(), self.remote, self.ref).status_verbose()
def print_validation(self): """Print validation message for project""" if not self.is_valid(): print(self.status()) repo = ProjectRepo(self.full_path(), self.remote, self.ref) print_validation(repo)
def branch(self, local=False, remote=False): """Print branches for project""" if not os.path.isdir(self.full_path()): print(colored(" - Project is missing\n", 'red')) return repo = ProjectRepo(self.full_path(), self._remote, self._ref) if not is_offline(): if remote: if self.fork is None: repo.fetch(self._remote, depth=self._depth) else: repo.fetch(self.fork.remote_name) repo.fetch(self._remote) repo.print_branches(local=local, remote=remote)
def validate_repo(self): """Validate repo state""" if not ProjectRepo.validate_repo(self): return False return not any( [self.is_dirty_submodule(s.path) for s in self.repo.submodules])
def fetch_all(self): """Fetch upstream changes if project exists on disk""" repo = ProjectRepo(self.full_path(), self.remote, self.ref) if self.fork is None: repo.fetch(self.remote, depth=self.depth) return repo.fetch(self.fork.remote_name) repo.fetch(self.remote)
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 herd_tag(self, url, tag, **kwargs): """Herd tag .. py:function:: herd_tag(url, tag, depth=0, rebase=False) :param str url: URL of repo :param str tag: Tag name Keyword Args: depth (int): Git clone depth. 0 indicates full clone, otherwise must be a positive integer rebase (bool): Whether to use rebase instead of pulling latest changes """ depth = kwargs.get('depth', 0) rebase = kwargs.get('rebase', False) ProjectRepo.herd_tag(self, url, tag, depth=depth, rebase=rebase) self.submodule_update_recursive(depth)
def formatted_project_path(self): """Return formatted project path :return: Formatted string of full file path :rtype: str """ repo = ProjectRepo(self.full_path(), self.remote, self.ref) return format_project_string(repo, self.path)
def branch(self, local=False, remote=False): """Print branches for project .. py:function:: branch(local=False, remote=False) :param Optional[bool] local: Print local branches :param Optional[bool] remote: Print remote branches """ repo = ProjectRepo(self.full_path(), self.remote, self.ref) if not is_offline() and remote: if self.fork is None: repo.fetch(self.remote, depth=self.depth) else: repo.fetch(self.fork.remote_name) repo.fetch(self.remote) repo.print_branches(local=local, remote=remote)
def is_valid(self): """Validate status of project :return: True, if not dirty or if the project doesn't exist on disk :rtype: bool """ return ProjectRepo(self.full_path(), self.remote, self.ref).validate_repo()
def herd(self, url, **kwargs): """Herd ref .. py:function:: herd(url, depth=0, fetch=True, rebase=False) :param str url: URL of repo Keyword Args: depth (int): Git clone depth. 0 indicates full clone, otherwise must be a positive integer fetch (bool): Whether to fetch rebase (bool): Whether to use rebase instead of pulling latest changes """ depth = kwargs.get('depth', 0) fetch = kwargs.get('fetch', True) rebase = kwargs.get('rebase', False) ProjectRepo.herd(self, url, depth=depth, fetch=fetch, rebase=rebase) self.submodule_update_recursive(depth)