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

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

Issue 81193002: Pythonification and refactoring of push-to-trunk. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Refactor step generation. Created 7 years, 1 month 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/push_to_trunk.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
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
63 def FileToText(file_name): 63 def FileToText(file_name):
64 with open(file_name) as f: 64 with open(file_name) as f:
65 return f.read() 65 return f.read()
66 66
67 67
68 def MSub(rexp, replacement, text): 68 def MSub(rexp, replacement, text):
69 return re.sub(rexp, replacement, text, flags=re.MULTILINE) 69 return re.sub(rexp, replacement, text, flags=re.MULTILINE)
70 70
71 71
72 def Fill80(line): 72 def Fill80(line):
73 # Replace tabs and remove surrounding space.
74 line = re.sub(r"\t", r" ", line.strip())
75
76 # Format with 8 characters indentation and line width 80.
73 return textwrap.fill(line, width=80, initial_indent=" ", 77 return textwrap.fill(line, width=80, initial_indent=" ",
74 subsequent_indent=" ") 78 subsequent_indent=" ")
75 79
76 80
77 def GetLastChangeLogEntries(change_log_file): 81 def GetLastChangeLogEntries(change_log_file):
78 result = [] 82 result = []
79 for line in LinesInFile(change_log_file): 83 for line in LinesInFile(change_log_file):
80 if re.search(r"^\d{4}-\d{2}-\d{2}:", line) and result: break 84 if re.search(r"^\d{4}-\d{2}-\d{2}:", line) and result: break
81 result.append(line) 85 result.append(line)
82 return "".join(result) 86 return "".join(result)
83 87
84 88
85 def MakeComment(text): 89 def MakeComment(text):
86 return MSub(r"^( ?)", "#", text) 90 return MSub(r"^( ?)", "#", text)
87 91
88 92
89 def StripComments(text): 93 def StripComments(text):
90 # Use split not splitlines to keep terminal newlines. 94 # Use split not splitlines to keep terminal newlines.
91 return "\n".join(filter(lambda x: not x.startswith("#"), text.split("\n"))) 95 return "\n".join(filter(lambda x: not x.startswith("#"), text.split("\n")))
92 96
93 97
94 def MakeChangeLogBody(commit_messages, auto_format=False): 98 def MakeChangeLogBody(commit_messages, auto_format=False):
95 result = "" 99 result = ""
96 added_titles = set() 100 added_titles = set()
97 for (title, body, author) in commit_messages: 101 for (title, body, author) in commit_messages:
98 # TODO(machenbach): Reload the commit description from rietveld in order to 102 # TODO(machenbach): Reload the commit description from rietveld in order to
99 # catch late changes. 103 # catch late changes.
100 title = title.rstrip() 104 title = title.strip()
101 if auto_format: 105 if auto_format:
102 # Only add commits that set the LOG flag correctly. 106 # Only add commits that set the LOG flag correctly.
103 log_exp = r"^[ \t]*LOG[ \t]*=[ \t]*(?:Y(?:ES)?)|TRUE" 107 log_exp = r"^[ \t]*LOG[ \t]*=[ \t]*(?:Y(?:ES)?)|TRUE"
104 if not re.search(log_exp, body, flags=re.I | re.M): 108 if not re.search(log_exp, body, flags=re.I | re.M):
105 continue 109 continue
106 # Never include reverts. 110 # Never include reverts.
107 if title.startswith("Revert "): 111 if title.startswith("Revert "):
108 continue 112 continue
109 # Don't include duplicates. 113 # Don't include duplicates.
110 if title in added_titles: 114 if title in added_titles:
111 continue 115 continue
112 116
113 # TODO(machenbach): Let python do all formatting. Get raw git title, attach 117 # TODO(machenbach): Let python do all formatting. Get raw git title, attach
114 # issue and add/move dot to the end - all in one line. Make formatting and 118 # issue and add/move dot to the end - all in one line. Make formatting and
115 # indentation afterwards. 119 # indentation afterwards.
116 120
117 # Add the commit's title line. 121 # Add the commit's title line.
118 result += "%s\n" % title 122 result += "%s\n" % Fill80(title)
119 added_titles.add(title) 123 added_titles.add(title)
120 124
121 # Add bug references. 125 # Add bug references.
122 result += MakeChangeLogBugReference(body) 126 result += MakeChangeLogBugReference(body)
123 127
124 # Append the commit's author for reference if not in auto-format mode. 128 # Append the commit's author for reference if not in auto-format mode.
125 if not auto_format: 129 if not auto_format:
126 result += "%s\n" % author.rstrip() 130 result += "%s\n" % Fill80("(%s)" % author.strip())
127 131
128 result += "\n" 132 result += "\n"
129 return result 133 return result
130 134
131 135
132 def MakeChangeLogBugReference(body): 136 def MakeChangeLogBugReference(body):
133 """Grep for "BUG=xxxx" lines in the commit message and convert them to 137 """Grep for "BUG=xxxx" lines in the commit message and convert them to
134 "(issue xxxx)". 138 "(issue xxxx)".
135 """ 139 """
136 crbugs = [] 140 crbugs = []
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after
198 url_fh = urllib2.urlopen(url, None, 60) 202 url_fh = urllib2.urlopen(url, None, 60)
199 try: 203 try:
200 return url_fh.read() 204 return url_fh.read()
201 finally: 205 finally:
202 url_fh.close() 206 url_fh.close()
203 207
204 DEFAULT_SIDE_EFFECT_HANDLER = SideEffectHandler() 208 DEFAULT_SIDE_EFFECT_HANDLER = SideEffectHandler()
205 209
206 210
207 class Step(object): 211 class Step(object):
208 def __init__(self, text="", requires=None): 212 def __init__(self, text, requires, number, config, state, options, handler):
209 self._text = text 213 self._text = text
210 self._number = -1
211 self._options = None
212 self._requires = requires 214 self._requires = requires
213 self._side_effect_handler = DEFAULT_SIDE_EFFECT_HANDLER
214
215 def SetNumber(self, number):
216 self._number = number 215 self._number = number
217
218 def SetConfig(self, config):
219 self._config = config 216 self._config = config
220
221 def SetState(self, state):
222 self._state = state 217 self._state = state
223
224 def SetOptions(self, options):
225 self._options = options 218 self._options = options
226
227 def SetSideEffectHandler(self, handler):
228 self._side_effect_handler = handler 219 self._side_effect_handler = handler
220 assert self._number >= 0
221 assert self._config is not None
222 assert self._state is not None
223 assert self._side_effect_handler is not None
229 224
230 def Config(self, key): 225 def Config(self, key):
231 return self._config[key] 226 return self._config[key]
232 227
233 def Run(self): 228 def Run(self):
234 assert self._number >= 0
235 assert self._config is not None
236 assert self._state is not None
237 assert self._side_effect_handler is not None
238 if self._requires: 229 if self._requires:
239 self.RestoreIfUnset(self._requires) 230 self.RestoreIfUnset(self._requires)
240 if not self._state[self._requires]: 231 if not self._state[self._requires]:
241 return 232 return
242 print ">>> Step %d: %s" % (self._number, self._text) 233 print ">>> Step %d: %s" % (self._number, self._text)
243 self.RunStep() 234 self.RunStep()
244 235
245 def RunStep(self): 236 def RunStep(self):
246 raise NotImplementedError 237 raise NotImplementedError
247 238
(...skipping 156 matching lines...) Expand 10 before | Expand all | Expand 10 after
404 answer = self.ReadLine() 395 answer = self.ReadLine()
405 396
406 # Takes a file containing the patch to apply as first argument. 397 # Takes a file containing the patch to apply as first argument.
407 def ApplyPatch(self, patch_file, reverse_patch=""): 398 def ApplyPatch(self, patch_file, reverse_patch=""):
408 args = "apply --index --reject %s \"%s\"" % (reverse_patch, patch_file) 399 args = "apply --index --reject %s \"%s\"" % (reverse_patch, patch_file)
409 if self.Git(args) is None: 400 if self.Git(args) is None:
410 self.WaitForResolvingConflicts(patch_file) 401 self.WaitForResolvingConflicts(patch_file)
411 402
412 403
413 class UploadStep(Step): 404 class UploadStep(Step):
414 def __init__(self): 405 MESSAGE = "Upload for code review."
415 Step.__init__(self, "Upload for code review.")
416 406
417 def RunStep(self): 407 def RunStep(self):
418 if self._options.r: 408 if self._options.r:
419 print "Using account %s for review." % self._options.r 409 print "Using account %s for review." % self._options.r
420 reviewer = self._options.r 410 reviewer = self._options.r
421 else: 411 else:
422 print "Please enter the email address of a V8 reviewer for your patch: ", 412 print "Please enter the email address of a V8 reviewer for your patch: ",
423 self.DieInForcedMode("A reviewer must be specified in forced mode.") 413 self.DieInForcedMode("A reviewer must be specified in forced mode.")
424 reviewer = self.ReadLine() 414 reviewer = self.ReadLine()
425 force_flag = " -f" if self._options.f else "" 415 force_flag = " -f" if self._options.f else ""
426 args = "cl upload -r \"%s\" --send-mail%s" % (reviewer, force_flag) 416 args = "cl upload -r \"%s\" --send-mail%s" % (reviewer, force_flag)
427 # TODO(machenbach): Check output in forced mode. Verify that all required 417 # TODO(machenbach): Check output in forced mode. Verify that all required
428 # base files were uploaded, if not retry. 418 # base files were uploaded, if not retry.
429 if self.Git(args, pipe=False) is None: 419 if self.Git(args, pipe=False) is None:
430 self.Die("'git cl upload' failed, please try again.") 420 self.Die("'git cl upload' failed, please try again.")
431 421
432 422
423 def MakeStep(step_class=Step, number=0, state=None, config=None,
424 options=None, side_effect_handler=DEFAULT_SIDE_EFFECT_HANDLER):
425 # Allow to pass in empty dictionaries.
426 state = state if state is not None else {}
427 config = config if config is not None else {}
428
429 try:
430 message = step_class.MESSAGE
431 except AttributeError:
432 message = step_class.__name__
433 try:
434 requires = step_class.REQUIRES
435 except AttributeError:
436 requires = None
437
438 return step_class(message, requires, number=number, config=config,
439 state=state, options=options,
440 handler=side_effect_handler)
441
442
433 def RunScript(step_classes, 443 def RunScript(step_classes,
434 config, 444 config,
435 options, 445 options,
436 side_effect_handler=DEFAULT_SIDE_EFFECT_HANDLER): 446 side_effect_handler=DEFAULT_SIDE_EFFECT_HANDLER):
437 state = {} 447 state = {}
438 steps = [] 448 steps = []
439 number = 0 449 for (number, step_class) in enumerate(step_classes):
440 450 steps.append(MakeStep(step_class, number, state, config,
441 for step_class in step_classes: 451 options, side_effect_handler))
442 # TODO(machenbach): Factory methods.
443 step = step_class()
444 step.SetNumber(number)
445 step.SetConfig(config)
446 step.SetOptions(options)
447 step.SetState(state)
448 step.SetSideEffectHandler(side_effect_handler)
449 steps.append(step)
450 number += 1
451 452
452 for step in steps[options.s:]: 453 for step in steps[options.s:]:
453 step.Run() 454 step.Run()
OLDNEW
« no previous file with comments | « tools/push-to-trunk/auto_roll.py ('k') | tools/push-to-trunk/push_to_trunk.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698