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

Side by Side Diff: tools/push-to-trunk/common_includes.py

Issue 185263003: Refactoring: Make script dependencies more object-oriented in push and merge scripts. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 6 years, 9 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 | Annotate | Revision Log
« no previous file with comments | « tools/push-to-trunk/auto_roll.py ('k') | tools/push-to-trunk/merge_to_branch.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 2013 the V8 project authors. All rights reserved. 2 # Copyright 2013 the V8 project authors. All rights reserved.
3 # Redistribution and use in source and binary forms, with or without 3 # Redistribution and use in source and binary forms, with or without
4 # modification, are permitted provided that the following conditions are 4 # modification, are permitted provided that the following conditions are
5 # met: 5 # met:
6 # 6 #
7 # * Redistributions of source code must retain the above copyright 7 # * Redistributions of source code must retain the above copyright
8 # notice, this list of conditions and the following disclaimer. 8 # notice, this list of conditions and the following disclaimer.
9 # * Redistributions in binary form must reproduce the above 9 # * Redistributions in binary form must reproduce the above
10 # copyright notice, this list of conditions and the following 10 # copyright notice, this list of conditions and the following
11 # disclaimer in the documentation and/or other materials provided 11 # disclaimer in the documentation and/or other materials provided
12 # with the distribution. 12 # with the distribution.
13 # * Neither the name of Google Inc. nor the names of its 13 # * Neither the name of Google Inc. nor the names of its
14 # contributors may be used to endorse or promote products derived 14 # contributors may be used to endorse or promote products derived
15 # from this software without specific prior written permission. 15 # from this software without specific prior written permission.
16 # 16 #
17 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 17 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18 # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 18 # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
19 # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 19 # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
20 # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 20 # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
21 # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 21 # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
22 # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 22 # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
23 # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23 # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24 # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24 # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25 # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25 # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26 # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 26 # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27 # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 28
29 import argparse
29 import datetime 30 import datetime
30 import json 31 import json
31 import os 32 import os
32 import re 33 import re
33 import subprocess 34 import subprocess
34 import sys 35 import sys
35 import textwrap 36 import textwrap
36 import time 37 import time
37 import urllib2 38 import urllib2
38 39
(...skipping 180 matching lines...) Expand 10 before | Expand all | Expand 10 after
219 220
220 221
221 class NoRetryException(Exception): 222 class NoRetryException(Exception):
222 pass 223 pass
223 224
224 225
225 class GitFailedException(Exception): 226 class GitFailedException(Exception):
226 pass 227 pass
227 228
228 229
229 class CommonOptions(object):
230 def __init__(self, options, manual=True):
231 self.requires_editor = True
232 self.wait_for_lgtm = True
233 self.step = options.step
234 self.force_readline_defaults = not manual
235 self.force_upload = not manual
236 self.manual = manual
237 self.reviewer = getattr(options, 'reviewer', "")
238 self.author = getattr(options, 'author', "")
239
240
241 class Step(GitRecipesMixin): 230 class Step(GitRecipesMixin):
242 def __init__(self, text, requires, number, config, state, options, handler): 231 def __init__(self, text, requires, number, config, state, options, handler):
243 self._text = text 232 self._text = text
244 self._requires = requires 233 self._requires = requires
245 self._number = number 234 self._number = number
246 self._config = config 235 self._config = config
247 self._state = state 236 self._state = state
248 self._options = options 237 self._options = options
249 self._side_effect_handler = handler 238 self._side_effect_handler = handler
250 assert self._number >= 0 239 assert self._number >= 0
251 assert self._config is not None 240 assert self._config is not None
252 assert self._state is not None 241 assert self._state is not None
253 assert self._side_effect_handler is not None 242 assert self._side_effect_handler is not None
254 assert isinstance(options, CommonOptions)
255 243
256 def __getitem__(self, key): 244 def __getitem__(self, key):
257 # Convenience method to allow direct [] access on step classes for 245 # Convenience method to allow direct [] access on step classes for
258 # manipulating the backed state dict. 246 # manipulating the backed state dict.
259 return self._state[key] 247 return self._state[key]
260 248
261 def __setitem__(self, key, value): 249 def __setitem__(self, key, value):
262 # Convenience method to allow direct [] access on step classes for 250 # Convenience method to allow direct [] access on step classes for
263 # manipulating the backed state dict. 251 # manipulating the backed state dict.
264 self._state[key] = value 252 self._state[key] = value
(...skipping 230 matching lines...) Expand 10 before | Expand all | Expand 10 after
495 try: 483 try:
496 requires = step_class.REQUIRES 484 requires = step_class.REQUIRES
497 except AttributeError: 485 except AttributeError:
498 requires = None 486 requires = None
499 487
500 return step_class(message, requires, number=number, config=config, 488 return step_class(message, requires, number=number, config=config,
501 state=state, options=options, 489 state=state, options=options,
502 handler=side_effect_handler) 490 handler=side_effect_handler)
503 491
504 492
505 def RunScript(step_classes, 493 class ScriptsBase(object):
506 config, 494 # TODO(machenbach): Move static config here.
507 options, 495 def __init__(self, config, side_effect_handler=DEFAULT_SIDE_EFFECT_HANDLER,
508 side_effect_handler=DEFAULT_SIDE_EFFECT_HANDLER): 496 state=None):
509 state_file = "%s-state.json" % config[PERSISTFILE_BASENAME] 497 self._config = config
510 if options.step == 0 and os.path.exists(state_file): 498 self._side_effect_handler = side_effect_handler
511 os.remove(state_file) 499 self._state = state if state is not None else {}
512 state = {}
513 steps = []
514 for (number, step_class) in enumerate(step_classes):
515 steps.append(MakeStep(step_class, number, state, config,
516 options, side_effect_handler))
517 500
518 for step in steps[options.step:]: 501 def _Description(self):
519 step.Run() 502 return None
503
504 def _PrepareOptions(self, parser):
505 pass
506
507 def _ProcessOptions(self, options):
508 return True
509
510 def _Steps(self):
511 raise Exception("Not implemented.")
512
513 def MakeOptions(self, args=None):
514 parser = argparse.ArgumentParser(description=self._Description())
515 parser.add_argument("-a", "--author", default="",
516 help="The author email used for rietveld.")
517 parser.add_argument("-r", "--reviewer", default="",
518 help="The account name to be used for reviews.")
519 parser.add_argument("-s", "--step",
520 help="Specify the step where to start work. Default: 0.",
521 default=0, type=int)
522
523 self._PrepareOptions(parser)
524
525 if args is None:
526 options = parser.parse_args()
527 else:
528 options = parser.parse_args(args)
529
530 # Process common options.
531 if options.step < 0:
532 print "Bad step number %d" % options.step
533 parser.print_help()
534 return None
535
536 # Defaults for options, common to all scripts.
537 options.manual = getattr(options, "manual", True)
538 options.force = getattr(options, "force", False)
539
540 # Derived options.
541 options.requires_editor = not options.force
542 options.wait_for_lgtm = not options.force
543 options.force_readline_defaults = not options.manual
544 options.force_upload = not options.manual
545
546 # Process script specific options.
547 if not self._ProcessOptions(options):
548 parser.print_help()
549 return None
550 return options
551
552 def RunSteps(self, step_classes, args=None):
553 options = self.MakeOptions(args)
554 if not options:
555 return 1
556
557 state_file = "%s-state.json" % self._config[PERSISTFILE_BASENAME]
558 if options.step == 0 and os.path.exists(state_file):
559 os.remove(state_file)
560
561 steps = []
562 for (number, step_class) in enumerate(step_classes):
563 steps.append(MakeStep(step_class, number, self._state, self._config,
564 options, self._side_effect_handler))
565 for step in steps[options.step:]:
566 step.Run()
567 return 0
568
569 def Run(self, args=None):
570 return self.RunSteps(self._Steps(), args)
OLDNEW
« no previous file with comments | « tools/push-to-trunk/auto_roll.py ('k') | tools/push-to-trunk/merge_to_branch.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698