Exemple #1
0
def herd(args) -> None:
    """Clowder herd command private implementation"""

    branch = None if args.branch is None else args.branch[0]
    tag = None if args.tag is None else args.tag[0]
    depth = None if args.depth is None else args.depth[0]
    protocol = None if args.protocol is None else GitProtocol(args.protocol[0])
    jobs = None if args.jobs is None else args.jobs[0]
    rebase = args.rebase

    config = Config()

    rebase_config = config.rebase
    rebase = rebase_config if rebase_config is not None else rebase

    protocol_config = config.protocol
    protocol = protocol_config if protocol_config is not None else protocol
    SOURCE_CONTROLLER.protocol_override = protocol

    jobs_config = config.jobs
    jobs = jobs_config if jobs_config is not None else jobs

    projects = config.process_projects_arg(args.projects)
    projects = CLOWDER_CONTROLLER.filter_projects(CLOWDER_CONTROLLER.projects,
                                                  projects)

    if jobs is not None and jobs != 1 and os.name == "posix":
        if jobs <= 0:
            jobs = 4
        parallel.herd(projects, jobs, branch, tag, depth, rebase)
        return

    CLOWDER_CONTROLLER.validate_project_statuses(projects)
    for project in projects:
        project.herd(branch=branch, tag=tag, depth=depth, rebase=rebase)
Exemple #2
0
def herd(projects: Tuple[ResolvedProject, ...],
         jobs: int,
         branch: Optional[str] = None,
         tag: Optional[str] = None,
         depth: Optional[int] = None,
         rebase: bool = False) -> None:
    """Clone projects or update latest from upstream in parallel

    :param Tuple[ResolvedProject, ...] projects: Projects to herd
    :param int jobs: Number of jobs to use running parallel commands
    :param Optional[str] branch: Branch to attempt to herd
    :param Optional[str] tag: Tag to attempt to herd
    :param Optional[int] depth: Git clone depth. 0 indicates full clone, otherwise must be a positive integer
    :param bool rebase: Whether to use rebase instead of pulling latest changes
    """

    CONSOLE.stdout(' - Herd projects in parallel\n')
    CLOWDER_CONTROLLER.validate_print_output(projects)

    run_func = partial(run_parallel,
                       jobs,
                       projects,
                       'herd',
                       branch=branch,
                       tag=tag,
                       depth=depth,
                       rebase=rebase)
    trio.run(run_func)
Exemple #3
0
def _reset_impl(project_names: List[str], timestamp_project: Optional[str] = None, jobs: Optional[int] = None) -> None:
    """Reset project branches to upstream or checkout tag/sha as detached HEAD

    :param List[str] project_names: Project names to reset
    :param Optional[str] timestamp_project: Reference project to checkout other project commit timestamps relative to
    :param Optional[int] jobs: Number of jobs to use running commands in parallel
    """

    config = Config()

    jobs_config = config.jobs
    jobs = jobs_config if jobs_config is not None else jobs

    projects = config.process_projects_arg(project_names)
    projects = CLOWDER_CONTROLLER.filter_projects(CLOWDER_CONTROLLER.projects, projects)

    if jobs is not None and jobs != 1 and os.name == "posix":
        if jobs <= 0:
            jobs = 4
        parallel.reset(projects, jobs, timestamp_project)
        return

    timestamp = None
    if timestamp_project:
        timestamp = CLOWDER_CONTROLLER.get_timestamp(timestamp_project)

    CLOWDER_CONTROLLER.validate_project_statuses(projects)
    for project in projects:
        project.reset(timestamp=timestamp)
Exemple #4
0
def yaml(args) -> None:
    """Clowder yaml command private implementation"""

    if args.resolved:
        CLOWDER_CONTROLLER.validate_project_statuses(
            CLOWDER_CONTROLLER.projects, allow_missing_repo=False)
        output = yaml_string(
            CLOWDER_CONTROLLER.get_yaml(resolved=True)).rstrip()
        CONSOLE.stdout(output)
    else:
        output = yaml_string(CLOWDER_CONTROLLER.get_yaml()).rstrip()
        CONSOLE.stdout(output)
Exemple #5
0
class SyncController(ArgparseController):
    """Clowder sync command controller"""
    class Meta:
        """Clowder sync Meta configuration"""

        label = 'sync'
        stacked_on = 'base'
        stacked_type = 'embedded'
        description = 'Sync fork with upstream remote'

    @expose(help='Sync fork with upstream remote',
            arguments=[
                (['--projects', '-p'],
                 dict(choices=CLOWDER_CONTROLLER.get_all_fork_project_names(),
                      nargs='+',
                      metavar='PROJECT',
                      help=options_help_message(
                          CLOWDER_CONTROLLER.get_all_fork_project_names(),
                          'projects to sync'))),
                (['--protocol'],
                 dict(choices=['https', 'ssh'],
                      nargs=1,
                      default=None,
                      metavar='PROTOCOL',
                      help='Protocol to clone new repos with')),
                (['--rebase', '-r'],
                 dict(action='store_true', help='use rebase instead of pull')),
                (['--parallel'],
                 dict(action='store_true', help='run commands in parallel'))
            ])
    def sync(self):
        """Clowder sync command entry point"""

        self._sync()

    @network_connection_required
    @valid_clowder_yaml_required
    @print_clowder_repo_status_fetch
    def _sync(self):
        """Clowder sync command private implementation"""

        protocol = None if self.app.pargs.protocol is None else self.app.pargs.protocol[
            0]

        all_fork_projects = CLOWDER_CONTROLLER.get_all_fork_project_names()
        if all_fork_projects == '':
            cprint(' - No forks to sync\n', 'red')
            return
        sync(CLOWDER_CONTROLLER,
             all_fork_projects,
             protocol=protocol,
             rebase=self.app.pargs.rebase,
             parallel=self.app.pargs.parallel)
Exemple #6
0
    def get_yaml(self, resolved: bool = False) -> Union[dict, str]:
        """Return python object representation for saving yaml

        :param bool resolved: Whether to get resolved commit hashes
        :return: YAML python object
        :raise UnknownTypeError:
        """

        from clowder.clowder_controller import CLOWDER_CONTROLLER

        if self._is_string:
            if not resolved:
                return self.name

            return {
                "name":
                self.name,
                "commit":
                CLOWDER_CONTROLLER.get_project_sha(self.resolved_project_id)
            }

        yaml = {"name": self.name}

        if self.path is not None:
            yaml['path'] = str(self.path)
        if resolved:
            yaml['commit'] = CLOWDER_CONTROLLER.get_project_sha(
                self.resolved_project_id)
        else:
            if self.branch is not None:
                yaml['branch'] = self.branch
            if self.tag is not None:
                yaml['tag'] = self.tag
            if self.commit is not None:
                yaml['commit'] = self.commit
        if self.groups is not None:
            yaml['groups'] = self.groups
        if self.remote is not None:
            yaml['remote'] = self.remote
        if self.source is not None:
            if isinstance(self.source, SourceName):
                yaml['source'] = self.source
            elif isinstance(self.source, Source):
                yaml['source'] = self.source.get_yaml()
            else:
                raise UnknownTypeError('Unknown source type')
        if self.git_settings is not None:
            yaml['git'] = self.git_settings.get_yaml()
        if self.upstream is not None:
            yaml['upstream'] = self.upstream.get_yaml()

        return yaml
Exemple #7
0
def _start_branches(args, tracking: bool) -> None:
    """clowder start branches command

    :param bool tracking: Whether to create tracking branches
    """

    projects = Config().process_projects_arg(args.projects)
    projects = CLOWDER_CONTROLLER.filter_projects(CLOWDER_CONTROLLER.projects,
                                                  projects)

    CLOWDER_CONTROLLER.validate_project_statuses(projects)
    for project in projects:
        CONSOLE.stdout(project.status())
        project.start(args.branch[0], tracking)
Exemple #8
0
def _forall_impl(command: str,
                 ignore_errors: bool,
                 projects: List[str],
                 jobs: Optional[int] = None) -> None:
    """Runs script in project directories specified

    :param str command: Command or script and optional arguments
    :param bool ignore_errors: Whether to exit if command returns a non-zero exit code
    :param List[str] projects: Project names to clean
    :param Optional[int] jobs: Number of jobs to use running parallel commands
    """

    projects = Config().process_projects_arg(projects)
    projects = CLOWDER_CONTROLLER.filter_projects(CLOWDER_CONTROLLER.projects,
                                                  projects)

    jobs_config = Config().jobs
    jobs = jobs_config if jobs_config is not None else jobs

    if jobs is not None and jobs != 1 and os.name == "posix":
        if jobs <= 0:
            jobs = 4
        parallel.forall(projects, jobs, command, ignore_errors)
        return

    for project in projects:
        CONSOLE.stdout(project.status())
        project.run(command, ignore_errors=ignore_errors)
Exemple #9
0
def _prune_impl(project_names: List[str], branch: str, force: bool = False,
                local: bool = False, remote: bool = False) -> None:
    """Prune branches

    :param List[str] project_names: Project names to prune
    :param str branch: Branch to prune
    :param bool force: Force delete branch
    :param bool local: Delete local branch
    :param bool remote: Delete remote branch
    """

    projects = Config().process_projects_arg(project_names)
    projects = CLOWDER_CONTROLLER.filter_projects(CLOWDER_CONTROLLER.projects, projects)

    CLOWDER_CONTROLLER.validate_project_statuses(projects)
    _prune_projects(projects, branch, force=force, local=local, remote=remote)
Exemple #10
0
    def _save(self):
        """Clowder save command private implementation

        :raise ClowderExit:
        """

        if self.app.pargs.version.lower() == 'default':
            print(fmt.save_default_error(self.app.pargs.version))
            raise ClowderExit(1)

        CLOWDER_REPO.print_status()
        validate_projects_exist(CLOWDER_CONTROLLER)
        validate_groups(CLOWDER_CONTROLLER.groups)

        version_name = self.app.pargs.version.replace(
            '/', '-')  # Replace path separators with dashes
        version_dir = os.path.join(ROOT_DIR, '.clowder', 'versions',
                                   version_name)
        _make_dir(version_dir)

        yaml_file = os.path.join(version_dir, 'clowder.yaml')
        if os.path.exists(yaml_file):
            print(
                fmt.save_version_exists_error(version_name, yaml_file) + '\n')
            raise ClowderExit(1)

        print(fmt.save_version(version_name, yaml_file))
        save_yaml(CLOWDER_CONTROLLER.get_yaml(), yaml_file)
Exemple #11
0
    def _yaml(self):
        """Clowder yaml command private implementation"""

        if self.app.pargs.resolved:
            print(fmt.yaml_string(CLOWDER_CONTROLLER.get_yaml(resolved=True)))
        else:
            print_yaml()
Exemple #12
0
def status(args) -> None:
    """Clowder status command private implementation"""

    projects = Config().process_projects_arg(args.projects)
    projects = CLOWDER_CONTROLLER.filter_projects(CLOWDER_CONTROLLER.projects,
                                                  projects)

    if args.fetch:
        _fetch_projects(projects)
    else:
        if ENVIRONMENT.clowder_repo_dir is not None:
            ClowderRepo(ENVIRONMENT.clowder_repo_dir).print_status()

    projects_output = CLOWDER_CONTROLLER.get_projects_output(projects)
    padding = len(max(projects_output, key=len))

    for project in projects:
        CONSOLE.stdout(project.status(padding=padding))
Exemple #13
0
def checkout(args) -> None:
    """Clowder checkout command private implementation"""

    projects = Config().process_projects_arg(args.projects)
    projects = CLOWDER_CONTROLLER.filter_projects(CLOWDER_CONTROLLER.projects,
                                                  projects)

    for project in projects:
        CONSOLE.stdout(project.status())
        project.checkout(args.branch[0])
Exemple #14
0
def stash(args) -> None:
    """Clowder stash command private implementation"""

    if not any([p.is_dirty for p in CLOWDER_CONTROLLER.projects]):
        CONSOLE.stdout(' - No changes to stash')
        return

    projects = Config().process_projects_arg(args.projects)
    projects = CLOWDER_CONTROLLER.filter_projects(CLOWDER_CONTROLLER.projects,
                                                  projects)

    for project in projects:
        CONSOLE.stdout(project.status())
        project.stash()
Exemple #15
0
def reset(projects: Tuple[ResolvedProject, ...],
          jobs: int,
          timestamp_project: Optional[str] = None) -> None:
    """Reset project branches to upstream or checkout tag/sha as detached HEAD in parallel

    :param Tuple[ResolvedProject, ...] projects: Project names to reset
    :param int jobs: Number of jobs to use running parallel commands
    :param Optional[str] timestamp_project: Reference project to checkout other project timestamps relative to
    """

    CONSOLE.stdout(' - Reset projects in parallel\n')
    CLOWDER_CONTROLLER.validate_print_output(projects)

    timestamp = None
    if timestamp_project:
        timestamp = CLOWDER_CONTROLLER.get_timestamp(timestamp_project)

    reset_func = partial(run_parallel,
                         jobs,
                         projects,
                         'reset',
                         timestamp=timestamp)
    trio.run(reset_func)
Exemple #16
0
def _prune_projects(projects: Tuple[ResolvedProject, ...], branch: str, force: bool = False, local: bool = False,
                    remote: bool = False) -> None:
    """Prune project branches

    :param Tuple[Project, ...] projects: Projects to prune
    :param str branch: Branch to prune
    :param bool force: Force delete branch
    :param bool local: Delete local branch
    :param bool remote: Delete remote branch
    :raise CommandArgumentError:
    """

    local_branch_exists = CLOWDER_CONTROLLER.project_has_branch(projects, branch, is_remote=False)
    remote_branch_exists = CLOWDER_CONTROLLER.project_has_branch(projects, branch, is_remote=True)

    if local and remote:
        branch_exists = local_branch_exists or remote_branch_exists
        if not branch_exists:
            CONSOLE.stdout(' - No local or remote branches to prune')
            return
        CONSOLE.stdout(' - Prune local and remote branches\n')
    elif remote:
        if not remote_branch_exists:
            CONSOLE.stdout(' - No remote branches to prune')
            return
        CONSOLE.stdout(' - Prune remote branches\n')
    elif local:
        if not local_branch_exists:
            CONSOLE.stdout(' - No local branches to prune')
            return
        CONSOLE.stdout(' - Prune local branches\n')
    else:
        raise CommandArgumentError('local and remote are both false, but at least one should be true')

    for project in projects:
        CONSOLE.stdout(project.status())
        project.prune(branch, force=force, local=local, remote=remote)
Exemple #17
0
    def _sync(self):
        """Clowder sync command private implementation"""

        protocol = None if self.app.pargs.protocol is None else self.app.pargs.protocol[
            0]

        all_fork_projects = CLOWDER_CONTROLLER.get_all_fork_project_names()
        if all_fork_projects == '':
            cprint(' - No forks to sync\n', 'red')
            return
        sync(CLOWDER_CONTROLLER,
             all_fork_projects,
             protocol=protocol,
             rebase=self.app.pargs.rebase,
             parallel=self.app.pargs.parallel)
Exemple #18
0
class DiffController(ArgparseController):
    """Clowder diff command controller"""

    class Meta:
        """Clowder diff Meta configuration"""

        label = 'diff'
        stacked_on = 'base'
        stacked_type = 'embedded'
        description = 'Show git diff for projects'

    @expose(
        help='Show git diff for projects',
        arguments=[
            (['--groups', '-g'], dict(choices=CLOWDER_CONTROLLER.get_all_group_names(),
                                      default=CLOWDER_CONTROLLER.get_all_group_names(),
                                      nargs='+', metavar='GROUP',
                                      help=options_help_message(CLOWDER_CONTROLLER.get_all_group_names(),
                                                                'groups to show diff for'))),
            (['--projects', '-p'], dict(choices=CLOWDER_CONTROLLER.get_all_project_names(),
                                        nargs='+', metavar='PROJECT',
                                        help=options_help_message(CLOWDER_CONTROLLER.get_all_project_names(),
                                                                  'projects to show diff for'))),
            (['--skip', '-s'], dict(choices=CLOWDER_CONTROLLER.get_all_project_names(),
                                    nargs='+', metavar='PROJECT', default=[],
                                    help=options_help_message(CLOWDER_CONTROLLER.get_all_project_names(),
                                                              'projects to skip')))
        ]
    )
    def diff(self):
        """Clowder diff command entry point"""

        self._diff()

    @valid_clowder_yaml_required
    @print_clowder_repo_status
    def _diff(self):
        """Clowder diff command private implementation"""

        if self.app.pargs.projects is None:
            groups = filter_groups(CLOWDER_CONTROLLER.groups, self.app.pargs.groups)
            for group in groups:
                run_group_command(group, self.app.pargs.skip, 'diff')
            return

        projects = filter_projects(CLOWDER_CONTROLLER.groups, project_names=self.app.pargs.projects)
        for project in projects:
            run_project_command(project, self.app.pargs.skip, 'diff')
Exemple #19
0
def branch(args) -> None:
    """Clowder branch command private implementation"""

    if args.remote:
        local = False
        remote = True
    elif args.all:
        local = True
        remote = True
    else:
        local = True
        remote = False

    projects = Config().process_projects_arg(args.projects)
    projects = CLOWDER_CONTROLLER.filter_projects(CLOWDER_CONTROLLER.projects,
                                                  projects)

    for project in projects:
        CONSOLE.stdout(project.status())
        project.branch(local=local, remote=remote)
Exemple #20
0
class StartController(ArgparseController):
    """Clowder start command controller"""

    class Meta:
        """Clowder start Meta configuration"""

        label = 'start'
        stacked_on = 'base'
        stacked_type = 'embedded'
        description = 'Start a new branch'

    @expose(
        help='Start a new branch',
        arguments=[
            (['branch'], dict(help='name of branch to create', metavar='BRANCH')),
            (['--tracking', '-t'], dict(action='store_true', help='create remote tracking branch')),
            (['--groups', '-g'], dict(choices=CLOWDER_CONTROLLER.get_all_group_names(),
                                      default=CLOWDER_CONTROLLER.get_all_group_names(),
                                      nargs='+', metavar='GROUP',
                                      help=options_help_message(CLOWDER_CONTROLLER.get_all_group_names(),
                                                                'groups to start'))),
            (['--projects', '-p'], dict(choices=CLOWDER_CONTROLLER.get_all_project_names(),
                                        nargs='+', metavar='PROJECT',
                                        help=options_help_message(CLOWDER_CONTROLLER.get_all_project_names(),
                                                                  'projects to start'))),
            (['--skip', '-s'], dict(choices=CLOWDER_CONTROLLER.get_all_project_names(),
                                    nargs='+', metavar='PROJECT', default=[],
                                    help=options_help_message(CLOWDER_CONTROLLER.get_all_project_names(),
                                                              'projects to skip')))
        ]
    )
    def start(self):
        """Clowder start command entry point"""

        self._start()

    @valid_clowder_yaml_required
    @print_clowder_repo_status
    def _start(self):
        """Clowder start command private implementation"""

        if self.app.pargs.tracking:
            self._start_tracking()
            return

        self._start_branches(False)

    @network_connection_required
    def _start_tracking(self):
        """clowder start tracking command"""

        self._start_branches(True)

    def _start_branches(self, tracking):
        """clowder start branches command"""

        if self.app.pargs.projects is None:
            groups = filter_groups(CLOWDER_CONTROLLER.groups, self.app.pargs.groups)
            validate_groups(groups)
            for group in groups:
                run_group_command(group, self.app.pargs.skip, 'start', self.app.pargs.branch, tracking)
            return

        projects = filter_projects(CLOWDER_CONTROLLER.groups, project_names=self.app.pargs.projects)
        validate_projects(projects)
        for project in projects:
            run_project_command(project, self.app.pargs.skip, 'start', self.app.pargs.branch, tracking)
Exemple #21
0
class CheckoutController(ArgparseController):
    """Clowder checkout command controller"""
    class Meta:
        """Clowder checkout Meta configuration"""

        label = 'checkout'
        stacked_on = 'base'
        stacked_type = 'embedded'
        description = 'Checkout local branch in projects'

    @expose(help='Checkout local branch in projects',
            arguments=[
                (['branch'],
                 dict(nargs=1,
                      action='store',
                      help='branch to checkout',
                      metavar='BRANCH')),
                (['--groups', '-g'],
                 dict(choices=CLOWDER_CONTROLLER.get_all_group_names(),
                      default=CLOWDER_CONTROLLER.get_all_group_names(),
                      nargs='+',
                      metavar='GROUP',
                      help=options_help_message(
                          CLOWDER_CONTROLLER.get_all_group_names(),
                          'groups to checkout branches for'))),
                (['--projects', '-p'],
                 dict(choices=CLOWDER_CONTROLLER.get_all_project_names(),
                      nargs='+',
                      metavar='PROJECT',
                      help=options_help_message(
                          CLOWDER_CONTROLLER.get_all_project_names(),
                          'projects to checkout branches for'))),
                (['--skip', '-s'],
                 dict(choices=CLOWDER_CONTROLLER.get_all_project_names(),
                      nargs='+',
                      metavar='PROJECT',
                      default=[],
                      help=options_help_message(
                          CLOWDER_CONTROLLER.get_all_project_names(),
                          'projects to skip')))
            ])
    def checkout(self):
        """Clowder checkout command entry point"""

        self._checkout()

    @valid_clowder_yaml_required
    @print_clowder_repo_status
    def _checkout(self):
        """Clowder checkout command private implementation"""

        if self.app.pargs.projects is None:
            groups = filter_groups(CLOWDER_CONTROLLER.groups,
                                   self.app.pargs.groups)
            for group in groups:
                run_group_command(group, self.app.pargs.skip, 'checkout',
                                  self.app.pargs.branch[0])
            return

        projects = filter_projects(CLOWDER_CONTROLLER.groups,
                                   project_names=self.app.pargs.projects)
        for project in projects:
            run_project_command(project, self.app.pargs.skip, 'checkout',
                                self.app.pargs.branch[0])
Exemple #22
0
class CleanController(ArgparseController):
    """Clowder clean command controller"""

    class Meta:
        """Clowder clean Meta configuration"""

        label = 'clean'
        stacked_on = 'base'
        stacked_type = 'embedded'
        description = 'Discard current changes in projects'

    @expose(
        help='Discard current changes in projects',
        arguments=[
            (['--all', '-a'], dict(action='store_true', help='clean all the things')),
            (['--recursive', '-r'], dict(action='store_true', help='clean submodules recursively')),
            (['-d'], dict(action='store_true', help='remove untracked directories')),
            (['-f'], dict(action='store_true', help='remove directories with .git subdirectory or file')),
            (['-X'], dict(action='store_true', help='remove only files ignored by git')),
            (['-x'], dict(action='store_true', help='remove all untracked files')),
            (['--groups', '-g'], dict(choices=CLOWDER_CONTROLLER.get_all_group_names(),
                                      default=CLOWDER_CONTROLLER.get_all_group_names(),
                                      nargs='+', metavar='GROUP',
                                      help=options_help_message(CLOWDER_CONTROLLER.get_all_group_names(),
                                                                'groups to clean'))),
            (['--projects', '-p'], dict(choices=CLOWDER_CONTROLLER.get_all_project_names(),
                                        nargs='+', metavar='PROJECT',
                                        help=options_help_message(CLOWDER_CONTROLLER.get_all_project_names(),
                                                                  'projects to clean'))),
            (['--skip', '-s'], dict(choices=CLOWDER_CONTROLLER.get_all_project_names(),
                                    nargs='+', metavar='PROJECT', default=[],
                                    help=options_help_message(CLOWDER_CONTROLLER.get_all_project_names(),
                                                              'projects to skip')))
            ]
    )
    def clean(self):
        """Clowder clean command entry point"""

        self._clean()

    @valid_clowder_yaml_required
    @print_clowder_repo_status
    def _clean(self):
        """Clowder clean command private implementation"""

        if self.app.pargs.all:
            _clean_all(CLOWDER_CONTROLLER, group_names=self.app.pargs.groups,
                       project_names=self.app.pargs.projects, skip=self.app.pargs.skip)
            return

        clean_args = ''
        if self.app.pargs.d:
            clean_args += 'd'
        if self.app.pargs.f:
            clean_args += 'f'
        if self.app.pargs.X:
            clean_args += 'X'
        if self.app.pargs.x:
            clean_args += 'x'
        _clean(CLOWDER_CONTROLLER, group_names=self.app.pargs.groups, project_names=self.app.pargs.projects,
               skip=self.app.pargs.skip, args=clean_args, recursive=self.app.pargs.recursive)
Exemple #23
0
class HerdController(ArgparseController):
    """Clowder herd command controller"""
    class Meta:
        """Clowder herd Meta configuration"""

        label = 'herd'
        stacked_on = 'base'
        stacked_type = 'embedded'
        description = 'Clone and update projects with latest changes'

    @expose(help='Clone and update projects with latest changes',
            arguments=[
                (['--parallel'],
                 dict(action='store_true', help='run commands in parallel')),
                (['--protocol'],
                 dict(choices=['https', 'ssh'],
                      nargs=1,
                      default=None,
                      metavar='PROTOCOL',
                      help='Protocol to clone new repos with')),
                (['--rebase', '-r'],
                 dict(action='store_true', help='use rebase instead of pull')),
                (['--depth', '-d'],
                 dict(default=None,
                      type=int,
                      nargs=1,
                      metavar='DEPTH',
                      help='depth to herd')),
                (['--branch', '-b'],
                 dict(nargs=1,
                      default=None,
                      metavar='BRANCH',
                      help='branch to herd if present')),
                (['--tag', '-t'],
                 dict(nargs=1,
                      default=None,
                      metavar='TAG',
                      help='tag to herd if present')),
                (['--groups', '-g'],
                 dict(choices=CLOWDER_CONTROLLER.get_all_group_names(),
                      default=CLOWDER_CONTROLLER.get_all_group_names(),
                      nargs='+',
                      metavar='GROUP',
                      help=options_help_message(
                          CLOWDER_CONTROLLER.get_all_group_names(),
                          'groups to herd'))),
                (['--projects', '-p'],
                 dict(choices=CLOWDER_CONTROLLER.get_all_project_names(),
                      nargs='+',
                      metavar='PROJECT',
                      help=options_help_message(
                          CLOWDER_CONTROLLER.get_all_project_names(),
                          'projects to herd'))),
                (['--skip', '-s'],
                 dict(choices=CLOWDER_CONTROLLER.get_all_project_names(),
                      nargs='+',
                      metavar='PROJECT',
                      default=[],
                      help=options_help_message(
                          CLOWDER_CONTROLLER.get_all_project_names(),
                          'projects to skip')))
            ])
    def herd(self):
        """Clowder herd command entry point"""

        self._herd()

    @network_connection_required
    @valid_clowder_yaml_required
    @print_clowder_repo_status_fetch
    def _herd(self):
        """Clowder herd command private implementation"""

        branch = None if self.app.pargs.branch is None else self.app.pargs.branch[
            0]
        tag = None if self.app.pargs.tag is None else self.app.pargs.tag[0]
        depth = None if self.app.pargs.depth is None else self.app.pargs.depth[
            0]
        protocol = None if self.app.pargs.protocol is None else self.app.pargs.protocol[
            0]

        kwargs = {
            'group_names': self.app.pargs.groups,
            'project_names': self.app.pargs.projects,
            'skip': self.app.pargs.skip,
            'branch': branch,
            'tag': tag,
            'depth': depth,
            'rebase': self.app.pargs.rebase,
            'protocol': protocol
        }

        if self.app.pargs.parallel:
            herd_parallel(CLOWDER_CONTROLLER, **kwargs)
            if os.name == "posix":
                return

        herd(CLOWDER_CONTROLLER, **kwargs)
Exemple #24
0
class ResetController(ArgparseController):
    """Clowder reset command controller"""
    class Meta:
        """Clowder reset Meta configuration"""

        label = 'reset'
        stacked_on = 'base'
        stacked_type = 'embedded'
        description = 'Reset branches to upstream commits or check out detached HEADs for tags and shas'

    @expose(
        help=
        'Reset branches to upstream commits or check out detached HEADs for tags and shas',
        arguments=[(['--parallel'],
                    dict(action='store_true',
                         help='run commands in parallel')),
                   (['--timestamp', '-t'],
                    dict(choices=CLOWDER_CONTROLLER.get_all_project_names(),
                         default=None,
                         nargs=1,
                         metavar='TIMESTAMP',
                         help='project to reset timestamps relative to')),
                   (['--groups', '-g'],
                    dict(choices=CLOWDER_CONTROLLER.get_all_group_names(),
                         default=CLOWDER_CONTROLLER.get_all_group_names(),
                         nargs='+',
                         metavar='GROUP',
                         help=options_help_message(
                             CLOWDER_CONTROLLER.get_all_group_names(),
                             'groups to reset'))),
                   (['--projects', '-p'],
                    dict(choices=CLOWDER_CONTROLLER.get_all_project_names(),
                         nargs='+',
                         metavar='PROJECT',
                         help=options_help_message(
                             CLOWDER_CONTROLLER.get_all_project_names(),
                             'projects to reset'))),
                   (['--skip', '-s'],
                    dict(choices=CLOWDER_CONTROLLER.get_all_project_names(),
                         nargs='+',
                         metavar='PROJECT',
                         default=[],
                         help=options_help_message(
                             CLOWDER_CONTROLLER.get_all_project_names(),
                             'projects to skip')))])
    def reset(self):
        """Clowder reset command entry point"""

        self._reset()

    @network_connection_required
    @valid_clowder_yaml_required
    @print_clowder_repo_status_fetch
    def _reset(self):
        """Clowder reset command private implementation"""

        timestamp_project = None
        if self.app.pargs.timestamp:
            timestamp_project = self.app.pargs.timestamp[0]
        reset(CLOWDER_CONTROLLER,
              group_names=self.app.pargs.groups,
              project_names=self.app.pargs.projects,
              skip=self.app.pargs.skip,
              timestamp_project=timestamp_project,
              parallel=self.app.pargs.parallel)
Exemple #25
0
class BranchController(ArgparseController):
    """Clowder branch command controller"""
    class Meta:
        """Clowder branch Meta configuration"""

        label = 'branch'
        stacked_on = 'base'
        stacked_type = 'embedded'
        description = 'Display current branches'

    @expose(help='Display current branches',
            arguments=[
                (['--all', '-a'],
                 dict(action='store_true',
                      help='show local and remote branches')),
                (['--remote',
                  '-r'], dict(action='store_true',
                              help='show remote branches')),
                (['--groups', '-g'],
                 dict(choices=CLOWDER_CONTROLLER.get_all_group_names(),
                      default=CLOWDER_CONTROLLER.get_all_group_names(),
                      nargs='+',
                      metavar='GROUP',
                      help=options_help_message(
                          CLOWDER_CONTROLLER.get_all_group_names(),
                          'groups to show branches for'))),
                (['--projects', '-p'],
                 dict(choices=CLOWDER_CONTROLLER.get_all_project_names(),
                      nargs='+',
                      metavar='PROJECT',
                      help=options_help_message(
                          CLOWDER_CONTROLLER.get_all_project_names(),
                          'projects to show branches for'))),
                (['--skip', '-s'],
                 dict(choices=CLOWDER_CONTROLLER.get_all_project_names(),
                      nargs='+',
                      metavar='PROJECT',
                      default=[],
                      help=options_help_message(
                          CLOWDER_CONTROLLER.get_all_project_names(),
                          'projects to skip')))
            ])
    def branch(self):
        """Clowder branch command entry point"""
        self._branch()

    @valid_clowder_yaml_required
    @print_clowder_repo_status
    def _branch(self):
        """Clowder branch command private implementation"""
        local = True
        remote = False
        if self.app.pargs.all:
            local = True
            remote = True
        elif self.app.pargs.remote:
            remote = True

        if self.app.pargs.projects is None:
            groups = filter_groups(CLOWDER_CONTROLLER.groups,
                                   self.app.pargs.groups)
            for group in groups:
                run_group_command(group,
                                  self.app.pargs.skip,
                                  'branch',
                                  local=local,
                                  remote=remote)
            return

        projects = filter_projects(CLOWDER_CONTROLLER.groups,
                                   project_names=self.app.pargs.projects)
        for project in projects:
            run_project_command(project,
                                self.app.pargs.skip,
                                'branch',
                                local=local,
                                remote=remote)
Exemple #26
0
class ForallController(ArgparseController):
    """Clowder forall command controller"""
    class Meta:
        """Clowder forall Meta configuration"""

        label = 'forall'
        stacked_on = 'base'
        stacked_type = 'embedded'
        description = 'Run command or script in project directories'

    @expose(help='Run command or script in project directories',
            arguments=[
                (['--command', '-c'],
                 dict(nargs='+',
                      metavar='COMMAND',
                      default=None,
                      help='command or script to run in project directories')),
                (['--ignore-errors', '-i'],
                 dict(action='store_true',
                      help='ignore errors in command or script')),
                (['--parallel'],
                 dict(action='store_true', help='run commands in parallel')),
                (['--groups', '-g'],
                 dict(choices=CLOWDER_CONTROLLER.get_all_group_names(),
                      default=CLOWDER_CONTROLLER.get_all_group_names(),
                      nargs='+',
                      metavar='GROUP',
                      help=options_help_message(
                          CLOWDER_CONTROLLER.get_all_group_names(),
                          'groups to run command for'))),
                (['--projects', '-p'],
                 dict(choices=CLOWDER_CONTROLLER.get_all_project_names(),
                      nargs='+',
                      metavar='PROJECT',
                      help=options_help_message(
                          CLOWDER_CONTROLLER.get_all_project_names(),
                          'projects to run command for'))),
                (['--skip', '-s'],
                 dict(choices=CLOWDER_CONTROLLER.get_all_project_names(),
                      nargs='+',
                      metavar='PROJECT',
                      default=[],
                      help=options_help_message(
                          CLOWDER_CONTROLLER.get_all_project_names(),
                          'projects to skip')))
            ])
    def forall(self):
        """Clowder forall command entry point"""

        self._forall()

    @valid_clowder_yaml_required
    @print_clowder_repo_status
    def _forall(self):
        """Clowder forall command private implementation"""

        forall(CLOWDER_CONTROLLER,
               self.app.pargs.command,
               self.app.pargs.ignore_errors,
               group_names=self.app.pargs.groups,
               project_names=self.app.pargs.projects,
               skip=self.app.pargs.skip,
               parallel=self.app.pargs.parallel)
Exemple #27
0
class PruneController(ArgparseController):
    """Clowder prune command controller"""
    class Meta:
        """Clowder prune Meta configuration"""

        label = 'prune'
        stacked_on = 'base'
        stacked_type = 'embedded'
        description = 'Prune branches'

    @expose(help='Prune branches',
            arguments=[
                (['branch'],
                 dict(help='name of branch to remove', metavar='BRANCH')),
                (['--force',
                  '-f'], dict(action='store_true',
                              help='force prune branches')),
                (['--all', '-a'],
                 dict(action='store_true',
                      help='prune local and remote branches')),
                (['--remote',
                  '-r'], dict(action='store_true',
                              help='prune remote branches')),
                (['--groups', '-g'],
                 dict(choices=CLOWDER_CONTROLLER.get_all_group_names(),
                      default=CLOWDER_CONTROLLER.get_all_group_names(),
                      nargs='+',
                      metavar='GROUP',
                      help=options_help_message(
                          CLOWDER_CONTROLLER.get_all_group_names(),
                          'groups to prune'))),
                (['--projects', '-p'],
                 dict(choices=CLOWDER_CONTROLLER.get_all_project_names(),
                      nargs='+',
                      metavar='PROJECT',
                      help=options_help_message(
                          CLOWDER_CONTROLLER.get_all_project_names(),
                          'projects to prune'))),
                (['--skip', '-s'],
                 dict(choices=CLOWDER_CONTROLLER.get_all_project_names(),
                      nargs='+',
                      metavar='PROJECT',
                      default=[],
                      help=options_help_message(
                          CLOWDER_CONTROLLER.get_all_project_names(),
                          'projects to skip')))
            ])
    def prune(self):
        """Clowder prune command entry point"""

        self._prune()

    @valid_clowder_yaml_required
    @print_clowder_repo_status
    def _prune(self):
        """Clowder prune command private implementation"""

        if self.app.pargs.all:
            self._prune_all()
            return

        if self.app.pargs.remote:
            self._prune_remote()
            return

        _prune(CLOWDER_CONTROLLER,
               self.app.pargs.groups,
               self.app.pargs.branch,
               project_names=self.app.pargs.projects,
               skip=self.app.pargs.skip,
               force=self.app.pargs.force,
               local=True)

    @network_connection_required
    def _prune_all(self):
        """clowder prune all command"""

        _prune(CLOWDER_CONTROLLER,
               self.app.pargs.groups,
               self.app.pargs.branch,
               project_names=self.app.pargs.projects,
               skip=self.app.pargs.skip,
               force=self.app.pargs.force,
               local=True,
               remote=True)

    @network_connection_required
    def _prune_remote(self):
        """clowder prune remote command"""

        _prune(CLOWDER_CONTROLLER,
               self.app.pargs.groups,
               self.app.pargs.branch,
               project_names=self.app.pargs.projects,
               skip=self.app.pargs.skip,
               remote=True)