1f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org#!/usr/bin/env python 2f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org# Copyright 2014 the V8 project authors. All rights reserved. 3f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org# Redistribution and use in source and binary forms, with or without 4f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org# modification, are permitted provided that the following conditions are 5f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org# met: 6f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org# 7f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org# * Redistributions of source code must retain the above copyright 8f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org# notice, this list of conditions and the following disclaimer. 9f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org# * Redistributions in binary form must reproduce the above 10f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org# copyright notice, this list of conditions and the following 11f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org# disclaimer in the documentation and/or other materials provided 12f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org# with the distribution. 13f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org# * Neither the name of Google Inc. nor the names of its 14f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org# contributors may be used to endorse or promote products derived 15f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org# from this software without specific prior written permission. 16f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org# 17f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 18f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 19f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 20f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 21f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 22f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 23f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 24f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 25f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 27f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org 29f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.orgimport re 30f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org 316474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.orgSHA1_RE = re.compile('^[a-fA-F0-9]{40}$') 329aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.orgROLL_DEPS_GIT_SVN_ID_RE = re.compile('^git-svn-id: .*@([0-9]+) .*$') 339aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org 349aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org# Regular expression that matches a single commit footer line. 359aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.orgCOMMIT_FOOTER_ENTRY_RE = re.compile(r'([^:]+):\s+(.+)') 369aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org 379aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org# Footer metadata key for commit position. 389aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.orgCOMMIT_POSITION_FOOTER_KEY = 'Cr-Commit-Position' 399aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org 409aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org# Regular expression to parse a commit position 419aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.orgCOMMIT_POSITION_RE = re.compile(r'(.+)@\{#(\d+)\}') 429aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org 439aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org# Key for the 'git-svn' ID metadata commit footer entry. 449aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.orgGIT_SVN_ID_FOOTER_KEY = 'git-svn-id' 459aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org 469aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org# e.g., git-svn-id: https://v8.googlecode.com/svn/trunk@23117 479aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org# ce2b1a6d-e550-0410-aec6-3dcde31c8c00 489aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.orgGIT_SVN_ID_RE = re.compile(r'((?:\w+)://[^@]+)@(\d+)\s+(?:[a-zA-Z0-9\-]+)') 499aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org 509aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org 519aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org# Copied from bot_update.py. 529aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.orgdef GetCommitMessageFooterMap(message): 539aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org """Returns: (dict) A dictionary of commit message footer entries. 549aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org """ 559aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org footers = {} 569aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org 579aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org # Extract the lines in the footer block. 589aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org lines = [] 599aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org for line in message.strip().splitlines(): 609aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org line = line.strip() 619aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org if len(line) == 0: 629aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org del(lines[:]) 639aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org continue 649aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org lines.append(line) 659aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org 669aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org # Parse the footer 679aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org for line in lines: 689aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org m = COMMIT_FOOTER_ENTRY_RE.match(line) 699aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org if not m: 709aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org # If any single line isn't valid, the entire footer is invalid. 719aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org footers.clear() 729aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org return footers 739aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org footers[m.group(1)] = m.group(2).strip() 749aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org return footers 756474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org 765b080567cf135f6dbaf23973ba6b6fa1d6af83b3machenbach@chromium.org 775b080567cf135f6dbaf23973ba6b6fa1d6af83b3machenbach@chromium.orgclass GitFailedException(Exception): 785b080567cf135f6dbaf23973ba6b6fa1d6af83b3machenbach@chromium.org pass 795b080567cf135f6dbaf23973ba6b6fa1d6af83b3machenbach@chromium.org 805b080567cf135f6dbaf23973ba6b6fa1d6af83b3machenbach@chromium.org 81f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.orgdef Strip(f): 82f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org def new_f(*args, **kwargs): 83f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org return f(*args, **kwargs).strip() 84f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org return new_f 85f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org 86f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org 87f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.orgdef MakeArgs(l): 88f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org """['-a', '', 'abc', ''] -> '-a abc'""" 89f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org return " ".join(filter(None, l)) 90f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org 91f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org 92f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.orgdef Quoted(s): 93f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org return "\"%s\"" % s 94f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org 95f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org 96f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.orgclass GitRecipesMixin(object): 9742ed2fc449e83fab2ccbf1b769a5e83715c9d783machenbach@chromium.org def GitIsWorkdirClean(self, **kwargs): 9842ed2fc449e83fab2ccbf1b769a5e83715c9d783machenbach@chromium.org return self.Git("status -s -uno", **kwargs).strip() == "" 99f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org 100f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org @Strip 10142ed2fc449e83fab2ccbf1b769a5e83715c9d783machenbach@chromium.org def GitBranch(self, **kwargs): 10242ed2fc449e83fab2ccbf1b769a5e83715c9d783machenbach@chromium.org return self.Git("branch", **kwargs) 103f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org 10442ed2fc449e83fab2ccbf1b769a5e83715c9d783machenbach@chromium.org def GitCreateBranch(self, name, branch="", **kwargs): 105f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org assert name 10642ed2fc449e83fab2ccbf1b769a5e83715c9d783machenbach@chromium.org self.Git(MakeArgs(["checkout -b", name, branch]), **kwargs) 107f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org 10842ed2fc449e83fab2ccbf1b769a5e83715c9d783machenbach@chromium.org def GitDeleteBranch(self, name, **kwargs): 109f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org assert name 11042ed2fc449e83fab2ccbf1b769a5e83715c9d783machenbach@chromium.org self.Git(MakeArgs(["branch -D", name]), **kwargs) 111f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org 11242ed2fc449e83fab2ccbf1b769a5e83715c9d783machenbach@chromium.org def GitReset(self, name, **kwargs): 1135b080567cf135f6dbaf23973ba6b6fa1d6af83b3machenbach@chromium.org assert name 11442ed2fc449e83fab2ccbf1b769a5e83715c9d783machenbach@chromium.org self.Git(MakeArgs(["reset --hard", name]), **kwargs) 1155b080567cf135f6dbaf23973ba6b6fa1d6af83b3machenbach@chromium.org 11642ed2fc449e83fab2ccbf1b769a5e83715c9d783machenbach@chromium.org def GitStash(self, **kwargs): 11742ed2fc449e83fab2ccbf1b769a5e83715c9d783machenbach@chromium.org self.Git(MakeArgs(["stash"]), **kwargs) 1184c3ce7c3fd2802da8f91c6516a9c9aea3cd93f1emachenbach@chromium.org 11942ed2fc449e83fab2ccbf1b769a5e83715c9d783machenbach@chromium.org def GitRemotes(self, **kwargs): 12042ed2fc449e83fab2ccbf1b769a5e83715c9d783machenbach@chromium.org return map(str.strip, 12142ed2fc449e83fab2ccbf1b769a5e83715c9d783machenbach@chromium.org self.Git(MakeArgs(["branch -r"]), **kwargs).splitlines()) 1225b080567cf135f6dbaf23973ba6b6fa1d6af83b3machenbach@chromium.org 12342ed2fc449e83fab2ccbf1b769a5e83715c9d783machenbach@chromium.org def GitCheckout(self, name, **kwargs): 124f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org assert name 12542ed2fc449e83fab2ccbf1b769a5e83715c9d783machenbach@chromium.org self.Git(MakeArgs(["checkout -f", name]), **kwargs) 126f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org 12742ed2fc449e83fab2ccbf1b769a5e83715c9d783machenbach@chromium.org def GitCheckoutFile(self, name, branch_or_hash, **kwargs): 12800a4ad70bb8883074ba7630edd7140762bcb86a0machenbach@chromium.org assert name 1295697144afb43181fed170b81c194fe1cc0fce3b6machenbach@chromium.org assert branch_or_hash 13042ed2fc449e83fab2ccbf1b769a5e83715c9d783machenbach@chromium.org self.Git(MakeArgs(["checkout -f", branch_or_hash, "--", name]), **kwargs) 13100a4ad70bb8883074ba7630edd7140762bcb86a0machenbach@chromium.org 13242ed2fc449e83fab2ccbf1b769a5e83715c9d783machenbach@chromium.org def GitCheckoutFileSafe(self, name, branch_or_hash, **kwargs): 1335b080567cf135f6dbaf23973ba6b6fa1d6af83b3machenbach@chromium.org try: 13442ed2fc449e83fab2ccbf1b769a5e83715c9d783machenbach@chromium.org self.GitCheckoutFile(name, branch_or_hash, **kwargs) 1355b080567cf135f6dbaf23973ba6b6fa1d6af83b3machenbach@chromium.org except GitFailedException: # pragma: no cover 1365b080567cf135f6dbaf23973ba6b6fa1d6af83b3machenbach@chromium.org # The file doesn't exist in that revision. 1375b080567cf135f6dbaf23973ba6b6fa1d6af83b3machenbach@chromium.org return False 1385b080567cf135f6dbaf23973ba6b6fa1d6af83b3machenbach@chromium.org return True 1395b080567cf135f6dbaf23973ba6b6fa1d6af83b3machenbach@chromium.org 14042ed2fc449e83fab2ccbf1b769a5e83715c9d783machenbach@chromium.org def GitChangedFiles(self, git_hash, **kwargs): 1415b080567cf135f6dbaf23973ba6b6fa1d6af83b3machenbach@chromium.org assert git_hash 1425b080567cf135f6dbaf23973ba6b6fa1d6af83b3machenbach@chromium.org try: 1435b080567cf135f6dbaf23973ba6b6fa1d6af83b3machenbach@chromium.org files = self.Git(MakeArgs(["diff --name-only", 1445b080567cf135f6dbaf23973ba6b6fa1d6af83b3machenbach@chromium.org git_hash, 14542ed2fc449e83fab2ccbf1b769a5e83715c9d783machenbach@chromium.org "%s^" % git_hash]), **kwargs) 1465b080567cf135f6dbaf23973ba6b6fa1d6af83b3machenbach@chromium.org return map(str.strip, files.splitlines()) 1475b080567cf135f6dbaf23973ba6b6fa1d6af83b3machenbach@chromium.org except GitFailedException: # pragma: no cover 1485b080567cf135f6dbaf23973ba6b6fa1d6af83b3machenbach@chromium.org # Git fails using "^" at branch roots. 1495b080567cf135f6dbaf23973ba6b6fa1d6af83b3machenbach@chromium.org return [] 1505b080567cf135f6dbaf23973ba6b6fa1d6af83b3machenbach@chromium.org 1515b080567cf135f6dbaf23973ba6b6fa1d6af83b3machenbach@chromium.org 152f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org @Strip 15342ed2fc449e83fab2ccbf1b769a5e83715c9d783machenbach@chromium.org def GitCurrentBranch(self, **kwargs): 15442ed2fc449e83fab2ccbf1b769a5e83715c9d783machenbach@chromium.org for line in self.Git("status -s -b -uno", **kwargs).strip().splitlines(): 155f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org match = re.match(r"^## (.+)", line) 156f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org if match: return match.group(1) 157486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org raise Exception("Couldn't find curent branch.") # pragma: no cover 158f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org 159f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org @Strip 160f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org def GitLog(self, n=0, format="", grep="", git_hash="", parent_hash="", 16142ed2fc449e83fab2ccbf1b769a5e83715c9d783machenbach@chromium.org branch="", reverse=False, **kwargs): 162f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org assert not (git_hash and parent_hash) 163f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org args = ["log"] 164f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org if n > 0: 165f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org args.append("-%d" % n) 166f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org if format: 167f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org args.append("--format=%s" % format) 168f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org if grep: 169255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org args.append("--grep=\"%s\"" % grep.replace("\"", "\\\"")) 170f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org if reverse: 171f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org args.append("--reverse") 172f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org if git_hash: 173f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org args.append(git_hash) 174f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org if parent_hash: 175f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org args.append("%s^" % parent_hash) 176f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org args.append(branch) 17742ed2fc449e83fab2ccbf1b769a5e83715c9d783machenbach@chromium.org return self.Git(MakeArgs(args), **kwargs) 178f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org 17942ed2fc449e83fab2ccbf1b769a5e83715c9d783machenbach@chromium.org def GitGetPatch(self, git_hash, **kwargs): 180f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org assert git_hash 18142ed2fc449e83fab2ccbf1b769a5e83715c9d783machenbach@chromium.org return self.Git(MakeArgs(["log", "-1", "-p", git_hash]), **kwargs) 182f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org 1835b080567cf135f6dbaf23973ba6b6fa1d6af83b3machenbach@chromium.org # TODO(machenbach): Unused? Remove. 18442ed2fc449e83fab2ccbf1b769a5e83715c9d783machenbach@chromium.org def GitAdd(self, name, **kwargs): 185f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org assert name 18642ed2fc449e83fab2ccbf1b769a5e83715c9d783machenbach@chromium.org self.Git(MakeArgs(["add", Quoted(name)]), **kwargs) 187f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org 18842ed2fc449e83fab2ccbf1b769a5e83715c9d783machenbach@chromium.org def GitApplyPatch(self, patch_file, reverse=False, **kwargs): 189f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org assert patch_file 190f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org args = ["apply --index --reject"] 191f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org if reverse: 192f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org args.append("--reverse") 193f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org args.append(Quoted(patch_file)) 19442ed2fc449e83fab2ccbf1b769a5e83715c9d783machenbach@chromium.org self.Git(MakeArgs(args), **kwargs) 195f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org 1969d1a7a8cdb664730cf5703185e85a4716748c564machenbach@chromium.org def GitUpload(self, reviewer="", author="", force=False, cq=False, 19742ed2fc449e83fab2ccbf1b769a5e83715c9d783machenbach@chromium.org bypass_hooks=False, **kwargs): 198f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org args = ["cl upload --send-mail"] 199f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org if author: 200f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org args += ["--email", Quoted(author)] 201f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org if reviewer: 202f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org args += ["-r", Quoted(reviewer)] 203f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org if force: 204f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org args.append("-f") 205c3564d8de4ebfc4fa3dc009fc9f6f18968ffcbd7machenbach@chromium.org if cq: 206c3564d8de4ebfc4fa3dc009fc9f6f18968ffcbd7machenbach@chromium.org args.append("--use-commit-queue") 2079d1a7a8cdb664730cf5703185e85a4716748c564machenbach@chromium.org if bypass_hooks: 2089d1a7a8cdb664730cf5703185e85a4716748c564machenbach@chromium.org args.append("--bypass-hooks") 209f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org # TODO(machenbach): Check output in forced mode. Verify that all required 210f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org # base files were uploaded, if not retry. 21142ed2fc449e83fab2ccbf1b769a5e83715c9d783machenbach@chromium.org self.Git(MakeArgs(args), pipe=False, **kwargs) 212f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org 21342ed2fc449e83fab2ccbf1b769a5e83715c9d783machenbach@chromium.org def GitCommit(self, message="", file_name="", author=None, **kwargs): 214f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org assert message or file_name 215f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org args = ["commit"] 216f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org if file_name: 217f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org args += ["-aF", Quoted(file_name)] 218f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org if message: 219f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org args += ["-am", Quoted(message)] 2209aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org if author: 2219aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org args += ["--author", "\"%s <%s>\"" % (author, author)] 22242ed2fc449e83fab2ccbf1b769a5e83715c9d783machenbach@chromium.org self.Git(MakeArgs(args), **kwargs) 223f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org 22442ed2fc449e83fab2ccbf1b769a5e83715c9d783machenbach@chromium.org def GitPresubmit(self, **kwargs): 22542ed2fc449e83fab2ccbf1b769a5e83715c9d783machenbach@chromium.org self.Git("cl presubmit", "PRESUBMIT_TREE_CHECK=\"skip\"", **kwargs) 226f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org 22742ed2fc449e83fab2ccbf1b769a5e83715c9d783machenbach@chromium.org def GitDCommit(self, **kwargs): 22842ed2fc449e83fab2ccbf1b769a5e83715c9d783machenbach@chromium.org self.Git( 22942ed2fc449e83fab2ccbf1b769a5e83715c9d783machenbach@chromium.org "cl dcommit -f --bypass-hooks", retry_on=lambda x: x is None, **kwargs) 230f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org 23142ed2fc449e83fab2ccbf1b769a5e83715c9d783machenbach@chromium.org def GitDiff(self, loc1, loc2, **kwargs): 23242ed2fc449e83fab2ccbf1b769a5e83715c9d783machenbach@chromium.org return self.Git(MakeArgs(["diff", loc1, loc2]), **kwargs) 233f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org 23442ed2fc449e83fab2ccbf1b769a5e83715c9d783machenbach@chromium.org def GitPull(self, **kwargs): 23542ed2fc449e83fab2ccbf1b769a5e83715c9d783machenbach@chromium.org self.Git("pull", **kwargs) 236f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org 23742ed2fc449e83fab2ccbf1b769a5e83715c9d783machenbach@chromium.org def GitFetchOrigin(self, **kwargs): 23842ed2fc449e83fab2ccbf1b769a5e83715c9d783machenbach@chromium.org self.Git("fetch origin", **kwargs) 2396474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org 24042ed2fc449e83fab2ccbf1b769a5e83715c9d783machenbach@chromium.org def GitConvertToSVNRevision(self, git_hash, **kwargs): 24142ed2fc449e83fab2ccbf1b769a5e83715c9d783machenbach@chromium.org result = self.Git(MakeArgs(["rev-list", "-n", "1", git_hash]), **kwargs) 2426474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org if not result or not SHA1_RE.match(result): 2436474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org raise GitFailedException("Git hash %s is unknown." % git_hash) 24442ed2fc449e83fab2ccbf1b769a5e83715c9d783machenbach@chromium.org log = self.GitLog(n=1, format="%B", git_hash=git_hash, **kwargs) 2456474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org for line in reversed(log.splitlines()): 2469aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org match = ROLL_DEPS_GIT_SVN_ID_RE.match(line.strip()) 2476474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org if match: 2486474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org return match.group(1) 2496474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org raise GitFailedException("Couldn't convert %s to SVN." % git_hash) 2506474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org 2519aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org @Strip 2529aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org # Copied from bot_update.py and modified for svn-like numbers only. 25342ed2fc449e83fab2ccbf1b769a5e83715c9d783machenbach@chromium.org def GetCommitPositionNumber(self, git_hash, **kwargs): 2549aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org """Dumps the 'git' log for a specific revision and parses out the commit 2559aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org position number. 2569aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org 2579aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org If a commit position metadata key is found, its number will be returned. 2589aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org 2599aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org Otherwise, we will search for a 'git-svn' metadata entry. If one is found, 2609aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org its SVN revision value is returned. 2619aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org """ 26242ed2fc449e83fab2ccbf1b769a5e83715c9d783machenbach@chromium.org git_log = self.GitLog(format='%B', n=1, git_hash=git_hash, **kwargs) 2639aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org footer_map = GetCommitMessageFooterMap(git_log) 2649aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org 2659aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org # Search for commit position metadata 2669aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org value = footer_map.get(COMMIT_POSITION_FOOTER_KEY) 2679aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org if value: 2689aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org match = COMMIT_POSITION_RE.match(value) 2699aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org if match: 2709aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org return match.group(2) 2719aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org 2729aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org # Extract the svn revision from 'git-svn' metadata 2739aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org value = footer_map.get(GIT_SVN_ID_FOOTER_KEY) 2749aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org if value: 2759aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org match = GIT_SVN_ID_RE.match(value) 2769aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org if match: 2779aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org return match.group(2) 2789aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org return None 2799aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org 2809aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org ### Git svn stuff 2819aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org 28242ed2fc449e83fab2ccbf1b769a5e83715c9d783machenbach@chromium.org def GitSVNFetch(self, **kwargs): 28342ed2fc449e83fab2ccbf1b769a5e83715c9d783machenbach@chromium.org self.Git("svn fetch", **kwargs) 284f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org 28542ed2fc449e83fab2ccbf1b769a5e83715c9d783machenbach@chromium.org def GitSVNRebase(self, **kwargs): 28642ed2fc449e83fab2ccbf1b769a5e83715c9d783machenbach@chromium.org self.Git("svn rebase", **kwargs) 287474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org 2885b080567cf135f6dbaf23973ba6b6fa1d6af83b3machenbach@chromium.org # TODO(machenbach): Unused? Remove. 289f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org @Strip 29042ed2fc449e83fab2ccbf1b769a5e83715c9d783machenbach@chromium.org def GitSVNLog(self, **kwargs): 29142ed2fc449e83fab2ccbf1b769a5e83715c9d783machenbach@chromium.org return self.Git("svn log -1 --oneline", **kwargs) 292f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org 293f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org @Strip 29442ed2fc449e83fab2ccbf1b769a5e83715c9d783machenbach@chromium.org def GitSVNFindGitHash(self, revision, branch="", **kwargs): 295f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org assert revision 29642ed2fc449e83fab2ccbf1b769a5e83715c9d783machenbach@chromium.org return self.Git( 29742ed2fc449e83fab2ccbf1b769a5e83715c9d783machenbach@chromium.org MakeArgs(["svn find-rev", "r%s" % revision, branch]), **kwargs) 298f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org 299f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org @Strip 30042ed2fc449e83fab2ccbf1b769a5e83715c9d783machenbach@chromium.org def GitSVNFindSVNRev(self, git_hash, branch="", **kwargs): 30142ed2fc449e83fab2ccbf1b769a5e83715c9d783machenbach@chromium.org return self.Git(MakeArgs(["svn find-rev", git_hash, branch]), **kwargs) 302f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org 30342ed2fc449e83fab2ccbf1b769a5e83715c9d783machenbach@chromium.org def GitSVNDCommit(self, **kwargs): 30442ed2fc449e83fab2ccbf1b769a5e83715c9d783machenbach@chromium.org return self.Git("svn dcommit 2>&1", retry_on=lambda x: x is None, **kwargs) 305f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org 30642ed2fc449e83fab2ccbf1b769a5e83715c9d783machenbach@chromium.org def GitSVNTag(self, version, **kwargs): 307f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org self.Git(("svn tag %s -m \"Tagging version %s\"" % (version, version)), 30842ed2fc449e83fab2ccbf1b769a5e83715c9d783machenbach@chromium.org retry_on=lambda x: x is None, 30942ed2fc449e83fab2ccbf1b769a5e83715c9d783machenbach@chromium.org **kwargs) 310