def _compare_commits(sha1, sha2):
    if sha1 == sha2:
        return 0
    try:
        wpt_git(['merge-base', '--is-ancestor', sha1, sha2])
        # SHA1 is an ancestor of SHA2
        return -1
    except subprocess.CalledProcessError:
        # The exception is raised when the return code is non-zero.
        return 1
Example #2
0
def verify_pr_tags(prs):
    # sort PRs by commit date and assert that this matches commit DAG order
    sorted_prs = sorted(prs, key=pr_commit_date)
    for pr, next_pr in zip(sorted_prs, sorted_prs[1:]):
        try:
            wpt_git(['merge-base', '--is-ancestor', pr['tag'], next_pr['tag']])
        except subprocess.CalledProcessError:
            print('Expected {} ({}) to be an ancestor of'
                  '{} ({}) based on commit dates.'
                  .format(pr['tag'], pr['commit_date'],
                          next_pr['tag'], next_pr['commit_date']))
            print('When this is not the case, the commit dates of merge_pr_*'
                  'tags cannot be trusted.')
            exit(1)
Example #3
0
def write_pr_db():
    prs = []
    for pr_tag in get_merge_pr_tags():
        # iso-strict-local works because TZ=UTC is set in the environment
        info = wpt_git(['log', '--no-walk', '--format=%H|%cd|%B',
                        '--date=iso-strict-local', pr_tag])
        commit, commit_date, commit_message = info.split('|', 2)

        chromium_commit = ''
        match = re.search(r'^Change-Id: (.+)$', commit_message, re.MULTILINE)
        if match is None:
            match = re.search(r'^Cr-Commit-Position: (.+)$',
                              commit_message, re.MULTILINE)
        if match is not None:
            chromium_commit = match.group(1).strip()

        prs.append({
            'tag': pr_tag,
            'commit': commit,
            'commit_date': commit_date,
            'chromium_commit': chromium_commit
        })

    print('Verifying that commit date order matches commit graph order')
    verify_pr_tags(prs)

    pr_db = PRDB(PRS_FILE)
    for pr in prs:
        pr_db.add({
            'PR': str(pr_number_from_tag(pr['tag'])),
            'merge_commit_sha': pr['commit'],
            'merged_at': pr['commit_date'],
            'chromium_commit': pr['chromium_commit']
        })
    pr_db.write(order='asc')

    print('Wrote {} PRs to {}'.format(len(pr_db), PRS_FILE))
    return pr_db
Example #4
0
    'Servo exports':
    ['--grep', '^Upstreamed from https://github\\.com/servo/'],
    'WebKit exports':
    ['--grep', '^WebKit export of https://bugs\\.webkit\\.org/'],
}


def isoformat(dt):
    return dt.isoformat() + 'Z'


db = CommitDB(COMMITS_CSV)
now = datetime.now()
since = datetime(2015, 1, 1)

while since < now:
    until = since + relativedelta(months=1)
    args = [
        'rev-list', 'origin/master', '--count', '--no-merges', '--since',
        isoformat(since), '--until',
        isoformat(until)
    ]
    record = {'Month': since.strftime('%Y-%m')}
    for field, grep_args in FIELD_GREP_ARGS.items():
        count = wpt_git(args + grep_args).strip()
        record[field] = count
    db.add(record)
    since = until

db.write()
def get_latencies(imports, prs):
    try:
        with open(MINS_FILE) as f:
            latencies = json.load(f)
            print('Read', len(latencies), 'results from', MINS_FILE)
            return latencies
    except (IOError, ValueError):
        pass

    latencies = {}
    total_prs = len(prs)
    for index, pr in enumerate(prs):
        print("[{}/{}] PR: {}".format(index + 1, total_prs, pr['html_url']))
        merge_commit = pr['merge_commit_sha']
        merged_at = pr['merged_at']
        try:
            wpt_git(['cat-file', '-t', merge_commit])
        except subprocess.CalledProcessError:
            print('Merge commit {} does not exist. SKIPPING!'.format(
                merge_commit))
            continue
        if _compare_commits(merge_commit, imports[-1].wpt_sha) > 0:
            print(
                'Merge point {} after last import point {}. SKIPPING!'.format(
                    merge_commit, imports[-1].wpt_sha))
            continue
        if _compare_commits(merge_commit, imports[0].wpt_sha) < 0:
            print('Merge point {} before first import point {}. SKIPPING!'.
                  format(merge_commit, imports[0].wpt_sha))
            continue

        index_found = binary_search_import(merge_commit, imports)
        import_found = imports[index_found]
        previous_import = imports[index_found - 1]
        # Check if I get my binary search right :)
        assert _compare_commits(merge_commit, import_found.wpt_sha) <= 0, \
               "PR merge point {} after import {}".format(
                   merge_commit, import_found)
        assert _compare_commits(merge_commit, previous_import.wpt_sha) > 0, \
               "PR merge point {} before the previous import {}".format(
                   merge_commit, previous_import)

        import_time = dateutil.parser.parse(imports[index_found].date)
        wpt_merge_time = dateutil.parser.parse(merged_at)
        delay = (import_time - wpt_merge_time).total_seconds() / 60
        print('PR merged at {} imported at {}'.format(merge_commit,
                                                      import_found.wpt_sha))
        print('Chromium import {} at {}'.format(import_found.cr_sha,
                                                import_found.date))
        print('Delay (mins):', delay)
        latencies[merge_commit] = {
            'import_sha': import_found.cr_sha,
            'import_time': import_found.date,
            'latency': delay,
        }

    print('Writing file', MINS_FILE)
    with open(MINS_FILE, 'w') as f:
        json.dump(latencies, f, indent=2)

    return latencies
Example #6
0
def get_merge_pr_tags():
    """Gets the list of merge_pr_* tags as string."""
    # --format="%(refname:strip=2) %(objectname)" would also include SHA-1
    return wpt_git(['tag', '--list', 'merge_pr_*']).splitlines()