2 # Copyright 2014 the V8 project authors. All rights reserved.
3 # Redistribution and use in source and binary forms, with or without
4 # modification, are permitted provided that the following conditions are
7 # * Redistributions of source code must retain the above copyright
8 # notice, this list of conditions and the following disclaimer.
9 # * Redistributions in binary form must reproduce the above
10 # copyright notice, this list of conditions and the following
11 # disclaimer in the documentation and/or other materials provided
12 # with the distribution.
13 # * Neither the name of Google Inc. nor the names of its
14 # contributors may be used to endorse or promote products derived
15 # from this software without specific prior written permission.
17 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18 # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
19 # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
20 # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
21 # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
22 # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
23 # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24 # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25 # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
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.
32 class GitFailedException(Exception):
37 def new_f(*args, **kwargs):
38 return f(*args, **kwargs).strip()
43 """['-a', '', 'abc', ''] -> '-a abc'"""
44 return " ".join(filter(None, l))
51 class GitRecipesMixin(object):
52 def GitIsWorkdirClean(self):
53 return self.Git("status -s -uno").strip() == ""
57 return self.Git("branch")
59 def GitCreateBranch(self, name, branch=""):
61 self.Git(MakeArgs(["checkout -b", name, branch]))
63 def GitDeleteBranch(self, name):
65 self.Git(MakeArgs(["branch -D", name]))
67 def GitReset(self, name):
69 self.Git(MakeArgs(["reset --hard", name]))
72 return map(str.strip, self.Git(MakeArgs(["branch -r"])).splitlines())
74 def GitCheckout(self, name):
76 self.Git(MakeArgs(["checkout -f", name]))
78 def GitCheckoutFile(self, name, branch_or_hash):
81 self.Git(MakeArgs(["checkout -f", branch_or_hash, "--", name]))
83 def GitCheckoutFileSafe(self, name, branch_or_hash):
85 self.GitCheckoutFile(name, branch_or_hash)
86 except GitFailedException: # pragma: no cover
87 # The file doesn't exist in that revision.
91 def GitChangedFiles(self, git_hash):
94 files = self.Git(MakeArgs(["diff --name-only",
97 return map(str.strip, files.splitlines())
98 except GitFailedException: # pragma: no cover
99 # Git fails using "^" at branch roots.
104 def GitCurrentBranch(self):
105 for line in self.Git("status -s -b -uno").strip().splitlines():
106 match = re.match(r"^## (.+)", line)
107 if match: return match.group(1)
108 raise Exception("Couldn't find curent branch.") # pragma: no cover
111 def GitLog(self, n=0, format="", grep="", git_hash="", parent_hash="",
112 branch="", reverse=False):
113 assert not (git_hash and parent_hash)
116 args.append("-%d" % n)
118 args.append("--format=%s" % format)
120 args.append("--grep=\"%s\"" % grep.replace("\"", "\\\""))
122 args.append("--reverse")
124 args.append(git_hash)
126 args.append("%s^" % parent_hash)
128 return self.Git(MakeArgs(args))
130 def GitGetPatch(self, git_hash):
132 return self.Git(MakeArgs(["log", "-1", "-p", git_hash]))
134 # TODO(machenbach): Unused? Remove.
135 def GitAdd(self, name):
137 self.Git(MakeArgs(["add", Quoted(name)]))
139 def GitApplyPatch(self, patch_file, reverse=False):
141 args = ["apply --index --reject"]
143 args.append("--reverse")
144 args.append(Quoted(patch_file))
145 self.Git(MakeArgs(args))
147 def GitUpload(self, reviewer="", author="", force=False):
148 args = ["cl upload --send-mail"]
150 args += ["--email", Quoted(author)]
152 args += ["-r", Quoted(reviewer)]
155 # TODO(machenbach): Check output in forced mode. Verify that all required
156 # base files were uploaded, if not retry.
157 self.Git(MakeArgs(args), pipe=False)
159 def GitCommit(self, message="", file_name=""):
160 assert message or file_name
163 args += ["-aF", Quoted(file_name)]
165 args += ["-am", Quoted(message)]
166 self.Git(MakeArgs(args))
168 def GitPresubmit(self):
169 self.Git("cl presubmit", "PRESUBMIT_TREE_CHECK=\"skip\"")
171 def GitDCommit(self):
172 self.Git("cl dcommit -f --bypass-hooks", retry_on=lambda x: x is None)
174 def GitDiff(self, loc1, loc2):
175 return self.Git(MakeArgs(["diff", loc1, loc2]))
180 def GitSVNFetch(self):
181 self.Git("svn fetch")
183 # TODO(machenbach): Unused? Remove.
186 return self.Git("svn log -1 --oneline")
189 def GitSVNFindGitHash(self, revision, branch=""):
191 return self.Git(MakeArgs(["svn find-rev", "r%s" % revision, branch]))
194 def GitSVNFindSVNRev(self, git_hash, branch=""):
195 return self.Git(MakeArgs(["svn find-rev", git_hash, branch]))
197 def GitSVNDCommit(self):
198 return self.Git("svn dcommit 2>&1", retry_on=lambda x: x is None)
200 def GitSVNTag(self, version):
201 self.Git(("svn tag %s -m \"Tagging version %s\"" % (version, version)),
202 retry_on=lambda x: x is None)