Esempio n. 1
0
def add_labels_based_on_size(pr: MergeRequest,
                             size_scheme: str = 'size/{size}'):
    """
    Labels the pull request with size labels according to the amount of
    code touched, commits and files involved. Helps plan the review in
    advance.
    """
    sizes = {'XXL', 'XL', 'L', 'M', 'S', 'XS'}
    with lock_igitt_object('label mr', pr):
        labels = pr.labels.difference(
            {size_scheme.format(size=size)
             for size in sizes})

        lines_added, lines_deleted = pr.diffstat
        commit_score = 4 * len(pr.commits)
        file_score = 4 * len(pr.affected_files)

        if commit_score + file_score + lines_added + lines_deleted <= 100:
            pr.labels = {size_scheme.format(size='XS')}.union(labels)

        elif commit_score + file_score + lines_added + lines_deleted <= 250:
            pr.labels = {size_scheme.format(size='S')}.union(labels)

        elif commit_score + file_score + lines_added + lines_deleted <= 500:
            pr.labels = {size_scheme.format(size='M')}.union(labels)

        elif commit_score + file_score + lines_added + lines_deleted <= 1000:
            pr.labels = {size_scheme.format(size='L')}.union(labels)

        elif commit_score + file_score + lines_added + lines_deleted <= 1500:
            pr.labels = {size_scheme.format(size='XL')}.union(labels)

        else:
            pr.labels = {size_scheme.format(size='XXL')}.union(labels)
Esempio n. 2
0
def add_stale_label_to_issues(
        repo: Repository,
        issue_expire_limit: int = 'Expiry limit in no. of days for issues',
        stale_label: str = 'Label to be used for marking stale',
        unassign: bool = 'Unassign assignees if an issue goes stale',
):
    """
    Assigns the chosen label to issues which haven't been updated in a certain
    period of time.
    """
    minimum_issue_update_time = (datetime.now() -
                                 timedelta(days=issue_expire_limit)).date()
    for issue in repo.search_issues(
            updated_before=minimum_issue_update_time,
            state=IssueStates.OPEN,
    ):
        with lock_igitt_object('label issue', issue):
            if stale_label not in issue.labels:
                issue.labels = issue.labels | {stale_label}
            if unassign and issue.assignees:
                users = ', '.join(f'@{a.username}' for a in issue.assignees)
                issue.assignees = set()
                issue.add_comment(
                    'This issue seems stale!\n\n' +
                    users + ' please reassign yourself if you\'re still '
                    'working on this.\n\n'
                    '(Powered by [GitMate.io](https://gitmate.io))')
Esempio n. 3
0
def label_hotspots(
    pr: MergeRequest,
    pattern: str = 'Pattern for matching against',
    hotspot_label: str = 'Label to be added if hotspot found',
):
    if len(get_hotspot_files(pattern, pr).intersection(pr.affected_files)):
        with lock_igitt_object('label mr', pr):
            pr.labels |= {hotspot_label}
Esempio n. 4
0
def sync_pr_with_updated_issue(issue: Issue,
                               sync_assignees: bool='Synchronize Assignees'):

    if not sync_assignees:  # pragma: no cover
        return

    for pr_object in MergeRequestModel.find_mrs_with_issue(issue):
        pr = pr_object.igitt_pr
        with lock_igitt_object('assign mr', pr):
            pr.assignees |= issue.assignees
        pr_object.closes_issues.update({str(issue.number): True})
        pr_object.save()
Esempio n. 5
0
def remove_stale_label_from_issues(
        entity: (Issue, MergeRequest),
        *args,
        stale_label: str = 'Label to be used for marking stale issues'
):
    """
    Unassigns the chosen label from issues when they are updated again or if
    they are mentioned from other pull requests.
    """
    if len(args) > 0 and args[0] == stale_label:
        # LABELED and UNLABELED events return the label used, skip action if
        # the label was ``stale_label``
        return

    if isinstance(entity, MergeRequest):
        issues = entity.mentioned_issues
        for issue in issues:
            with lock_igitt_object('label issue', issue):
                issue.labels = issue.labels - {stale_label}
    else:
        with lock_igitt_object('label issue', entity):
            entity.labels = entity.labels - {stale_label}
Esempio n. 6
0
def sync_updated_pr_with_issue(pr: MergeRequest,
                               sync_assignees: bool='Synchronize Assignees'):
    issues = pr.closes_issues
    repo = Repository.from_igitt_repo(pr.repository)
    pr_obj = MergeRequestModel.objects.get_or_create(
        repo=repo, number=pr.number)[0]
    data = defaultdict(dict)

    with lock_igitt_object('label mr', pr):
        labels = pr.labels
        for issue in issues:
            labels = issue.labels | labels
        pr.labels = labels

    if sync_assignees:
        with lock_igitt_object('assign mr', pr):
            assignees = pr.assignees
            for issue in issues:
                assignees |= issue.assignees
                data[str(issue.number)]['assignees'] = True
            pr.assignees = assignees

    pr_obj.closes_issues = data
    pr_obj.save()
Esempio n. 7
0
def add_assignees_to_issue(
    issue: Issue,
    keywords: dict() = 'Keywords that trigger assignments',
):
    issue_summary = issue.title.lower() + ' ' + issue.description.lower()
    new_assignees = {
        assignee
        for assignee, l_keywords in keywords.items()
        for keyword in l_keywords.split(',')
        if keyword.strip() and keyword in issue_summary
    }

    with lock_igitt_object('assign issue', issue, refresh_needed=False):
        for assignee in new_assignees:
            issue.assign(assignee)
Esempio n. 8
0
def remove_stale_label_from_merge_requests(
        pr: MergeRequest,
        *args,
        stale_label: str = 'Label to be used for marking stale'
):
    """
    Unassigns the chosen label from pull requests when they are updated again.
    """
    if len(args) > 0 and args[0] == stale_label:
        # LABELED and UNLABELED events return the label used, skip action if
        # the label was ``stale_label``
        return

    with lock_igitt_object('label mr', pr):
        pr.labels = pr.labels - {stale_label}
Esempio n. 9
0
def add_stale_label_to_merge_requests(
        repo: Repository,
        pr_expire_limit: int = 'Expiry limit in no. of day for pull requests',
        stale_label: str = 'Label to be used for marking stale'
):
    """
    Assigns the chosen label to pull requests which haven't been updated in a
    certain period of time.
    """
    minimum_pr_update_time = (datetime.now() -
                              timedelta(days=pr_expire_limit)).date()
    for pr in repo.search_mrs(
            updated_before=minimum_pr_update_time,
            state=MergeRequestStates.OPEN,
    ):
        with lock_igitt_object('label mr', pr):
            if stale_label not in pr.labels:
                pr.labels = pr.labels | {stale_label}
Esempio n. 10
0
def add_approved_label(
        commit: Commit,
        approved_label: str = 'status/ci-approved',
        status_labels: str = 'status/pending_review, status/WIP'):
    """
    Labels the PR as approved when the head commit passes all tests.
    """
    status_labels = [
        label.strip() for label in status_labels.split(',') if label.strip()
    ]

    for db_pr in MergeRequestModel.objects.filter(head_sha=commit.sha):
        pr = db_pr.igitt_pr
        with lock_igitt_object('label mr', pr):
            labels = pr.labels
            if commit.combined_status is Status.SUCCESS:
                pr.labels = {approved_label} | labels - set(status_labels)
            else:
                pr.labels = labels - {approved_label}
Esempio n. 11
0
def mark_pending_review_or_wip_accordingly(
        pr: MergeRequest,
        wip_label: str = 'Work in progress',
        pending_review_label: str = 'Review pending'):
    """
    Labels the pull request as pending review and removes work in
    progress on every changed PR accordingly. But retains work in progress
    label, if title of the pull request begins with "wip".
    """
    with lock_igitt_object('label mr', pr):
        labels = pr.labels
        # Allows [wip] and WIP:
        if not 'wip' in pr.title.lower()[:4]:
            labels.add(pending_review_label)
            labels.discard(wip_label)
        else:
            labels.add(wip_label)
            labels.discard(pending_review_label)

        pr.labels = labels
Esempio n. 12
0
def add_labels_to_issue(
    issue: Issue,
    keywords: dict() = 'Keywords that trigger respective labels',
    label_texts_as_keywords: bool = 'Apply mentioned labels automatically',
):
    issue_summary = issue.title.lower() + ' ' + issue.description.lower()
    new_labels = {
        label
        for label, l_keywords in keywords.items()
        for keyword in l_keywords.split(',')
        if keyword.strip() and keyword in issue_summary
    }

    if label_texts_as_keywords:
        new_labels |= {
            label
            for label in issue.available_labels
            if label.lower() in issue_summary
        }

    with lock_igitt_object('label issue', issue):
        issue.labels = new_labels.union(issue.labels)
Esempio n. 13
0
def sync_label_remove_from_issue_with_pr(issue: Issue, label: str):
    for pr_object in MergeRequestModel.find_mrs_with_issue(issue):
        pr = pr_object.igitt_pr
        with lock_igitt_object('label mr', pr):
            pr.labels -= {label}