OLD | NEW |
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 |
(...skipping 29 matching lines...) Expand all Loading... |
40 import textwrap | 40 import textwrap |
41 import time | 41 import time |
42 import urllib | 42 import urllib |
43 import urllib2 | 43 import urllib2 |
44 | 44 |
45 from git_recipes import GitRecipesMixin | 45 from git_recipes import GitRecipesMixin |
46 from git_recipes import GitFailedException | 46 from git_recipes import GitFailedException |
47 | 47 |
48 PERSISTFILE_BASENAME = "PERSISTFILE_BASENAME" | 48 PERSISTFILE_BASENAME = "PERSISTFILE_BASENAME" |
49 BRANCHNAME = "BRANCHNAME" | 49 BRANCHNAME = "BRANCHNAME" |
50 VERSION_FILE = "VERSION_FILE" | |
51 CHANGELOG_FILE = "CHANGELOG_FILE" | 50 CHANGELOG_FILE = "CHANGELOG_FILE" |
52 CHANGELOG_ENTRY_FILE = "CHANGELOG_ENTRY_FILE" | 51 CHANGELOG_ENTRY_FILE = "CHANGELOG_ENTRY_FILE" |
53 COMMITMSG_FILE = "COMMITMSG_FILE" | 52 COMMITMSG_FILE = "COMMITMSG_FILE" |
54 PATCH_FILE = "PATCH_FILE" | 53 PATCH_FILE = "PATCH_FILE" |
55 | 54 |
| 55 VERSION_FILE = os.path.join("src", "version.cc") |
| 56 |
56 # V8 base directory. | 57 # V8 base directory. |
57 DEFAULT_CWD = os.path.dirname( | 58 DEFAULT_CWD = os.path.dirname( |
58 os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) | 59 os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) |
59 | 60 |
60 | 61 |
61 def TextToFile(text, file_name): | 62 def TextToFile(text, file_name): |
62 with open(file_name, "w") as f: | 63 with open(file_name, "w") as f: |
63 f.write(text) | 64 f.write(text) |
64 | 65 |
65 | 66 |
(...skipping 189 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
255 return time.mktime(datetime.datetime.utcnow().timetuple()) | 256 return time.mktime(datetime.datetime.utcnow().timetuple()) |
256 | 257 |
257 DEFAULT_SIDE_EFFECT_HANDLER = SideEffectHandler() | 258 DEFAULT_SIDE_EFFECT_HANDLER = SideEffectHandler() |
258 | 259 |
259 | 260 |
260 class NoRetryException(Exception): | 261 class NoRetryException(Exception): |
261 pass | 262 pass |
262 | 263 |
263 | 264 |
264 class Step(GitRecipesMixin): | 265 class Step(GitRecipesMixin): |
265 def __init__(self, text, requires, number, config, state, options, handler): | 266 def __init__(self, text, number, config, state, options, handler): |
266 self._text = text | 267 self._text = text |
267 self._requires = requires | |
268 self._number = number | 268 self._number = number |
269 self._config = config | 269 self._config = config |
270 self._state = state | 270 self._state = state |
271 self._options = options | 271 self._options = options |
272 self._side_effect_handler = handler | 272 self._side_effect_handler = handler |
273 | 273 |
274 # The testing configuration might set a different default cwd. | 274 # The testing configuration might set a different default cwd. |
275 self.default_cwd = self._config.get("DEFAULT_CWD") or DEFAULT_CWD | 275 self.default_cwd = self._config.get("DEFAULT_CWD") or DEFAULT_CWD |
276 | 276 |
277 assert self._number >= 0 | 277 assert self._number >= 0 |
(...skipping 13 matching lines...) Expand all Loading... |
291 | 291 |
292 def Config(self, key): | 292 def Config(self, key): |
293 return self._config[key] | 293 return self._config[key] |
294 | 294 |
295 def Run(self): | 295 def Run(self): |
296 # Restore state. | 296 # Restore state. |
297 state_file = "%s-state.json" % self._config[PERSISTFILE_BASENAME] | 297 state_file = "%s-state.json" % self._config[PERSISTFILE_BASENAME] |
298 if not self._state and os.path.exists(state_file): | 298 if not self._state and os.path.exists(state_file): |
299 self._state.update(json.loads(FileToText(state_file))) | 299 self._state.update(json.loads(FileToText(state_file))) |
300 | 300 |
301 # Skip step if requirement is not met. | |
302 if self._requires and not self._state.get(self._requires): | |
303 return | |
304 | |
305 print ">>> Step %d: %s" % (self._number, self._text) | 301 print ">>> Step %d: %s" % (self._number, self._text) |
306 try: | 302 try: |
307 return self.RunStep() | 303 return self.RunStep() |
308 finally: | 304 finally: |
309 # Persist state. | 305 # Persist state. |
310 TextToFile(json.dumps(self._state), state_file) | 306 TextToFile(json.dumps(self._state), state_file) |
311 | 307 |
312 def RunStep(self): # pragma: no cover | 308 def RunStep(self): # pragma: no cover |
313 raise NotImplementedError | 309 raise NotImplementedError |
314 | 310 |
(...skipping 135 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
450 os.remove(f) | 446 os.remove(f) |
451 if os.path.isdir(f): | 447 if os.path.isdir(f): |
452 shutil.rmtree(f) | 448 shutil.rmtree(f) |
453 | 449 |
454 def ReadAndPersistVersion(self, prefix=""): | 450 def ReadAndPersistVersion(self, prefix=""): |
455 def ReadAndPersist(var_name, def_name): | 451 def ReadAndPersist(var_name, def_name): |
456 match = re.match(r"^#define %s\s+(\d*)" % def_name, line) | 452 match = re.match(r"^#define %s\s+(\d*)" % def_name, line) |
457 if match: | 453 if match: |
458 value = match.group(1) | 454 value = match.group(1) |
459 self["%s%s" % (prefix, var_name)] = value | 455 self["%s%s" % (prefix, var_name)] = value |
460 for line in LinesInFile(self._config[VERSION_FILE]): | 456 for line in LinesInFile(os.path.join(self.default_cwd, VERSION_FILE)): |
461 for (var_name, def_name) in [("major", "MAJOR_VERSION"), | 457 for (var_name, def_name) in [("major", "MAJOR_VERSION"), |
462 ("minor", "MINOR_VERSION"), | 458 ("minor", "MINOR_VERSION"), |
463 ("build", "BUILD_NUMBER"), | 459 ("build", "BUILD_NUMBER"), |
464 ("patch", "PATCH_LEVEL")]: | 460 ("patch", "PATCH_LEVEL")]: |
465 ReadAndPersist(var_name, def_name) | 461 ReadAndPersist(var_name, def_name) |
466 | 462 |
467 def WaitForLGTM(self): | 463 def WaitForLGTM(self): |
468 print ("Please wait for an LGTM, then type \"LGTM<Return>\" to commit " | 464 print ("Please wait for an LGTM, then type \"LGTM<Return>\" to commit " |
469 "your change. (If you need to iterate on the patch or double check " | 465 "your change. (If you need to iterate on the patch or double check " |
470 "that it's sane, do so in another shell, but remember to not " | 466 "that it's sane, do so in another shell, but remember to not " |
(...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
597 def MakeStep(step_class=Step, number=0, state=None, config=None, | 593 def MakeStep(step_class=Step, number=0, state=None, config=None, |
598 options=None, side_effect_handler=DEFAULT_SIDE_EFFECT_HANDLER): | 594 options=None, side_effect_handler=DEFAULT_SIDE_EFFECT_HANDLER): |
599 # Allow to pass in empty dictionaries. | 595 # Allow to pass in empty dictionaries. |
600 state = state if state is not None else {} | 596 state = state if state is not None else {} |
601 config = config if config is not None else {} | 597 config = config if config is not None else {} |
602 | 598 |
603 try: | 599 try: |
604 message = step_class.MESSAGE | 600 message = step_class.MESSAGE |
605 except AttributeError: | 601 except AttributeError: |
606 message = step_class.__name__ | 602 message = step_class.__name__ |
607 try: | |
608 requires = step_class.REQUIRES | |
609 except AttributeError: | |
610 requires = None | |
611 | 603 |
612 return step_class(message, requires, number=number, config=config, | 604 return step_class(message, number=number, config=config, |
613 state=state, options=options, | 605 state=state, options=options, |
614 handler=side_effect_handler) | 606 handler=side_effect_handler) |
615 | 607 |
616 | 608 |
617 class ScriptsBase(object): | 609 class ScriptsBase(object): |
618 # TODO(machenbach): Move static config here. | 610 # TODO(machenbach): Move static config here. |
619 def __init__(self, config, side_effect_handler=DEFAULT_SIDE_EFFECT_HANDLER, | 611 def __init__(self, config, side_effect_handler=DEFAULT_SIDE_EFFECT_HANDLER, |
620 state=None): | 612 state=None): |
621 self._config = config | 613 self._config = config |
622 self._side_effect_handler = side_effect_handler | 614 self._side_effect_handler = side_effect_handler |
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
707 for (number, step_class) in enumerate(step_classes): | 699 for (number, step_class) in enumerate(step_classes): |
708 steps.append(MakeStep(step_class, number, self._state, self._config, | 700 steps.append(MakeStep(step_class, number, self._state, self._config, |
709 options, self._side_effect_handler)) | 701 options, self._side_effect_handler)) |
710 for step in steps[options.step:]: | 702 for step in steps[options.step:]: |
711 if step.Run(): | 703 if step.Run(): |
712 return 0 | 704 return 0 |
713 return 0 | 705 return 0 |
714 | 706 |
715 def Run(self, args=None): | 707 def Run(self, args=None): |
716 return self.RunSteps(self._Steps(), args) | 708 return self.RunSteps(self._Steps(), args) |
OLD | NEW |