예제 #1
0
def get_duration_data(durations, owner_repo="edx/edx-platform", since=None):
    """
    Update `durations`, a dict of dict of lists of pull requests.

    `durations` has four lists of data, where each list contains pull requests:
      internal open pull requests (all)
      external open pull requests (all)
      internal closed pull requests (since the `since` value)
      external closed pull requests (since the `since` value)

    These lists are organized into a dictionary that categorizes the lists
    by position and state.
    """
    open_issues_generator = itertools.izip(
        get_pulls(owner_repo, state="open", org=True),
        itertools.repeat("open"))
    closed_issues_generator = itertools.izip(
        get_pulls(owner_repo, state="closed", since=since, org=True),
        itertools.repeat("closed"))

    for issue, state in itertools.chain(open_issues_generator,
                                        closed_issues_generator):
        created_at = issue.created_at
        if state == "open":
            closed_at = datetime.utcnow()
        else:
            closed_at = issue.closed_at
        issue.duration = closed_at - created_at

        if DEBUG:
            print("{pr.id}: {pr.intext} {state}".format(pr=issue, state=state),
                  file=sys.stderr)

        durations[state][issue.intext].append(issue)
예제 #2
0
def get_bucket_data(buckets, repo_name, date_bucket_fn, start, by_size=False, lines=False, closed=False):
    print(repo_name)
    pull_details = "all" if (by_size or lines) else "list"
    for pull in get_pulls(repo_name, state="all", pull_details=pull_details, org=True):
        # print("{0.id}: {0.combinedstate} {0.intext}".format(pull))

        ignore_ref = "(^release$|^rc/)"
        if re.search(ignore_ref, pull.base_ref) or pull.title == "Update translations (autogenerated message)":
            #print("Ignoring pull #{0.number}: {0.title}".format(pull))
            continue

        if by_size:
            size = " " + size_of_pull(pull)
        else:
            size = ""
        intext = pull.intext

        if lines:
            increment = lines_in_pull(pull)
        else:
            increment = 1

        created = make_timezone_aware(pull.created_at)
        if created >= start:
            buckets[date_bucket_fn(created)]["opened " + intext + size] += increment

        if pull.combinedstate == "merged":
            merged = make_timezone_aware(pull.merged_at)
            if merged >= start:
                buckets[date_bucket_fn(merged)]["merged " + intext + size] += increment
        elif closed and pull.combinedstate == "closed":
            closed = make_timezone_aware(pull.closed_at)
            buckets[date_bucket_fn(closed)]["closed " + intext + size] += increment
예제 #3
0
파일: pull_age.py 프로젝트: edx/repo-tools
def get_duration_data(durations, owner_repo="edx/edx-platform", since=None):
    """
    Update `durations`, a dict of dict of lists of pull requests.

    `durations` has four lists of data, where each list contains pull requests:
      internal open pull requests (all)
      external open pull requests (all)
      internal closed pull requests (since the `since` value)
      external closed pull requests (since the `since` value)

    These lists are organized into a dictionary that categorizes the lists
    by position and state.
    """
    open_issues_generator = itertools.izip(
        get_pulls(owner_repo, state="open", org=True),
        itertools.repeat("open")
    )
    closed_issues_generator = itertools.izip(
        get_pulls(owner_repo, state="closed", since=since, org=True),
        itertools.repeat("closed")
    )

    for issue, state in itertools.chain(open_issues_generator, closed_issues_generator):
        created_at = issue.created_at
        if state == "open":
            closed_at = datetime.utcnow()
        else:
            closed_at = issue.closed_at
        issue.duration = closed_at - created_at

        if DEBUG:
            print("{pr.id}: {pr.intext} {state}".format(
                pr=issue, state=state
            ), file=sys.stderr)

        durations[state][issue.intext].append(issue)
예제 #4
0
def get_bucket_data(buckets,
                    repo_name,
                    date_bucket_fn,
                    start,
                    lines=False,
                    internal=False):
    print(repo_name)
    pull_details = "all" if lines else "list"
    for pull in get_pulls(repo_name,
                          state="all",
                          pull_details=pull_details,
                          org=True):
        # print("{0.id}: {0.combinedstate} {0.intext}".format(pull))

        intext = pull.intext  # internal or external
        # if internal is True, only want to look at "internal" PRs, and if
        # internal is False, only want to look at "external" PRs.
        if (internal and intext != 'internal') or (not internal
                                                   and intext != 'external'):
            continue

        ignore_ref = "(^release$|^rc/)"
        if re.search(
                ignore_ref, pull.base_ref
        ) or pull.title == "Update translations (autogenerated message)":
            # print("Ignoring pull #{0.number}: {0.title}".format(pull))
            continue

        if lines:
            increment = lines_in_pull(pull)
        else:
            increment = 1

        created = make_timezone_aware(pull.created_at)
        bucket_key = date_bucket_fn(created)
        if created >= start:
            buckets[bucket_key]["opened " + intext] += increment

            # Bucket based on its current state
            if pull.combinedstate == "merged":
                buckets[bucket_key]["merged " + intext] += increment
            elif pull.combinedstate == "closed":
                buckets[bucket_key]["closed " + intext] += increment
            else:
                # PR is still open
                print("Unresolved[{1}]: pull #{0.number}: {0.title}".format(
                    pull, bucket_key))
                buckets[bucket_key]["unresolved " + intext] += increment
예제 #5
0
def get_bucket_data(buckets,
                    repo_name,
                    date_bucket_fn,
                    start,
                    by_size=False,
                    lines=False,
                    closed=False):
    print(repo_name)
    pull_details = "all" if (by_size or lines) else "list"
    for pull in get_pulls(repo_name,
                          state="all",
                          pull_details=pull_details,
                          org=True):
        # print("{0.id}: {0.combinedstate} {0.intext}".format(pull))

        ignore_ref = "(^release$|^rc/)"
        if re.search(ignore_ref, pull.base_ref):
            #print("Ignoring pull #{0.number}: {0.title}".format(pull))
            continue

        if by_size:
            size = " " + size_of_pull(pull)
        else:
            size = ""
        intext = pull.intext

        if lines:
            increment = lines_in_pull(pull)
        else:
            increment = 1

        created = make_timezone_aware(pull.created_at)
        if created >= start:
            buckets[date_bucket_fn(created)]["opened " + intext +
                                             size] += increment

        if pull.combinedstate == "merged":
            merged = make_timezone_aware(pull.merged_at)
            if merged >= start:
                buckets[date_bucket_fn(merged)]["merged " + intext +
                                                size] += increment
        elif closed and pull.combinedstate == "closed":
            closed = make_timezone_aware(pull.closed_at)
            buckets[date_bucket_fn(closed)]["closed " + intext +
                                            size] += increment
예제 #6
0
def get_bucket_data(buckets, repo_name, date_bucket_fn, start, lines=False, internal=False):
    print(repo_name)
    pull_details = "all" if lines else "list"
    for pull in get_pulls(repo_name, state="all", pull_details=pull_details, org=True):
        # print("{0.id}: {0.combinedstate} {0.intext}".format(pull))

        intext = pull.intext  # internal or external
        # if internal is True, only want to look at "internal" PRs, and if
        # internal is False, only want to look at "external" PRs.
        if (internal and intext != 'internal') or (not internal and intext != 'external'):
            continue

        ignore_ref = "(^release$|^rc/)"
        if re.search(ignore_ref, pull.base_ref) or pull.title == "Update translations (autogenerated message)":
            # print("Ignoring pull #{0.number}: {0.title}".format(pull))
            continue

        if lines:
            increment = lines_in_pull(pull)
        else:
            increment = 1

        created = make_timezone_aware(pull.created_at)
        bucket_key = date_bucket_fn(created)
        if created >= start:
            buckets[bucket_key]["opened " + intext] += increment

            # Bucket based on its current state 
            if pull.combinedstate == "merged":
                buckets[bucket_key]["merged " + intext] += increment
            elif pull.combinedstate == "closed":
                buckets[bucket_key]["closed " + intext] += increment
            else:
                # PR is still open
                print("Unresolved[{1}]: pull #{0.number}: {0.title}".format(pull, bucket_key))
                buckets[bucket_key]["unresolved " + intext] += increment
예제 #7
0
def main(argv):
    parser = argparse.ArgumentParser(description="Summarize pull requests by organization.")
    parser.add_argument(
        "--since", metavar="DAYS", type=int,
        help="Only consider pull requests closed in the past DAYS days"
    )
    parser.add_argument(
        "--start", type=date_arg,
        help="Date to start collecting, format is flexible: "
        "20141225, Dec/25/2014, 2014-12-25, etc"
    )
    parser.add_argument(
        "--end", type=date_arg,
        help="Date to end collecting, format is flexible: "
        "25/Dec/2014, 12/25/2014, 2014-12-25, etc"
    )
    parser.add_argument(
        "--short", action="store_true",
        help="Only show the short summary"
    )

    args = parser.parse_args(argv[1:])

    since = None
    if args.since:
        since = make_timezone_aware(datetime.today() - timedelta(days=args.since))
    if args.start:
        if since is not None:
            raise Exception("Can't use --since and --start")
        since = args.start

    repos = [ r for r in Repo.from_yaml() if r.track_pulls ]

    by_org = collections.defaultdict(list)

    for repo in repos:
        for pull in get_pulls(repo.name, state="closed", pull_details="list", org=True, since=since):
            # We only want external pull requests.
            if pull.intext != "external":
                continue
            # We only want merged pull requests.
            if pull.combinedstate != "merged":
                continue
            # Pull requests can be recently modified even if they were merged
            # long ago, so only take things merged since our since date.
            merged = make_timezone_aware(pull.merged_at)
            if merged < since:
                continue

            if args.end is not None:
                # We don't want to count things merged after our end date.
                if merged >= args.end:
                    continue

            pull.repo = repo.nick
            by_org[pull.org].append(pull)

    keys = sorted(by_org, key=lambda k: len(by_org[k]), reverse=True)
    for key in keys:
        print("{}: {}".format(key, len(by_org[key])))

    fmt = "{pull.repo:4s} {pull.number:5d} {pull.user_login:>17s} {pull.title}"

    if args.short:
        if 'unsigned' in keys:
            print("\n-- {} -------".format('unsigned'))
            for pull in by_org['unsigned']:
                print(fmt.format(pull=pull))
    else:
        for key in keys:
            print("\n-- {} -------".format(key))
            for pull in by_org[key]:
                print(fmt.format(pull=pull))
예제 #8
0
def get_external_pulls(repo):
    """Produce a stream of external pull requests."""
    for issue in get_pulls(repo, state="all", org=True):
        if issue.intext == 'external':
            yield issue
예제 #9
0
def get_filtered_pulls(repo, interesting):
    """Produce a stream of external pull requests."""
    for issue in get_pulls(repo, state="all", org=True):
        if interesting(issue):
            yield issue
예제 #10
0
def get_filtered_pulls(repo, interesting):
    """Produce a stream of external pull requests."""
    for issue in get_pulls(repo, state="all", org=True):
        if interesting(issue):
            yield issue