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

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

Issue 196133017: Experimental parser: merge r19949 (Closed) Base URL: https://v8.googlecode.com/svn/branches/experimental/parser
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/git_recipes.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 2014 the V8 project authors. All rights reserved. 2 # Copyright 2014 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 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
43 "/tmp/v8-merge-to-branch-tempfile-already-merging", 43 "/tmp/v8-merge-to-branch-tempfile-already-merging",
44 TEMP_BRANCH: "prepare-merge-temporary-branch-created-by-script", 44 TEMP_BRANCH: "prepare-merge-temporary-branch-created-by-script",
45 DOT_GIT_LOCATION: ".git", 45 DOT_GIT_LOCATION: ".git",
46 VERSION_FILE: "src/version.cc", 46 VERSION_FILE: "src/version.cc",
47 TEMPORARY_PATCH_FILE: "/tmp/v8-prepare-merge-tempfile-temporary-patch", 47 TEMPORARY_PATCH_FILE: "/tmp/v8-prepare-merge-tempfile-temporary-patch",
48 COMMITMSG_FILE: "/tmp/v8-prepare-merge-tempfile-commitmsg", 48 COMMITMSG_FILE: "/tmp/v8-prepare-merge-tempfile-commitmsg",
49 COMMIT_HASHES_FILE: "/tmp/v8-merge-to-branch-tempfile-PATCH_COMMIT_HASHES", 49 COMMIT_HASHES_FILE: "/tmp/v8-merge-to-branch-tempfile-PATCH_COMMIT_HASHES",
50 } 50 }
51 51
52 52
53 class MergeToBranchOptions(CommonOptions):
54 def __init__(self, options):
55 super(MergeToBranchOptions, self).__init__(options, True)
56 self.requires_editor = True
57 self.wait_for_lgtm = True
58 self.delete_sentinel = options.f
59 self.message = getattr(options, "message", "")
60 self.revert = getattr(options, "r", False)
61 self.revert_bleeding_edge = getattr(options, "revert_bleeding_edge", False)
62 self.patch = getattr(options, "p", "")
63 self.branch = options.branch
64 self.revisions = options.revisions
65
66
67 class Preparation(Step): 53 class Preparation(Step):
68 MESSAGE = "Preparation." 54 MESSAGE = "Preparation."
69 55
70 def RunStep(self): 56 def RunStep(self):
71 if os.path.exists(self.Config(ALREADY_MERGING_SENTINEL_FILE)): 57 if os.path.exists(self.Config(ALREADY_MERGING_SENTINEL_FILE)):
72 if self._options.delete_sentinel: 58 if self._options.force:
73 os.remove(self.Config(ALREADY_MERGING_SENTINEL_FILE)) 59 os.remove(self.Config(ALREADY_MERGING_SENTINEL_FILE))
74 elif self._options.step == 0: 60 elif self._options.step == 0: # pragma: no cover
75 self.Die("A merge is already in progress") 61 self.Die("A merge is already in progress")
76 open(self.Config(ALREADY_MERGING_SENTINEL_FILE), "a").close() 62 open(self.Config(ALREADY_MERGING_SENTINEL_FILE), "a").close()
77 63
78 self.InitialEnvironmentChecks() 64 self.InitialEnvironmentChecks()
79 if self._options.revert_bleeding_edge: 65 if self._options.revert_bleeding_edge:
80 self["merge_to_branch"] = "bleeding_edge" 66 self["merge_to_branch"] = "bleeding_edge"
81 elif self._options.branch: 67 elif self._options.branch:
82 self["merge_to_branch"] = self._options.branch 68 self["merge_to_branch"] = self._options.branch
83 else: 69 else: # pragma: no cover
84 self.Die("Please specify a branch to merge to") 70 self.Die("Please specify a branch to merge to")
85 71
86 self.CommonPrepare() 72 self.CommonPrepare()
87 self.PrepareBranch() 73 self.PrepareBranch()
88 74
89 75
90 class CreateBranch(Step): 76 class CreateBranch(Step):
91 MESSAGE = "Create a fresh branch for the patch." 77 MESSAGE = "Create a fresh branch for the patch."
92 78
93 def RunStep(self): 79 def RunStep(self):
94 self.GitCreateBranch(self.Config(BRANCHNAME), 80 self.GitCreateBranch(self.Config(BRANCHNAME),
95 "svn/%s" % self["merge_to_branch"]) 81 "svn/%s" % self["merge_to_branch"])
96 82
97 83
98 class SearchArchitecturePorts(Step): 84 class SearchArchitecturePorts(Step):
99 MESSAGE = "Search for corresponding architecture ports." 85 MESSAGE = "Search for corresponding architecture ports."
100 86
101 def RunStep(self): 87 def RunStep(self):
102 self["full_revision_list"] = list(OrderedDict.fromkeys( 88 self["full_revision_list"] = list(OrderedDict.fromkeys(
103 self._options.revisions)) 89 self._options.revisions))
104 port_revision_list = [] 90 port_revision_list = []
105 for revision in self["full_revision_list"]: 91 for revision in self["full_revision_list"]:
106 # Search for commits which matches the "Port rXXX" pattern. 92 # Search for commits which matches the "Port rXXX" pattern.
107 git_hashes = self.GitLog(reverse=True, format="%H", 93 git_hashes = self.GitLog(reverse=True, format="%H",
108 grep="Port r%d" % int(revision), 94 grep="Port r%d" % int(revision),
109 branch="svn/bleeding_edge") 95 branch="svn/bleeding_edge")
110 for git_hash in git_hashes.splitlines(): 96 for git_hash in git_hashes.splitlines():
111 svn_revision = self.GitSVNFindSVNRev(git_hash, "svn/bleeding_edge") 97 svn_revision = self.GitSVNFindSVNRev(git_hash, "svn/bleeding_edge")
112 if not svn_revision: 98 if not svn_revision: # pragma: no cover
113 self.Die("Cannot determine svn revision for %s" % git_hash) 99 self.Die("Cannot determine svn revision for %s" % git_hash)
114 revision_title = self.GitLog(n=1, format="%s", git_hash=git_hash) 100 revision_title = self.GitLog(n=1, format="%s", git_hash=git_hash)
115 101
116 # Is this revision included in the original revision list? 102 # Is this revision included in the original revision list?
117 if svn_revision in self["full_revision_list"]: 103 if svn_revision in self["full_revision_list"]:
118 print("Found port of r%s -> r%s (already included): %s" 104 print("Found port of r%s -> r%s (already included): %s"
119 % (revision, svn_revision, revision_title)) 105 % (revision, svn_revision, revision_title))
120 else: 106 else:
121 print("Found port of r%s -> r%s: %s" 107 print("Found port of r%s -> r%s: %s"
122 % (revision, svn_revision, revision_title)) 108 % (revision, svn_revision, revision_title))
123 port_revision_list.append(svn_revision) 109 port_revision_list.append(svn_revision)
124 110
125 # Do we find any port? 111 # Do we find any port?
126 if len(port_revision_list) > 0: 112 if len(port_revision_list) > 0:
127 if self.Confirm("Automatically add corresponding ports (%s)?" 113 if self.Confirm("Automatically add corresponding ports (%s)?"
128 % ", ".join(port_revision_list)): 114 % ", ".join(port_revision_list)):
129 #: 'y': Add ports to revision list. 115 #: 'y': Add ports to revision list.
130 self["full_revision_list"].extend(port_revision_list) 116 self["full_revision_list"].extend(port_revision_list)
131 117
132 118
133 class FindGitRevisions(Step): 119 class FindGitRevisions(Step):
134 MESSAGE = "Find the git revisions associated with the patches." 120 MESSAGE = "Find the git revisions associated with the patches."
135 121
136 def RunStep(self): 122 def RunStep(self):
137 self["patch_commit_hashes"] = [] 123 self["patch_commit_hashes"] = []
138 for revision in self["full_revision_list"]: 124 for revision in self["full_revision_list"]:
139 next_hash = self.GitSVNFindGitHash(revision, "svn/bleeding_edge") 125 next_hash = self.GitSVNFindGitHash(revision, "svn/bleeding_edge")
140 if not next_hash: 126 if not next_hash: # pragma: no cover
141 self.Die("Cannot determine git hash for r%s" % revision) 127 self.Die("Cannot determine git hash for r%s" % revision)
142 self["patch_commit_hashes"].append(next_hash) 128 self["patch_commit_hashes"].append(next_hash)
143 129
144 # Stringify: [123, 234] -> "r123, r234" 130 # Stringify: [123, 234] -> "r123, r234"
145 self["revision_list"] = ", ".join(map(lambda s: "r%s" % s, 131 self["revision_list"] = ", ".join(map(lambda s: "r%s" % s,
146 self["full_revision_list"])) 132 self["full_revision_list"]))
147 133
148 if not self["revision_list"]: 134 if not self["revision_list"]: # pragma: no cover
149 self.Die("Revision list is empty.") 135 self.Die("Revision list is empty.")
150 136
151 if self._options.revert: 137 if self._options.revert:
152 if not self._options.revert_bleeding_edge: 138 if not self._options.revert_bleeding_edge:
153 self["new_commit_msg"] = ("Rollback of %s in %s branch." 139 self["new_commit_msg"] = ("Rollback of %s in %s branch."
154 % (self["revision_list"], self["merge_to_branch"])) 140 % (self["revision_list"], self["merge_to_branch"]))
155 else: 141 else:
156 self["new_commit_msg"] = "Revert %s." % self["revision_list"] 142 self["new_commit_msg"] = "Revert %s." % self["revision_list"]
157 else: 143 else:
158 self["new_commit_msg"] = ("Merged %s into %s branch." 144 self["new_commit_msg"] = ("Merged %s into %s branch."
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after
239 225
240 class PrepareSVN(Step): 226 class PrepareSVN(Step):
241 MESSAGE = "Determine svn commit revision." 227 MESSAGE = "Determine svn commit revision."
242 228
243 def RunStep(self): 229 def RunStep(self):
244 if self._options.revert_bleeding_edge: 230 if self._options.revert_bleeding_edge:
245 return 231 return
246 self.GitSVNFetch() 232 self.GitSVNFetch()
247 commit_hash = self.GitLog(n=1, format="%H", grep=self["new_commit_msg"], 233 commit_hash = self.GitLog(n=1, format="%H", grep=self["new_commit_msg"],
248 branch="svn/%s" % self["merge_to_branch"]) 234 branch="svn/%s" % self["merge_to_branch"])
249 if not commit_hash: 235 if not commit_hash: # pragma: no cover
250 self.Die("Unable to map git commit to svn revision.") 236 self.Die("Unable to map git commit to svn revision.")
251 self["svn_revision"] = self.GitSVNFindSVNRev(commit_hash) 237 self["svn_revision"] = self.GitSVNFindSVNRev(commit_hash)
252 print "subversion revision number is r%s" % self["svn_revision"] 238 print "subversion revision number is r%s" % self["svn_revision"]
253 239
254 240
255 class TagRevision(Step): 241 class TagRevision(Step):
256 MESSAGE = "Create the tag." 242 MESSAGE = "Create the tag."
257 243
258 def RunStep(self): 244 def RunStep(self):
259 if self._options.revert_bleeding_edge: 245 if self._options.revert_bleeding_edge:
(...skipping 21 matching lines...) Expand all
281 self.CommonCleanup() 267 self.CommonCleanup()
282 if not self._options.revert_bleeding_edge: 268 if not self._options.revert_bleeding_edge:
283 print "*** SUMMARY ***" 269 print "*** SUMMARY ***"
284 print "version: %s" % self["version"] 270 print "version: %s" % self["version"]
285 print "branch: %s" % self["to_url"] 271 print "branch: %s" % self["to_url"]
286 print "svn revision: %s" % self["svn_revision"] 272 print "svn revision: %s" % self["svn_revision"]
287 if self["revision_list"]: 273 if self["revision_list"]:
288 print "patches: %s" % self["revision_list"] 274 print "patches: %s" % self["revision_list"]
289 275
290 276
291 def RunMergeToBranch(config, 277 class MergeToBranch(ScriptsBase):
292 options, 278 def _Description(self):
293 side_effect_handler=DEFAULT_SIDE_EFFECT_HANDLER): 279 return ("Performs the necessary steps to merge revisions from "
294 step_classes = [ 280 "bleeding_edge to other branches, including trunk.")
295 Preparation,
296 CreateBranch,
297 SearchArchitecturePorts,
298 FindGitRevisions,
299 ApplyPatches,
300 PrepareVersion,
301 IncrementVersion,
302 CommitLocal,
303 UploadStep,
304 CommitRepository,
305 PrepareSVN,
306 TagRevision,
307 CleanUp,
308 ]
309 281
310 RunScript(step_classes, config, options, side_effect_handler) 282 def _PrepareOptions(self, parser):
283 group = parser.add_mutually_exclusive_group(required=True)
284 group.add_argument("--branch", help="The branch to merge to.")
285 group.add_argument("-R", "--revert-bleeding-edge",
286 help="Revert specified patches from bleeding edge.",
287 default=False, action="store_true")
288 parser.add_argument("revisions", nargs="*",
289 help="The revisions to merge.")
290 parser.add_argument("-f", "--force",
291 help="Delete sentinel file.",
292 default=False, action="store_true")
293 parser.add_argument("-m", "--message",
294 help="A commit message for the patch.")
295 parser.add_argument("--revert",
296 help="Revert specified patches.",
297 default=False, action="store_true")
298 parser.add_argument("-p", "--patch",
299 help="A patch file to apply as part of the merge.")
300
301 def _ProcessOptions(self, options):
302 # TODO(machenbach): Add a test that covers revert from bleeding_edge
303 if len(options.revisions) < 1:
304 if not options.patch:
305 print "Either a patch file or revision numbers must be specified"
306 return False
307 if not options.message:
308 print "You must specify a merge comment if no patches are specified"
309 return False
310 return True
311
312 def _Steps(self):
313 return [
314 Preparation,
315 CreateBranch,
316 SearchArchitecturePorts,
317 FindGitRevisions,
318 ApplyPatches,
319 PrepareVersion,
320 IncrementVersion,
321 CommitLocal,
322 UploadStep,
323 CommitRepository,
324 PrepareSVN,
325 TagRevision,
326 CleanUp,
327 ]
311 328
312 329
313 def BuildOptions(): 330 if __name__ == "__main__": # pragma: no cover
314 parser = argparse.ArgumentParser( 331 sys.exit(MergeToBranch(CONFIG).Run())
315 description=("Performs the necessary steps to merge revisions from "
316 "bleeding_edge to other branches, including trunk."))
317 group = parser.add_mutually_exclusive_group(required=True)
318 group.add_argument("--branch", help="The branch to merge to.")
319 group.add_argument("-R", "--revert-bleeding-edge",
320 help="Revert specified patches from bleeding edge.",
321 default=False, action="store_true")
322 parser.add_argument("revisions", nargs="*",
323 help="The revisions to merge.")
324 parser.add_argument("-a", "--author", default="",
325 help="The author email used for rietveld.")
326 parser.add_argument("-f",
327 help="Delete sentinel file.",
328 default=False, action="store_true")
329 parser.add_argument("-m", "--message",
330 help="A commit message for the patch.")
331 parser.add_argument("-r", "--revert",
332 help="Revert specified patches.",
333 default=False, action="store_true")
334 parser.add_argument("-p", "--patch", dest="p",
335 help="A patch file to apply as part of the merge.")
336 parser.add_argument("-s", "--step",
337 help="The step where to start work. Default: 0.",
338 default=0, type=int)
339 return parser
340
341
342 def ProcessOptions(options):
343 # TODO(machenbach): Add a test that covers revert from bleeding_edge
344 if len(options.revisions) < 1:
345 if not options.patch:
346 print "Either a patch file or revision numbers must be specified"
347 return False
348 if not options.message:
349 print "You must specify a merge comment if no patches are specified"
350 return False
351 return True
352
353
354 def Main():
355 parser = BuildOptions()
356 options = parser.parse_args()
357 if not ProcessOptions(options):
358 parser.print_help()
359 return 1
360 RunMergeToBranch(CONFIG, MergeToBranchOptions(options))
361
362 if __name__ == "__main__":
363 sys.exit(Main())
OLDNEW
« no previous file with comments | « tools/push-to-trunk/git_recipes.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