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
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)
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
'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
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()