OLD | NEW |
1 # Copyright 2016 The Chromium Authors. All rights reserved. | 1 # Copyright 2016 The Chromium Authors. All rights reserved. |
2 # Use of this source code is governed by a BSD-style license that can be | 2 # Use of this source code is governed by a BSD-style license that can be |
3 # found in the LICENSE file. | 3 # found in the LICENSE file. |
4 | 4 |
5 import logging | 5 import logging |
6 | 6 |
7 from webkitpy.w3c.local_wpt import LocalWPT | 7 from webkitpy.w3c.local_wpt import LocalWPT |
8 from webkitpy.w3c.chromium_commit import ChromiumCommit | 8 from webkitpy.w3c.chromium_commit import ChromiumCommit |
9 from webkitpy.w3c.deps_updater import DepsUpdater | |
10 | 9 |
11 _log = logging.getLogger(__name__) | 10 _log = logging.getLogger(__name__) |
12 | |
13 CHROMIUM_WPT_DIR = 'third_party/WebKit/LayoutTests/imported/wpt/' | 11 CHROMIUM_WPT_DIR = 'third_party/WebKit/LayoutTests/imported/wpt/' |
14 | 12 |
15 | 13 |
16 class TestExporter(object): | 14 class TestExporter(object): |
17 | 15 |
18 def __init__(self, host, wpt_github, dry_run=False): | 16 def __init__(self, host, wpt_github, dry_run=False): |
19 self.host = host | 17 self.host = host |
20 self.wpt_github = wpt_github | 18 self.wpt_github = wpt_github |
| 19 self.local_wpt = LocalWPT(self.host) |
21 self.dry_run = dry_run | 20 self.dry_run = dry_run |
22 | 21 |
23 def run(self): | 22 def run(self): |
24 # First, poll for an in-flight pull request and merge if exists | 23 # First, poll for an in-flight pull request and merge if exists |
25 pull_requests = self.wpt_github.in_flight_pull_requests() | 24 pull_requests = self.wpt_github.in_flight_pull_requests() |
26 | 25 |
27 if len(pull_requests) == 1: | 26 if len(pull_requests) == 1: |
28 pull_request = pull_requests.pop() | 27 pull_request = pull_requests.pop() |
29 | 28 |
30 _log.info('In-flight PR found: #%d', pull_request['number']) | 29 _log.info('In-flight PR found: #%d', pull_request['number']) |
31 _log.info(pull_request['title']) | 30 _log.info(pull_request['title']) |
32 | 31 |
33 # TODO(jeffcarp): Check the PR status here | 32 # TODO(jeffcarp): Check the PR status here |
34 | 33 |
35 if self.dry_run: | 34 if self.dry_run: |
36 _log.info('[dry_run] Would have attempted to merge PR') | 35 _log.info('[dry_run] Would have attempted to merge PR') |
37 else: | 36 else: |
38 _log.info('Merging...') | 37 _log.info('Merging...') |
39 self.wpt_github.merge_pull_request(pull_request['number']) | 38 self.wpt_github.merge_pull_request(pull_request['number']) |
40 _log.info('PR merged!') | 39 _log.info('PR merged!') |
41 elif len(pull_requests) > 1: | 40 elif len(pull_requests) > 1: |
42 _log.error(pull_requests) | 41 _log.error(pull_requests) |
43 # TODO(jeffcarp): Print links to PRs | 42 # TODO(jeffcarp): Print links to PRs |
44 raise Exception('More than two in-flight PRs!') | 43 raise Exception('More than two in-flight PRs!') |
45 | 44 |
46 # Second, look for exportable commits in Chromium | 45 # Second, look for exportable commits in Chromium |
47 # At this point, no in-flight PRs should exist | 46 # At this point, no in-flight PRs should exist |
48 # If there was an issue merging, it should have errored out | 47 # If there was an issue merging, it should have errored out |
49 local_wpt = LocalWPT(self.host, use_github=False) | |
50 | 48 |
51 # TODO(jeffcarp): have the script running this fetch Chromium origin/mas
ter | 49 # TODO(jeffcarp): have the script running this fetch Chromium origin/mas
ter |
52 # TODO(jeffcarp): move WPT fetch out of its constructor to match planned
ChromiumWPT pattern | 50 # TODO(jeffcarp): move WPT fetch out of its constructor to match planned
ChromiumWPT pattern |
53 | 51 |
54 wpt_commit, chromium_commit = local_wpt.most_recent_chromium_commit() | 52 wpt_commit, chromium_commit = self.local_wpt.most_recent_chromium_commit
() |
55 assert chromium_commit, 'No Chromium commit found, this is impossible' | 53 assert chromium_commit, 'No Chromium commit found, this is impossible' |
56 | 54 |
57 wpt_behind_master = local_wpt.commits_behind_master(wpt_commit) | 55 wpt_behind_master = self.local_wpt.commits_behind_master(wpt_commit) |
58 | 56 |
59 _log.info('\nLast Chromium export commit in web-platform-tests:') | 57 _log.info('\nLast Chromium export commit in web-platform-tests:') |
60 _log.info('web-platform-tests@%s', wpt_commit) | 58 _log.info('web-platform-tests@%s', wpt_commit) |
61 _log.info('(%d behind web-platform-tests@origin/master)', wpt_behind_mas
ter) | 59 _log.info('(%d behind web-platform-tests@origin/master)', wpt_behind_mas
ter) |
62 | 60 |
63 _log.info('\nThe above WPT commit points to the following Chromium commi
t:') | 61 _log.info('\nThe above WPT commit points to the following Chromium commi
t:') |
64 _log.info('chromium@%s', chromium_commit.sha) | 62 _log.info('chromium@%s', chromium_commit.sha) |
65 _log.info('(%d behind chromium@origin/master)', chromium_commit.num_behi
nd_master()) | 63 _log.info('(%d behind chromium@origin/master)', chromium_commit.num_behi
nd_master()) |
66 | 64 |
67 exportable_commits = self.exportable_commits_since(chromium_commit.sha) | 65 exportable_commits = self.exportable_commits_since(chromium_commit.sha) |
(...skipping 16 matching lines...) Expand all Loading... |
84 # TODO: now do a test comparison of patch against local WPT | 82 # TODO: now do a test comparison of patch against local WPT |
85 | 83 |
86 if self.dry_run: | 84 if self.dry_run: |
87 _log.info('[dry_run] Stopping before creating PR') | 85 _log.info('[dry_run] Stopping before creating PR') |
88 _log.info('\n\n[dry_run] message:') | 86 _log.info('\n\n[dry_run] message:') |
89 _log.info(message) | 87 _log.info(message) |
90 _log.info('\n\n[dry_run] patch:') | 88 _log.info('\n\n[dry_run] patch:') |
91 _log.info(patch) | 89 _log.info(patch) |
92 return | 90 return |
93 | 91 |
94 local_branch_name = local_wpt.create_branch_with_patch(message, patch) | 92 local_branch_name = self.local_wpt.create_branch_with_patch(message, pat
ch) |
95 | 93 |
96 response_data = self.wpt_github.create_pr( | 94 response_data = self.wpt_github.create_pr( |
97 local_branch_name=local_branch_name, | 95 local_branch_name=local_branch_name, |
98 desc_title=outbound_commit.subject(), | 96 desc_title=outbound_commit.subject(), |
99 body=outbound_commit.body()) | 97 body=outbound_commit.body()) |
100 | 98 |
101 _log.info('Create PR response: %s', response_data) | 99 _log.info('Create PR response: %s', response_data) |
102 | 100 |
103 def exportable_commits_since(self, commit): | 101 def exportable_commits_since(self, commit): |
104 """Returns SHAs of exportable commits since `commit` in chronological or
der. | 102 """Returns SHAs of exportable commits since `commit` in chronological or
der. |
105 | 103 |
106 Args: | 104 Args: |
107 commit: The SHA of the Chromium commit from which this method will l
ook. | 105 commit: The SHA of the Chromium commit from which this method will l
ook. |
108 """ | 106 """ |
109 repo_root = self.host.executive.run_command([ | 107 repo_root = self.host.executive.run_command([ |
110 'git', 'rev-parse', '--show-toplevel' | 108 'git', 'rev-parse', '--show-toplevel' |
111 ]).strip() | 109 ]).strip() |
112 | 110 |
113 commits = self.host.executive.run_command([ | 111 commits = self.host.executive.run_command([ |
114 'git', 'rev-list', '{}..HEAD'.format(commit), '--reverse', | 112 'git', 'rev-list', '{}..HEAD'.format(commit), '--reverse', |
115 '--', repo_root + '/' + CHROMIUM_WPT_DIR | 113 '--', repo_root + '/' + CHROMIUM_WPT_DIR |
116 ]).splitlines() | 114 ]).splitlines() |
117 | 115 |
118 chromium_commits = [ChromiumCommit(self.host, sha=c) for c in commits] | 116 chromium_commits = [ChromiumCommit(self.host, sha=c) for c in commits] |
119 | 117 |
120 def is_exportable(chromium_commit): | 118 def is_exportable(chromium_commit): |
121 message = chromium_commit.message() | 119 patch = chromium_commit.format_patch() |
122 return ( | 120 return ( |
123 'NOEXPORT=true' not in message | 121 patch |
124 and not message.startswith('Import ') | 122 and self.local_wpt.test_patch(patch) |
125 # TODO(jeffcarp): change this to allow any commit with | 123 and 'NOEXPORT=true' not in chromium_commit.message() |
126 # any non-expectation changes to be exportable | 124 and not chromium_commit.message().startswith('Import ') |
127 and not self._has_expectations(chromium_commit) | |
128 ) | 125 ) |
129 | 126 |
130 return filter(is_exportable, chromium_commits) | 127 return [c for c in chromium_commits if is_exportable(c)] |
131 | |
132 def _has_expectations(self, chromium_commit): | |
133 files = self.host.executive.run_command([ | |
134 'git', 'diff-tree', '--no-commit-id', | |
135 '--name-only', '-r', chromium_commit.sha | |
136 ]).splitlines() | |
137 | |
138 return any(DepsUpdater.is_baseline(f) for f in files) | |
OLD | NEW |