Beispiel #1
0
    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())
Beispiel #2
0
    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)
Beispiel #3
0
    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)
Beispiel #4
0
    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)
Beispiel #5
0
    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()
Beispiel #6
0
    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
        ])
Beispiel #7
0
    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()
Beispiel #8
0
    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
Beispiel #9
0
    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
Beispiel #10
0
    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)
Beispiel #11
0
    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)
Beispiel #12
0
    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
Beispiel #13
0
    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)