Example #1
0
def check_reviews_repobee_4(allocations_file: pathlib.Path, title_regex: str,
                            api: plug.PlatformAPI) -> None:
    """Preview version of the `reviews check` command for RepoBee 4."""
    data = json.loads(allocations_file.read_text(sys.getdefaultencoding()))
    review_allocations = data["allocations"]
    num_reviews = int(data["num_reviews"])

    expected_reviewers = {
        allocation["reviewed_repo"]["url"]:
        allocation["review_team"]["members"]
        for allocation in review_allocations
    }

    reviewed_repos = progresswrappers.get_repos(expected_reviewers.keys(), api)
    reviews = collections.defaultdict(list)

    for reviewed_repo in reviewed_repos:
        review_issue_authors = {
            issue.author
            for issue in api.get_repo_issues(reviewed_repo)
            if re.match(title_regex, issue.title)
        }
        for expected_reviewer in expected_reviewers[reviewed_repo.url]:
            reviews[expected_reviewer].append(
                plug.Review(
                    repo=reviewed_repo.name,
                    done=expected_reviewer in review_issue_authors,
                ))

    plug.echo(
        formatters.format_peer_review_progress_output(
            reviews,
            list(itertools.chain.from_iterable(expected_reviewers.values())),
            num_reviews,
        ))
Example #2
0
def close_issue(
    title_regex: str, repos: Iterable[plug.StudentRepo], api: plug.PlatformAPI
) -> None:
    """Close issues whose titles match the title_regex in student repos.

    Args:
        title_regex: A regex to match against issue titles.
        assignment_names: Names of assignments.
        teams: Team objects specifying student groups.
        api: An implementation of :py:class:`repobee_plug.PlatformAPI` used to
            interface with the platform (e.g. GitHub or GitLab) instance.
    """
    repo_urls = (repo.url for repo in repos)
    platform_repos = progresswrappers.get_repos(repo_urls, api)
    for repo in platform_repos:
        to_close = [
            issue
            for issue in api.get_repo_issues(repo)
            if re.match(title_regex, issue.title)
            and issue.state == plug.IssueState.OPEN
        ]
        for issue in to_close:
            api.close_issue(issue)
            msg = f"Closed {repo.name}/#{issue.number}='{issue.title}'"
            platform_repos.write(msg)  # type: ignore
            plug.log.info(msg)
Example #3
0
def check_peer_review_progress(
    assignment_names: Iterable[str],
    teams: Iterable[plug.Team],
    title_regex: str,
    num_reviews: int,
    api: plug.PlatformAPI,
) -> None:
    """Check which teams have opened peer review issues in their allotted
    review repos

    Args:
        assignment_names: Names of assignments.
        teams: An iterable of student teams.
        title_regex: A regex to match against issue titles.
        num_reviews: Amount of reviews each student is expected to have made.
        api: An implementation of :py:class:`repobee_plug.PlatformAPI` used to
            interface with the platform (e.g. GitHub or GitLab) instance.

    """
    teams = list(teams)
    reviews = collections.defaultdict(list)

    review_team_names = [
        plug.generate_review_team_name(team, assignment_name) for team in teams
        for assignment_name in assignment_names
    ]

    review_teams = progresswrappers.get_teams(review_team_names,
                                              api,
                                              desc="Processing review teams")
    for review_team in review_teams:
        repos = list(api.get_team_repos(review_team))
        if len(repos) != 1:
            plug.log.warning(
                f"Expected {review_team.name} to have 1 associated "
                f"repo, found {len(repos)}. "
                f"Skipping...")
            continue

        reviewed_repo = repos[0]
        expected_reviewers = set(review_team.members)
        reviewing_teams = _extract_reviewing_teams(teams, expected_reviewers)

        review_issue_authors = {
            issue.author
            for issue in api.get_repo_issues(reviewed_repo)
            if re.match(title_regex, issue.title)
        }

        for team in reviewing_teams:
            reviews[str(team)].append(
                plug.Review(
                    repo=reviewed_repo.name,
                    done=any(
                        map(review_issue_authors.__contains__, team.members)),
                ))

    plug.echo(
        formatters.format_peer_review_progress_output(
            reviews, [team.name for team in teams], num_reviews))
Example #4
0
def _get_issue_generator(
    repos: Iterable[plug.Repo],
    title_regex: str,
    author: Optional[str],
    state: plug.IssueState,
    api: plug.PlatformAPI,
) -> Iterable[Tuple[str, Iterable[plug.Issue]]]:
    issues_per_repo = (
        (
            repo.name,
            [
                issue
                for issue in api.get_repo_issues(repo)
                if re.match(title_regex, issue.title)
                and (state == plug.IssueState.ALL or state == issue.state)
                and (not author or issue.author == author)
            ],
        )
        for repo in repos
    )
    return issues_per_repo
Example #5
0
def _get_issue_generator(
    repos: Iterable[plug.StudentRepo],
    title_regex: str,
    author: Optional[str],
    state: plug.IssueState,
    double_blind_key: Optional[str],
    api: plug.PlatformAPI,
) -> Iterable[Tuple[plug.StudentRepo, Iterable[plug.Issue]]]:
    for repo in repos:
        if double_blind_key:
            team_name = _hash_if_key(repo.team.name, double_blind_key)
            repo_name = _hash_if_key(repo.name, double_blind_key)
            platform_repo = api.get_repo(repo_name, team_name)
        else:
            platform_repo = api.get_repo(repo.name, repo.team.name)

        yield repo, [
            issue for issue in api.get_repo_issues(platform_repo)
            if re.match(title_regex, issue.title) and (
                state == plug.IssueState.ALL or state == issue.state) and (
                    not author or issue.author == author)
        ]