def print_existence_message(self): """Print existence validation message for projects in group""" if self.existing_projects(): return print(fmt.group_name(self.name)) for project in self.projects: if not existing_git_repository(project.full_path()): print(project.status()) existing_git_repository(project.full_path())
def run(self, commands, ignore_errors, parallel=False): """Run commands or script in project directory .. py:function:: run(commands, ignore_errors, parallel=False) :param list[str] commands: Commands to run :param bool ignore_errors: Whether to exit if command returns a non-zero exit code :param Optional[bool] parallel: Whether commands are being run in parallel, affects output """ if not parallel and not existing_git_repository(self.full_path()): print(colored(" - Project is missing\n", 'red')) return self._print_output = not parallel forall_env = { 'CLOWDER_PATH': ROOT_DIR, 'PROJECT_PATH': self.full_path(), 'PROJECT_NAME': self.name, 'PROJECT_REMOTE': self.remote, 'PROJECT_REF': self.ref } if self.fork: forall_env['FORK_REMOTE'] = self.fork.remote_name for cmd in commands: self._run_forall_command(cmd, forall_env, ignore_errors, parallel)
def configure_remotes(self, upstream_remote_name, upstream_remote_url, fork_remote_name, fork_remote_url): """Configure remotes names for fork and upstream :param str upstream_remote_name: Upstream remote name :param str upstream_remote_url: Upstream remote url :param str fork_remote_name: Fork remote name :param str fork_remote_url: Fork remote url """ if not existing_git_repository(self.repo_path): return try: remotes = self.repo.remotes except GitError: return except (KeyboardInterrupt, SystemExit): self._exit() else: for remote in remotes: if upstream_remote_url == self._remote_get_url(remote.name) and remote.name != upstream_remote_name: self._rename_remote(remote.name, upstream_remote_name) continue if fork_remote_url == self._remote_get_url(remote.name) and remote.name != fork_remote_name: self._rename_remote(remote.name, fork_remote_name) self._compare_remotes(upstream_remote_name, upstream_remote_url, fork_remote_name, fork_remote_url)
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) if not existing_git_repository(self.repo_path): self._init_repo() self._create_remote(self.remote, url, remove_dir=True) try: self._checkout_new_repo_tag(tag, self.remote, depth) except ClowderGitError: fetch = depth != 0 self.herd(url, depth=depth, fetch=fetch, rebase=rebase) return try: self.fetch(self.remote, ref='refs/tags/' + tag, depth=depth) self._checkout_tag(tag) except ClowderGitError: fetch = depth != 0 self.herd(url, depth=depth, fetch=fetch, rebase=rebase)
def _init_repo(self): """Initialize repository :raise OSError: """ if existing_git_repository(self.repo_path): return try: self._print(' - Initialize repo at ' + fmt.get_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()
def existing_projects(self): """Validate existence status of all projects :return: True, if all projects exist :rtype: bool """ return all([ existing_git_repository(project.full_path()) for project in self.projects ])
def validate_repo(self): """Validate repo state :return: True, if repo not dirty or doesn't exist on disk :rtype: bool """ if not existing_git_repository(self.repo_path): return True return not self.is_dirty()
def status(self): """Return formatted fork status :return: Formatted fork status :rtype: str """ if not existing_git_repository(self.path): return colored(self.path, 'green') repo = ProjectRepo(self.full_path(), self.remote_name, 'refs/heads/master') project_output = format_project_string(repo, self.path) current_ref_output = format_project_ref_string(repo) return project_output + ' ' + current_ref_output
def __init__(self, repo_path, remote, default_ref, parallel=False): """GitRepo __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 """ self.repo_path = repo_path self.default_ref = default_ref self.remote = remote self.parallel = parallel self.repo = self._repo() if existing_git_repository(repo_path) else None self._print_output = not parallel
def create_clowder_repo(self, url, branch, depth=0): """Clone clowder git repo from url at path .. py:function:: create_clowder_repo(url, branch, depth=0) :param str url: URL of repo :param str branch: Branch name :param Optional[int] depth: Git clone depth. 0 indicates full clone, otherwise must be a positive integer """ if existing_git_repository(self.repo_path): return self._init_repo() self._create_remote(self.remote, url, remove_dir=True) self._checkout_new_repo_branch(branch, depth)
def herd_branch(self, url, branch, **kwargs): """Herd branch .. py:function:: herd_branch(url, branch, depth=0, fork_remote=None, rebase=False) :param str url: URL of repo :param str branch: Branch name Keyword Args: depth (int): Git clone depth. 0 indicates full clone, otherwise must be a positive integer fork_remote (str): Fork remote name rebase (bool): Whether to use rebase instead of pulling latest changes """ depth = kwargs.get('depth', 0) rebase = kwargs.get('rebase', False) fork_remote = kwargs.get('fork_remote', None) if not existing_git_repository(self.repo_path): self._herd_branch_initial(url, branch, depth=depth) return branch_output = fmt.ref_string(branch) branch_ref = 'refs/heads/' + branch if self.existing_local_branch(branch): self._herd_branch_existing_local(branch, depth=depth, rebase=rebase, fork_remote=fork_remote) return self.fetch(self.remote, depth=depth, ref=branch_ref, allow_failure=True) if self.existing_remote_branch(branch, self.remote): self._herd(self.remote, branch_ref, depth=depth, fetch=False, rebase=rebase) return remote_output = fmt.remote_string(self.remote) self._print(' - No existing remote branch ' + remote_output + ' ' + branch_output) if fork_remote: self.fetch(fork_remote, depth=depth, ref=branch_ref) if self.existing_remote_branch(branch, fork_remote): self._herd(fork_remote, branch_ref, depth=depth, fetch=False, rebase=rebase) return remote_output = fmt.remote_string(fork_remote) self._print(' - No existing remote branch ' + remote_output + ' ' + branch_output) fetch = depth != 0 self.herd(url, depth=depth, fetch=fetch, rebase=rebase)
def status(self, padding=None): """Return formatted status for project :param Optional[int] padding: Amount of padding to use for printing project on left and current ref on right :return: Formatting project name and status :rtype: str """ if not existing_git_repository(self.full_path()): return colored(self.name, 'green') repo = ProjectRepo(self.full_path(), self.remote, self.ref) project_output = format_project_string(repo, self.path) current_ref_output = format_project_ref_string(repo) if padding: project_output = project_output.ljust(padding) return project_output + ' ' + current_ref_output
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) if not existing_git_repository(self.repo_path): self._herd_initial(url, depth=depth) return self._create_remote(self.remote, url) self._herd(self.remote, self.default_ref, depth=depth, fetch=fetch, rebase=rebase)