Beispiel #1
0
def _create_update_push_tuples(
    teams: Iterable[plug.StudentTeam],
    template_repos: Iterable[plug.TemplateRepo],
    api: plug.PlatformAPI,
) -> Iterable[PushSpec]:
    """Create push tuples for existing repos. Repos that don't exist are
    ignored.

    Args:
        teams: An iterable of teams.
        template_repos: Template repositories.
        api: A platform API instance.
    Returns:
        A list of PushSpec namedtuples for all student repo urls that relate to
        any of the master repo urls.
    """
    urls_to_templates = {}
    for team, template_repo in itertools.product(teams, template_repos):
        repo_url, *_ = api.get_repo_urls(
            [template_repo.name], team_names=[team.name]
        )
        urls_to_templates[repo_url] = template_repo

    for repo in api.get_repos(list(urls_to_templates.keys())):
        template = urls_to_templates[repo.url]
        branch = git.active_branch(template.path)
        yield PushSpec(template.path, api.insert_auth(repo.url), branch)
Beispiel #2
0
def _delete_anonymous_repos(
    assignment_names: Iterable[str],
    student_teams: Iterable[plug.StudentTeam],
    double_blind_key: str,
    api: plug.PlatformAPI,
):
    """Delete any anonymous repos created for these students and
    assignments.
    """
    anon_repo_names = [
        _hash_if_key(
            plug.generate_repo_name(student_team, assignment_name),
            key=double_blind_key,
        ) for student_team, assignment_name in itertools.product(
            student_teams, assignment_names)
    ]
    anon_repo_urls = api.get_repo_urls(anon_repo_names)
    anon_repos = api.get_repos(anon_repo_urls)
    anon_repos_progress = plug.cli.io.progress_bar(
        anon_repos,
        desc="Deleting anonymous repo copies",
        total=len(anon_repo_names),
    )
    for repo in anon_repos_progress:
        api.delete_repo(repo)
    progresswrappers.end_progress(anon_repos_progress)
Beispiel #3
0
    def post_setup(self, repo: plug.StudentRepo, api: plug.PlatformAPI):
        """Add a created student repo to the teachers team."""
        platform_repo = next(iter(api.get_repos([repo.url])))
        teachers_team = _get_or_create_team(TEACHERS_TEAM_NAME, api)

        api.assign_repo(
            team=teachers_team,
            repo=platform_repo,
            permission=plug.TeamPermission.PULL,
        )
        return plug.Result(
            name="tamanager",
            status=plug.Status.SUCCESS,
            msg=f"Added to the {TEACHERS_TEAM_NAME} team",
        )
Beispiel #4
0
    def command(self, api: plug.PlatformAPI) -> Optional[plug.Result]:
        teachers_team = _get_or_create_team(TEACHERS_TEAM_NAME, api)
        existing_members = teachers_team.members
        new_members = list(set(self.teachers) - set(existing_members))

        api.assign_members(teachers_team,
                           new_members,
                           permission=plug.TeamPermission.PULL)

        for repo in plug.cli.io.progress_bar(
                api.get_repos(), desc="Granting read access to repos"):
            api.assign_repo(
                repo=repo,
                team=teachers_team,
                permission=plug.TeamPermission.PULL,
            )

        msg = (f"Added {', '.join(new_members)} to the '{TEACHERS_TEAM_NAME}' "
               "team")
        return plug.Result(name="add-teachers",
                           status=plug.Status.SUCCESS,
                           msg=msg)
Beispiel #5
0
def get_repos(
    repo_urls: Iterable[str],
    api: plug.PlatformAPI,
    desc: str = "Fetching repos",
    **kwargs: Any,
) -> Iterable[plug.Repo]:
    """Wrapper around :py:meth:`repobee_plug.PlatformAPI.get_repos` that also
    provides an auto-updating progress bar to the CLI.

    Args:
        repo_urls: An iterable of repo URLs.
        api: An instance of the platform API.
        desc: A description of the action.
        kwargs: Keyword arguments to the underlying implementation of the
            progress bar.
    Returns:
        An iterable of repos with an auto-updating CLI progress bar.
    """
    repo_urls = list(repo_urls)
    return plug.cli.io.progress_bar(api.get_repos(repo_urls),
                                    desc=desc,
                                    total=len(repo_urls),
                                    **kwargs)
Beispiel #6
0
def list_issues(
    repos: Iterable[plug.StudentRepo],
    api: plug.PlatformAPI,
    state: plug.IssueState = plug.IssueState.OPEN,
    title_regex: str = "",
    show_body: bool = False,
    author: Optional[str] = None,
) -> Mapping[str, List[plug.Result]]:
    """List all issues in the specified repos.

    Args:
        repos: The repos from which to fetch issues.
        api: An implementation of :py:class:`repobee_plug.PlatformAPI` used to
            interface with the platform (e.g. GitHub or GitLab) instance.
        state: state of the repo (open or closed). Defaults to open.
        title_regex: If specified, only issues with titles matching the regex
            are displayed. Defaults to the empty string (which matches
            everything).
        show_body: If True, the body of the issue is displayed along with the
            default info.
        author: Only show issues by this author.
    """
    # TODO optimize by not getting all repos at once
    repos = list(repos)
    repo_names = [repo.name for repo in repos]
    max_repo_name_length = max(map(len, repo_names))

    platform_repos = api.get_repos([repo.url for repo in repos])
    issues_per_repo = _get_issue_generator(
        platform_repos,
        title_regex=title_regex,
        author=author,
        state=state,
        api=api,
    )

    # _log_repo_issues exhausts the issues_per_repo iterator and
    # returns a list with the same information. It's important to
    # have issues_per_repo as an iterator as it greatly speeds
    # up visual feedback to the user when fetching many issues
    pers_issues_per_repo = _log_repo_issues(
        issues_per_repo, show_body, max_repo_name_length + 6
    )

    # for writing to JSON
    hook_result_mapping = {
        repo_name: [
            plug.Result(
                name="list-issues",
                status=plug.Status.SUCCESS,
                msg="Fetched {} issues from {}".format(len(issues), repo_name),
                data={issue.number: issue.to_dict() for issue in issues},
            )
        ]
        for repo_name, issues in pers_issues_per_repo
    }
    # meta hook result
    hook_result_mapping["list-issues"] = [
        plug.Result(
            name="meta",
            status=plug.Status.SUCCESS,
            msg="Meta info about the list-issues hook results",
            data={"state": state.value},
        )
    ]
    return hook_result_mapping