| OLD | NEW |
| 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 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 87 def MakeArgs(l): | 87 def MakeArgs(l): |
| 88 """['-a', '', 'abc', ''] -> '-a abc'""" | 88 """['-a', '', 'abc', ''] -> '-a abc'""" |
| 89 return " ".join(filter(None, l)) | 89 return " ".join(filter(None, l)) |
| 90 | 90 |
| 91 | 91 |
| 92 def Quoted(s): | 92 def Quoted(s): |
| 93 return "\"%s\"" % s | 93 return "\"%s\"" % s |
| 94 | 94 |
| 95 | 95 |
| 96 class GitRecipesMixin(object): | 96 class GitRecipesMixin(object): |
| 97 def GitIsWorkdirClean(self): | 97 def GitIsWorkdirClean(self, **kwargs): |
| 98 return self.Git("status -s -uno").strip() == "" | 98 return self.Git("status -s -uno", **kwargs).strip() == "" |
| 99 | 99 |
| 100 @Strip | 100 @Strip |
| 101 def GitBranch(self): | 101 def GitBranch(self, **kwargs): |
| 102 return self.Git("branch") | 102 return self.Git("branch", **kwargs) |
| 103 | 103 |
| 104 def GitCreateBranch(self, name, branch=""): | 104 def GitCreateBranch(self, name, branch="", **kwargs): |
| 105 assert name | 105 assert name |
| 106 self.Git(MakeArgs(["checkout -b", name, branch])) | 106 self.Git(MakeArgs(["checkout -b", name, branch]), **kwargs) |
| 107 | 107 |
| 108 def GitDeleteBranch(self, name): | 108 def GitDeleteBranch(self, name, **kwargs): |
| 109 assert name | 109 assert name |
| 110 self.Git(MakeArgs(["branch -D", name])) | 110 self.Git(MakeArgs(["branch -D", name]), **kwargs) |
| 111 | 111 |
| 112 def GitReset(self, name): | 112 def GitReset(self, name, **kwargs): |
| 113 assert name | 113 assert name |
| 114 self.Git(MakeArgs(["reset --hard", name])) | 114 self.Git(MakeArgs(["reset --hard", name]), **kwargs) |
| 115 | 115 |
| 116 def GitStash(self): | 116 def GitStash(self, **kwargs): |
| 117 self.Git(MakeArgs(["stash"])) | 117 self.Git(MakeArgs(["stash"]), **kwargs) |
| 118 | 118 |
| 119 def GitRemotes(self): | 119 def GitRemotes(self, **kwargs): |
| 120 return map(str.strip, self.Git(MakeArgs(["branch -r"])).splitlines()) | 120 return map(str.strip, |
| 121 self.Git(MakeArgs(["branch -r"]), **kwargs).splitlines()) |
| 121 | 122 |
| 122 def GitCheckout(self, name): | 123 def GitCheckout(self, name, **kwargs): |
| 123 assert name | 124 assert name |
| 124 self.Git(MakeArgs(["checkout -f", name])) | 125 self.Git(MakeArgs(["checkout -f", name]), **kwargs) |
| 125 | 126 |
| 126 def GitCheckoutFile(self, name, branch_or_hash): | 127 def GitCheckoutFile(self, name, branch_or_hash, **kwargs): |
| 127 assert name | 128 assert name |
| 128 assert branch_or_hash | 129 assert branch_or_hash |
| 129 self.Git(MakeArgs(["checkout -f", branch_or_hash, "--", name])) | 130 self.Git(MakeArgs(["checkout -f", branch_or_hash, "--", name]), **kwargs) |
| 130 | 131 |
| 131 def GitCheckoutFileSafe(self, name, branch_or_hash): | 132 def GitCheckoutFileSafe(self, name, branch_or_hash, **kwargs): |
| 132 try: | 133 try: |
| 133 self.GitCheckoutFile(name, branch_or_hash) | 134 self.GitCheckoutFile(name, branch_or_hash, **kwargs) |
| 134 except GitFailedException: # pragma: no cover | 135 except GitFailedException: # pragma: no cover |
| 135 # The file doesn't exist in that revision. | 136 # The file doesn't exist in that revision. |
| 136 return False | 137 return False |
| 137 return True | 138 return True |
| 138 | 139 |
| 139 def GitChangedFiles(self, git_hash): | 140 def GitChangedFiles(self, git_hash, **kwargs): |
| 140 assert git_hash | 141 assert git_hash |
| 141 try: | 142 try: |
| 142 files = self.Git(MakeArgs(["diff --name-only", | 143 files = self.Git(MakeArgs(["diff --name-only", |
| 143 git_hash, | 144 git_hash, |
| 144 "%s^" % git_hash])) | 145 "%s^" % git_hash]), **kwargs) |
| 145 return map(str.strip, files.splitlines()) | 146 return map(str.strip, files.splitlines()) |
| 146 except GitFailedException: # pragma: no cover | 147 except GitFailedException: # pragma: no cover |
| 147 # Git fails using "^" at branch roots. | 148 # Git fails using "^" at branch roots. |
| 148 return [] | 149 return [] |
| 149 | 150 |
| 150 | 151 |
| 151 @Strip | 152 @Strip |
| 152 def GitCurrentBranch(self): | 153 def GitCurrentBranch(self, **kwargs): |
| 153 for line in self.Git("status -s -b -uno").strip().splitlines(): | 154 for line in self.Git("status -s -b -uno", **kwargs).strip().splitlines(): |
| 154 match = re.match(r"^## (.+)", line) | 155 match = re.match(r"^## (.+)", line) |
| 155 if match: return match.group(1) | 156 if match: return match.group(1) |
| 156 raise Exception("Couldn't find curent branch.") # pragma: no cover | 157 raise Exception("Couldn't find curent branch.") # pragma: no cover |
| 157 | 158 |
| 158 @Strip | 159 @Strip |
| 159 def GitLog(self, n=0, format="", grep="", git_hash="", parent_hash="", | 160 def GitLog(self, n=0, format="", grep="", git_hash="", parent_hash="", |
| 160 branch="", reverse=False): | 161 branch="", reverse=False, **kwargs): |
| 161 assert not (git_hash and parent_hash) | 162 assert not (git_hash and parent_hash) |
| 162 args = ["log"] | 163 args = ["log"] |
| 163 if n > 0: | 164 if n > 0: |
| 164 args.append("-%d" % n) | 165 args.append("-%d" % n) |
| 165 if format: | 166 if format: |
| 166 args.append("--format=%s" % format) | 167 args.append("--format=%s" % format) |
| 167 if grep: | 168 if grep: |
| 168 args.append("--grep=\"%s\"" % grep.replace("\"", "\\\"")) | 169 args.append("--grep=\"%s\"" % grep.replace("\"", "\\\"")) |
| 169 if reverse: | 170 if reverse: |
| 170 args.append("--reverse") | 171 args.append("--reverse") |
| 171 if git_hash: | 172 if git_hash: |
| 172 args.append(git_hash) | 173 args.append(git_hash) |
| 173 if parent_hash: | 174 if parent_hash: |
| 174 args.append("%s^" % parent_hash) | 175 args.append("%s^" % parent_hash) |
| 175 args.append(branch) | 176 args.append(branch) |
| 176 return self.Git(MakeArgs(args)) | 177 return self.Git(MakeArgs(args), **kwargs) |
| 177 | 178 |
| 178 def GitGetPatch(self, git_hash): | 179 def GitGetPatch(self, git_hash, **kwargs): |
| 179 assert git_hash | 180 assert git_hash |
| 180 return self.Git(MakeArgs(["log", "-1", "-p", git_hash])) | 181 return self.Git(MakeArgs(["log", "-1", "-p", git_hash]), **kwargs) |
| 181 | 182 |
| 182 # TODO(machenbach): Unused? Remove. | 183 # TODO(machenbach): Unused? Remove. |
| 183 def GitAdd(self, name): | 184 def GitAdd(self, name, **kwargs): |
| 184 assert name | 185 assert name |
| 185 self.Git(MakeArgs(["add", Quoted(name)])) | 186 self.Git(MakeArgs(["add", Quoted(name)]), **kwargs) |
| 186 | 187 |
| 187 def GitApplyPatch(self, patch_file, reverse=False): | 188 def GitApplyPatch(self, patch_file, reverse=False, **kwargs): |
| 188 assert patch_file | 189 assert patch_file |
| 189 args = ["apply --index --reject"] | 190 args = ["apply --index --reject"] |
| 190 if reverse: | 191 if reverse: |
| 191 args.append("--reverse") | 192 args.append("--reverse") |
| 192 args.append(Quoted(patch_file)) | 193 args.append(Quoted(patch_file)) |
| 193 self.Git(MakeArgs(args)) | 194 self.Git(MakeArgs(args), **kwargs) |
| 194 | 195 |
| 195 def GitUpload(self, reviewer="", author="", force=False, cq=False, | 196 def GitUpload(self, reviewer="", author="", force=False, cq=False, |
| 196 bypass_hooks=False): | 197 bypass_hooks=False, **kwargs): |
| 197 args = ["cl upload --send-mail"] | 198 args = ["cl upload --send-mail"] |
| 198 if author: | 199 if author: |
| 199 args += ["--email", Quoted(author)] | 200 args += ["--email", Quoted(author)] |
| 200 if reviewer: | 201 if reviewer: |
| 201 args += ["-r", Quoted(reviewer)] | 202 args += ["-r", Quoted(reviewer)] |
| 202 if force: | 203 if force: |
| 203 args.append("-f") | 204 args.append("-f") |
| 204 if cq: | 205 if cq: |
| 205 args.append("--use-commit-queue") | 206 args.append("--use-commit-queue") |
| 206 if bypass_hooks: | 207 if bypass_hooks: |
| 207 args.append("--bypass-hooks") | 208 args.append("--bypass-hooks") |
| 208 # TODO(machenbach): Check output in forced mode. Verify that all required | 209 # TODO(machenbach): Check output in forced mode. Verify that all required |
| 209 # base files were uploaded, if not retry. | 210 # base files were uploaded, if not retry. |
| 210 self.Git(MakeArgs(args), pipe=False) | 211 self.Git(MakeArgs(args), pipe=False, **kwargs) |
| 211 | 212 |
| 212 def GitCommit(self, message="", file_name="", author=None): | 213 def GitCommit(self, message="", file_name="", author=None, **kwargs): |
| 213 assert message or file_name | 214 assert message or file_name |
| 214 args = ["commit"] | 215 args = ["commit"] |
| 215 if file_name: | 216 if file_name: |
| 216 args += ["-aF", Quoted(file_name)] | 217 args += ["-aF", Quoted(file_name)] |
| 217 if message: | 218 if message: |
| 218 args += ["-am", Quoted(message)] | 219 args += ["-am", Quoted(message)] |
| 219 if author: | 220 if author: |
| 220 args += ["--author", "\"%s <%s>\"" % (author, author)] | 221 args += ["--author", "\"%s <%s>\"" % (author, author)] |
| 221 self.Git(MakeArgs(args)) | 222 self.Git(MakeArgs(args), **kwargs) |
| 222 | 223 |
| 223 def GitPresubmit(self): | 224 def GitPresubmit(self, **kwargs): |
| 224 self.Git("cl presubmit", "PRESUBMIT_TREE_CHECK=\"skip\"") | 225 self.Git("cl presubmit", "PRESUBMIT_TREE_CHECK=\"skip\"", **kwargs) |
| 225 | 226 |
| 226 def GitDCommit(self): | 227 def GitDCommit(self, **kwargs): |
| 227 self.Git("cl dcommit -f --bypass-hooks", retry_on=lambda x: x is None) | 228 self.Git( |
| 229 "cl dcommit -f --bypass-hooks", retry_on=lambda x: x is None, **kwargs) |
| 228 | 230 |
| 229 def GitDiff(self, loc1, loc2): | 231 def GitDiff(self, loc1, loc2, **kwargs): |
| 230 return self.Git(MakeArgs(["diff", loc1, loc2])) | 232 return self.Git(MakeArgs(["diff", loc1, loc2]), **kwargs) |
| 231 | 233 |
| 232 def GitPull(self): | 234 def GitPull(self, **kwargs): |
| 233 self.Git("pull") | 235 self.Git("pull", **kwargs) |
| 234 | 236 |
| 235 def GitFetchOrigin(self): | 237 def GitFetchOrigin(self, **kwargs): |
| 236 self.Git("fetch origin") | 238 self.Git("fetch origin", **kwargs) |
| 237 | 239 |
| 238 def GitConvertToSVNRevision(self, git_hash): | 240 def GitConvertToSVNRevision(self, git_hash, **kwargs): |
| 239 result = self.Git(MakeArgs(["rev-list", "-n", "1", git_hash])) | 241 result = self.Git(MakeArgs(["rev-list", "-n", "1", git_hash]), **kwargs) |
| 240 if not result or not SHA1_RE.match(result): | 242 if not result or not SHA1_RE.match(result): |
| 241 raise GitFailedException("Git hash %s is unknown." % git_hash) | 243 raise GitFailedException("Git hash %s is unknown." % git_hash) |
| 242 log = self.GitLog(n=1, format="%B", git_hash=git_hash) | 244 log = self.GitLog(n=1, format="%B", git_hash=git_hash, **kwargs) |
| 243 for line in reversed(log.splitlines()): | 245 for line in reversed(log.splitlines()): |
| 244 match = ROLL_DEPS_GIT_SVN_ID_RE.match(line.strip()) | 246 match = ROLL_DEPS_GIT_SVN_ID_RE.match(line.strip()) |
| 245 if match: | 247 if match: |
| 246 return match.group(1) | 248 return match.group(1) |
| 247 raise GitFailedException("Couldn't convert %s to SVN." % git_hash) | 249 raise GitFailedException("Couldn't convert %s to SVN." % git_hash) |
| 248 | 250 |
| 249 @Strip | 251 @Strip |
| 250 # Copied from bot_update.py and modified for svn-like numbers only. | 252 # Copied from bot_update.py and modified for svn-like numbers only. |
| 251 def GetCommitPositionNumber(self, git_hash): | 253 def GetCommitPositionNumber(self, git_hash, **kwargs): |
| 252 """Dumps the 'git' log for a specific revision and parses out the commit | 254 """Dumps the 'git' log for a specific revision and parses out the commit |
| 253 position number. | 255 position number. |
| 254 | 256 |
| 255 If a commit position metadata key is found, its number will be returned. | 257 If a commit position metadata key is found, its number will be returned. |
| 256 | 258 |
| 257 Otherwise, we will search for a 'git-svn' metadata entry. If one is found, | 259 Otherwise, we will search for a 'git-svn' metadata entry. If one is found, |
| 258 its SVN revision value is returned. | 260 its SVN revision value is returned. |
| 259 """ | 261 """ |
| 260 git_log = self.GitLog(format='%B', n=1, git_hash=git_hash) | 262 git_log = self.GitLog(format='%B', n=1, git_hash=git_hash, **kwargs) |
| 261 footer_map = GetCommitMessageFooterMap(git_log) | 263 footer_map = GetCommitMessageFooterMap(git_log) |
| 262 | 264 |
| 263 # Search for commit position metadata | 265 # Search for commit position metadata |
| 264 value = footer_map.get(COMMIT_POSITION_FOOTER_KEY) | 266 value = footer_map.get(COMMIT_POSITION_FOOTER_KEY) |
| 265 if value: | 267 if value: |
| 266 match = COMMIT_POSITION_RE.match(value) | 268 match = COMMIT_POSITION_RE.match(value) |
| 267 if match: | 269 if match: |
| 268 return match.group(2) | 270 return match.group(2) |
| 269 | 271 |
| 270 # Extract the svn revision from 'git-svn' metadata | 272 # Extract the svn revision from 'git-svn' metadata |
| 271 value = footer_map.get(GIT_SVN_ID_FOOTER_KEY) | 273 value = footer_map.get(GIT_SVN_ID_FOOTER_KEY) |
| 272 if value: | 274 if value: |
| 273 match = GIT_SVN_ID_RE.match(value) | 275 match = GIT_SVN_ID_RE.match(value) |
| 274 if match: | 276 if match: |
| 275 return match.group(2) | 277 return match.group(2) |
| 276 return None | 278 return None |
| 277 | 279 |
| 278 ### Git svn stuff | 280 ### Git svn stuff |
| 279 | 281 |
| 280 def GitSVNFetch(self): | 282 def GitSVNFetch(self, **kwargs): |
| 281 self.Git("svn fetch") | 283 self.Git("svn fetch", **kwargs) |
| 282 | 284 |
| 283 def GitSVNRebase(self): | 285 def GitSVNRebase(self, **kwargs): |
| 284 self.Git("svn rebase") | 286 self.Git("svn rebase", **kwargs) |
| 285 | 287 |
| 286 # TODO(machenbach): Unused? Remove. | 288 # TODO(machenbach): Unused? Remove. |
| 287 @Strip | 289 @Strip |
| 288 def GitSVNLog(self): | 290 def GitSVNLog(self, **kwargs): |
| 289 return self.Git("svn log -1 --oneline") | 291 return self.Git("svn log -1 --oneline", **kwargs) |
| 290 | 292 |
| 291 @Strip | 293 @Strip |
| 292 def GitSVNFindGitHash(self, revision, branch=""): | 294 def GitSVNFindGitHash(self, revision, branch="", **kwargs): |
| 293 assert revision | 295 assert revision |
| 294 return self.Git(MakeArgs(["svn find-rev", "r%s" % revision, branch])) | 296 return self.Git( |
| 297 MakeArgs(["svn find-rev", "r%s" % revision, branch]), **kwargs) |
| 295 | 298 |
| 296 @Strip | 299 @Strip |
| 297 def GitSVNFindSVNRev(self, git_hash, branch=""): | 300 def GitSVNFindSVNRev(self, git_hash, branch="", **kwargs): |
| 298 return self.Git(MakeArgs(["svn find-rev", git_hash, branch])) | 301 return self.Git(MakeArgs(["svn find-rev", git_hash, branch]), **kwargs) |
| 299 | 302 |
| 300 def GitSVNDCommit(self): | 303 def GitSVNDCommit(self, **kwargs): |
| 301 return self.Git("svn dcommit 2>&1", retry_on=lambda x: x is None) | 304 return self.Git("svn dcommit 2>&1", retry_on=lambda x: x is None, **kwargs) |
| 302 | 305 |
| 303 def GitSVNTag(self, version): | 306 def GitSVNTag(self, version, **kwargs): |
| 304 self.Git(("svn tag %s -m \"Tagging version %s\"" % (version, version)), | 307 self.Git(("svn tag %s -m \"Tagging version %s\"" % (version, version)), |
| 305 retry_on=lambda x: x is None) | 308 retry_on=lambda x: x is None, |
| 309 **kwargs) |
| OLD | NEW |