Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(527)

Side by Side Diff: commit_queue.py

Issue 23483019: Changes to support One-Click Revert in Commit Queue (Closed) Base URL: https://src.chromium.org/chrome/trunk/tools/commit-queue/
Patch Set: Created 7 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | context.py » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 #!/usr/bin/env python 1 #!/usr/bin/env python
2 # Copyright (c) 2012 The Chromium Authors. All rights reserved. 2 # Copyright (c) 2012 The Chromium Authors. All rights reserved.
3 # Use of this source code is governed by a BSD-style license that can be 3 # Use of this source code is governed by a BSD-style license that can be
4 # found in the LICENSE file. 4 # found in the LICENSE file.
5 """Commit queue executable. 5 """Commit queue executable.
6 6
7 Reuse Rietveld and the Chromium Try Server to process and automatically commit 7 Reuse Rietveld and the Chromium Try Server to process and automatically commit
8 patches. 8 patches.
9 """ 9 """
10 10
(...skipping 17 matching lines...) Expand all
28 import errors 28 import errors
29 import projects 29 import projects
30 import sig_handler 30 import sig_handler
31 31
32 32
33 ROOT_DIR = os.path.dirname(os.path.abspath(__file__)) 33 ROOT_DIR = os.path.dirname(os.path.abspath(__file__))
34 34
35 35
36 class OnlyIssueRietveld(rietveld.Rietveld): 36 class OnlyIssueRietveld(rietveld.Rietveld):
37 """Returns a single issue for end-to-end in prod testing.""" 37 """Returns a single issue for end-to-end in prod testing."""
38 def __init__(self, url, email, password, extra_headers, only_issue): 38 def __init__(self, url, email, password, extra_headers, only_issue,
39 only_revert_issue):
39 super(OnlyIssueRietveld, self).__init__(url, email, password, extra_headers) 40 super(OnlyIssueRietveld, self).__init__(url, email, password, extra_headers)
40 self._only_issue = only_issue 41 self._only_issue = only_issue
42 self._only_revert_issue = only_revert_issue
41 43
42 def get_pending_issues(self): 44 def get_pending_issues(self):
43 """If it's set to return a single issue, only return this one.""" 45 """If it's set to return a single issue, only return this one."""
44 if self._only_issue: 46 if self._only_issue:
45 return [self._only_issue] 47 return [self._only_issue]
46 return [] 48 return []
47 49
50 def get_revert_issues(self):
51 """If it's set to return a single revert issue, only return this one."""
52 if self._only_revert_issue:
53 return [self._only_revert_issue]
54 return []
55
48 def get_issue_properties(self, issue, messages): 56 def get_issue_properties(self, issue, messages):
49 """Hacks the result to fake that the issue has the commit bit set.""" 57 """Hacks the result to fake that the issue has the commit bit set."""
50 data = super(OnlyIssueRietveld, self).get_issue_properties(issue, messages) 58 data = super(OnlyIssueRietveld, self).get_issue_properties(issue, messages)
51 if issue == self._only_issue: 59 if issue == self._only_issue:
52 data['commit'] = True 60 data['commit'] = True
61 elif issue == self._only_revert_issue:
62 data['revert'] = True
53 return data 63 return data
54 64
55 def set_flag(self, issue, patchset, flag, value): 65 def set_flag(self, issue, patchset, flag, value):
56 if issue == self._only_issue and flag == 'commit' and value == 'False': 66 if issue == self._only_issue and flag == 'commit' and value == 'False':
57 self._only_issue = None 67 self._only_issue = None
58 return super(OnlyIssueRietveld, self).set_flag(issue, patchset, flag, value) 68 return super(OnlyIssueRietveld, self).set_flag(issue, patchset, flag, value)
59 69
60 70
61 class ReadOnlyRietveld(rietveld.Rietveld): 71 class ReadOnlyRietveld(rietveld.Rietveld):
62 def __init__(self, url, email, password, extra_headers, only_issue): 72 def __init__(self, url, email, password, extra_headers, only_issue,
73 only_revert_issue):
63 super(ReadOnlyRietveld, self).__init__(url, email, password, extra_headers) 74 super(ReadOnlyRietveld, self).__init__(url, email, password, extra_headers)
64 self._only_issue = only_issue 75 self._only_issue = only_issue
65 self._restricted = bool(only_issue) 76 self._only_revert_issue = only_revert_issue
77 self._restricted = bool(only_issue) or bool(only_revert_issue)
66 78
67 def _send(self, request_path, **kwargs): 79 def _send(self, request_path, **kwargs):
68 """Ignore all post requests.""" 80 """Ignore all post requests."""
69 if kwargs.get('payload'): 81 if kwargs.get('payload'):
70 logging.warn('Ignoring POST to %s', request_path) 82 logging.warn('Ignoring POST to %s', request_path)
71 return 83 return
72 return super(ReadOnlyRietveld, self)._send(request_path, **kwargs) 84 return super(ReadOnlyRietveld, self)._send(request_path, **kwargs)
73 85
74 def get_pending_issues(self): 86 def get_pending_issues(self):
75 """If it's set to return a single issue, only return this one.""" 87 """If it's set to return a single issue, only return this one."""
76 if self._restricted: 88 if self._restricted:
77 if self._only_issue: 89 if self._only_issue:
78 return [self._only_issue] 90 return [self._only_issue]
79 return [] 91 return []
80 return super(ReadOnlyRietveld, self).get_pending_issues() 92 return super(ReadOnlyRietveld, self).get_pending_issues()
81 93
94 def get_revert_issues(self):
95 """If it's set to return a single issue, only return this one."""
96 if self._restricted:
97 if self._only_revert_issue:
98 return [self._only_revert_issue]
99 return []
100 return super(ReadOnlyRietveld, self).get_revert_issues()
101
82 def get_issue_properties(self, issue, messages): 102 def get_issue_properties(self, issue, messages):
83 """Hacks the result to fake that the issue has the commit bit set.""" 103 """Hacks the result to fake that the issue has the commit bit set."""
84 data = super(ReadOnlyRietveld, self).get_issue_properties(issue, messages) 104 data = super(ReadOnlyRietveld, self).get_issue_properties(issue, messages)
85 if issue == self._only_issue: 105 if issue == self._only_issue:
86 data['commit'] = True 106 data['commit'] = True
107 elif issue == self._only_revert_issue:
108 data['revert'] = True
87 return data 109 return data
88 110
89 def set_flag(self, issue, patchset, flag, value): 111 def set_flag(self, issue, patchset, flag, value):
90 if issue == self._only_issue and flag == 'commit' and value == 'False': 112 if issue == self._only_issue and flag == 'commit' and value == 'False':
91 self._only_issue = None 113 self._only_issue = None
92 return super(ReadOnlyRietveld, self).set_flag(issue, patchset, flag, value) 114 return super(ReadOnlyRietveld, self).set_flag(issue, patchset, flag, value)
93 115
94 116
95 class FakeCheckout(object): 117 class FakeCheckout(object):
96 def __init__(self): 118 def __init__(self):
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after
158 description=sys.modules['__main__'].__doc__) 180 description=sys.modules['__main__'].__doc__)
159 project_choices = projects.supported_projects() 181 project_choices = projects.supported_projects()
160 parser.add_option('-v', '--verbose', action='store_true') 182 parser.add_option('-v', '--verbose', action='store_true')
161 parser.add_option( 183 parser.add_option(
162 '--no-dry-run', 184 '--no-dry-run',
163 action='store_false', 185 action='store_false',
164 dest='dry_run', 186 dest='dry_run',
165 default=True, 187 default=True,
166 help='Run for real instead of dry-run mode which is the default. ' 188 help='Run for real instead of dry-run mode which is the default. '
167 'WARNING: while the CQ won\'t touch rietveld in dry-run mode, the ' 189 'WARNING: while the CQ won\'t touch rietveld in dry-run mode, the '
168 'Try Server will. So it is recommended to use --only-issue') 190 'Try Server will. So it is recommended to use --only-issue or '
191 '--only-revert-issue')
169 parser.add_option( 192 parser.add_option(
170 '--only-issue', 193 '--only-issue',
171 type='int', 194 type='int',
172 help='Limits to a single issue. Useful for live testing; WARNING: it ' 195 help='Limits to a single issue. Useful for live testing; WARNING: it '
173 'will fake that the issue has the CQ bit set, so only try with an ' 196 'will fake that the issue has the CQ bit set, so only try with an '
174 'issue you don\'t mind about.') 197 'issue you don\'t mind about.')
175 parser.add_option( 198 parser.add_option(
199 '--only-revert-issue',
200 type='int',
201 help='Limits to a single issue to revert. Useful for live testing; '
202 'WARNING: it will fake that the issue has the revert bit set, so only '
203 'try with an issue you don\'t mind about.')
204 parser.add_option(
176 '--fake', 205 '--fake',
177 action='store_true', 206 action='store_true',
178 help='Run with a fake checkout to speed up testing') 207 help='Run with a fake checkout to speed up testing')
179 parser.add_option( 208 parser.add_option(
180 '--no-try', 209 '--no-try',
181 action='store_true', 210 action='store_true',
182 help='Don\'t send try jobs.') 211 help='Don\'t send try jobs.')
183 parser.add_option( 212 parser.add_option(
184 '-p', 213 '-p',
185 '--poll-interval', 214 '--poll-interval',
(...skipping 29 matching lines...) Expand all
215 os.path.join(ROOT_DIR, 'subversion_config')) 244 os.path.join(ROOT_DIR, 'subversion_config'))
216 245
217 url = 'https://chromiumcodereview.appspot.com' 246 url = 'https://chromiumcodereview.appspot.com'
218 gaia_creds = creds.Credentials(os.path.join(work_dir, '.gaia_pwd')) 247 gaia_creds = creds.Credentials(os.path.join(work_dir, '.gaia_pwd'))
219 if options.dry_run: 248 if options.dry_run:
220 logging.debug('Dry run - skipping SCM check.') 249 logging.debug('Dry run - skipping SCM check.')
221 if options.only_issue: 250 if options.only_issue:
222 print( 251 print(
223 'Using read-only Rietveld; using only issue %d' % 252 'Using read-only Rietveld; using only issue %d' %
224 options.only_issue) 253 options.only_issue)
254 elif options.only_revert_issue:
255 print(
256 'Using read-only Rietveld; using only issue %d to revert' %
257 options.only_revert_issue)
225 else: 258 else:
226 print('Using read-only Rietveld') 259 print('Using read-only Rietveld')
227 # Make sure rietveld is not modified. 260 # Make sure rietveld is not modified.
228 rietveld_obj = ReadOnlyRietveld( 261 rietveld_obj = ReadOnlyRietveld(
229 url, 262 url,
230 options.user, 263 options.user,
231 gaia_creds.get(options.user), 264 gaia_creds.get(options.user),
232 None, 265 None,
233 options.only_issue) 266 options.only_issue,
267 options.only_revert_issue)
234 else: 268 else:
235 AlertOnUncleanCheckout() 269 AlertOnUncleanCheckout()
236 print('WARNING: The Commit Queue is going to commit stuff') 270 print('WARNING: The Commit Queue is going to commit stuff')
237 if options.only_issue: 271 if options.only_issue or options.only_revert_issue:
238 print('Using only issue %d' % options.only_issue) 272 if options.only_issue:
273 print('Using only issue %d' % options.only_issue)
274 else:
275 print('Using only issue %d to revert' % options.only_revert_issue)
239 rietveld_obj = OnlyIssueRietveld( 276 rietveld_obj = OnlyIssueRietveld(
240 url, 277 url,
241 options.user, 278 options.user,
242 gaia_creds.get(options.user), 279 gaia_creds.get(options.user),
243 None, 280 None,
244 options.only_issue) 281 options.only_issue,
282 options.only_revert_issue)
245 else: 283 else:
246 rietveld_obj = rietveld.Rietveld( 284 rietveld_obj = rietveld.Rietveld(
247 url, 285 url,
248 options.user, 286 options.user,
249 gaia_creds.get(options.user), 287 gaia_creds.get(options.user),
250 None) 288 None)
251 289
252 pc = projects.load_project( 290 pc = projects.load_project(
253 options.project, 291 options.project,
254 options.user, 292 options.user,
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
300 pc.process_new_pending_commit() 338 pc.process_new_pending_commit()
301 pc.update_status() 339 pc.update_status()
302 pc.scan_results() 340 pc.scan_results()
303 if sig_handler.getTriggeredSignals(): 341 if sig_handler.getTriggeredSignals():
304 raise KeyboardInterrupt() 342 raise KeyboardInterrupt()
305 # Save the db at each loop. The db can easily be in the 1mb range so 343 # Save the db at each loop. The db can easily be in the 1mb range so
306 # it's slowing down the CQ a tad but it in the 100ms range even for that 344 # it's slowing down the CQ a tad but it in the 100ms range even for that
307 # size. 345 # size.
308 pc.save(db_path) 346 pc.save(db_path)
309 347
310 # More than a second to wait and due to sync. 348 # More than a 2 seconds to wait and due to sync.
311 now = time.time() 349 now = time.time()
312 if (next_loop - now) >= 1 and (next_sync - now) <= 0: 350 if (next_loop - now) >= 2 and (next_sync - now) <= 0:
313 if sys.stdout.isatty(): 351 if sys.stdout.isatty():
314 sys.stdout.write('Syncing while waiting \r') 352 sys.stdout.write('Syncing while waiting \r')
315 sys.stdout.flush() 353 sys.stdout.flush()
316 try: 354 try:
317 pc.context.checkout.prepare(None) 355 pc.context.checkout.prepare(None)
318 except subprocess2.CalledProcessError as e: 356 except subprocess2.CalledProcessError as e:
319 # Don't crash, most of the time it's the svn server that is dead. 357 # Don't crash, most of the time it's the svn server that is dead.
320 # How fun. Send a stack trace to annoy the maintainer. 358 # How fun. Send a stack trace to annoy the maintainer.
321 errors.send_stack(e) 359 errors.send_stack(e)
322 next_sync = time.time() + SYNC_DELAY 360 next_sync = time.time() + SYNC_DELAY
(...skipping 30 matching lines...) Expand all
353 return 23 391 return 23
354 except errors.ConfigurationError as e: 392 except errors.ConfigurationError as e:
355 parser.error(str(e)) 393 parser.error(str(e))
356 return 1 394 return 1
357 return 0 395 return 0
358 396
359 397
360 if __name__ == '__main__': 398 if __name__ == '__main__':
361 fix_encoding.fix_encoding() 399 fix_encoding.fix_encoding()
362 sys.exit(main()) 400 sys.exit(main())
OLDNEW
« no previous file with comments | « no previous file | context.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698