Index: drover.py |
diff --git a/drover.py b/drover.py |
index b147a03c97d9a372c5c787b16d6033557ac7a068..472f3ee07f73f807958e11747d362d1e061bcddd 100644 |
--- a/drover.py |
+++ b/drover.py |
@@ -1,76 +1,77 @@ |
+# Copyright (c) 2009 The Chromium Authors. All rights reserved. |
+# Use of this source code is governed by a BSD-style license that can be |
+# found in the LICENSE file. |
+ |
+import os |
+import re |
import subprocess |
import sys |
-import re |
-import os |
import webbrowser |
+ |
def deltree(root): |
- """ |
- Removes a given directory |
- """ |
+ """Removes a given directory.""" |
if (not os.path.exists(root)): |
return |
- |
+ |
if sys.platform == 'win32': |
os.system('rmdir /S /Q ' + root.replace('/','\\')) |
else: |
for name in os.listdir(root): |
- path = os.path.join(root, name) |
- if os.path.isdir(path): |
- deltree(path) |
- else: |
- os.unlink(path) |
+ path = os.path.join(root, name) |
+ if os.path.isdir(path): |
+ deltree(path) |
+ else: |
+ os.unlink(path) |
os.rmdir(root) |
+ |
def clobberDir(dir): |
- """ |
- Removes a given directory |
- """ |
- |
+ """Removes a given directory.""" |
+ |
if (os.path.exists(dir)): |
- print dir + " directory found, deleting" |
- #The following line was removed due to access controls in Windows |
- #which make os.unlink(path) calls impossible. |
- #deltree(dir) |
- os.system('rmdir /S /Q ' + dir.replace('/','\\')) |
+ print dir + " directory found, deleting" |
+ # The following line was removed due to access controls in Windows |
+ # which make os.unlink(path) calls impossible. |
+ # deltree(dir) |
+ os.system('rmdir /S /Q ' + dir.replace('/','\\')) |
+ |
def gclUpload(revision, author): |
- command = "gcl upload " + str(revision) + " --send_mail --no_try --no_presubmit --reviewers=" + author |
+ command = ("gcl upload " + str(revision) + |
+ " --send_mail --no_try --no_presubmit --reviewers=" + author) |
os.system(command) |
-# subprocess.Popen(command, |
-# shell=True, |
-# stdout=None, |
+# subprocess.Popen(command, |
+# shell=True, |
+# stdout=None, |
# stderr=subprocess.PIPE) |
# stderr=subprocess.PIPE).stdout.readlines() |
# for line in svn_info: |
# match = re.search(r"Issue created. URL: (http://.+)", line) |
# if match: |
-# return match.group(1) |
- |
- return None |
+# return match.group(1) |
+ return None |
+ |
def getAuthor(url, revision): |
command = 'svn info ' + url + "@"+str(revision) |
- svn_info = subprocess.Popen(command, |
- shell=True, |
- stdout=subprocess.PIPE, |
+ svn_info = subprocess.Popen(command, |
+ shell=True, |
+ stdout=subprocess.PIPE, |
stderr=subprocess.PIPE).stdout.readlines() |
for line in svn_info: |
match = re.search(r"Last Changed Author: (.+)", line) |
if match: |
- return match.group(1) |
- |
+ return match.group(1) |
return None |
def getRevisionLog(url, revision): |
- """ |
- Takes an svn url and gets the associated revision. |
- """ |
+ """Takes an svn url and gets the associated revision. """ |
command = 'svn log ' + url + " -r"+str(revision) |
- svn_info = subprocess.Popen(command, |
- shell=True, |
- stdout=subprocess.PIPE, |
+ svn_info = subprocess.Popen(command, |
+ shell=True, |
+ stdout=subprocess.PIPE, |
stderr=subprocess.PIPE).stdout.readlines() |
rtn= "" |
pos = 0 |
@@ -82,117 +83,101 @@ def getRevisionLog(url, revision): |
return rtn |
+ |
def checkoutRevision(url, revision, branch_url): |
paths = getBestMergePaths(url, revision) |
- |
deltree('./src') |
- |
if not os.path.exists('./src'): |
command = 'svn checkout -N ' + branch_url |
print command |
os.system(command) |
- #This line is extremely important due to the way svn behaves in the set-depths |
- #action. If parents aren't handled before children, the child directories get |
- #clobbered and the merge step fails. |
+ # This line is extremely important due to the way svn behaves in the |
+ # set-depths action. If parents aren't handled before children, the child |
+ # directories get clobbered and the merge step fails. |
paths.sort() |
- |
for path in paths: |
- subpaths = path.split('/') |
- subpaths.pop(0) |
- base = './src' |
- for subpath in subpaths: |
- base += '/' + subpath |
- if not os.path.exists(base): |
- command = ('svn update --depth empty ' + base) |
- print command |
- os.system(command) |
- else: |
- print "Found " + base |
- |
- files = getFilesInRevision(url, revision) |
- |
- for file in files: |
- #Prevent the tool from clobbering the src directory |
+ subpaths = path.split('/') |
+ subpaths.pop(0) |
+ base = './src' |
+ for subpath in subpaths: |
+ base += '/' + subpath |
+ if not os.path.exists(base): |
+ command = ('svn update --depth empty ' + base) |
+ print command |
+ os.system(command) |
+ else: |
+ print "Found " + base |
+ |
+ for file in getFilesInRevision(url, revision): |
+ # Prevent the tool from clobbering the src directory. |
if (file == ""): |
continue |
command = ('svn up ./src' + file) |
print command |
os.system(command) |
- |
-#def mergeRevision(url, revision): |
-# command = 'svn merge -r ' + str(revision-1) + ":" + str(revision) + " " + url |
-# print command |
-# os.system(command) |
+ |
def mergeRevision(url, revision, ignoreAncestry=False): |
paths = getBestMergePaths(url, revision) |
for path in paths: |
command = ('svn merge -N -r ' + str(revision-1) + ":" + str(revision) + " ") |
if (ignoreAncestry): |
- command = command + " --ignore-ancestry " |
+ command = command + " --ignore-ancestry " |
command = command + url + path + " ./src" + path |
- |
print command |
os.system(command) |
+ |
def revertRevision(url, revision): |
paths = getBestMergePaths(url, revision) |
for path in paths: |
- command = ('svn merge -N -r ' + str(revision) + ":" + str(revision-1) + " " + |
- url + path + " ./src" + path) |
+ command = ('svn merge -N -r ' + str(revision) + ":" + str(revision-1) + |
+ " " + url + path + " ./src" + path) |
print command |
os.system(command) |
+ |
def getBestMergePaths(url, revision): |
- """ |
- Takes an svn url and gets the associated revision. |
- """ |
+ """Takes an svn url and gets the associated revision.""" |
command = 'svn log ' + url + " -r "+str(revision) + " -v" |
- svn_info = subprocess.Popen(command, |
- shell=True, |
- stdout=subprocess.PIPE, |
+ svn_info = subprocess.Popen(command, |
+ shell=True, |
+ stdout=subprocess.PIPE, |
stderr=subprocess.PIPE).stdout.readlines() |
- map = dict() |
+ map = {} |
for line in svn_info: |
- #match = re.search(r"[\n\r ]+[MADUC][\n\r ]+/.*/src(.*)/.+", line) |
- #match = re.search(r"[\n\r ]+[MADUC][\n\r ]+/(?:trunk|branches/\d+)/src(.*)/.+", line) |
match = re.search(r"[\n\r ]+[MADUC][\n\r ]+/(?:trunk|branches/\d+)/src([^ ]*)/[^ ]+", line) |
- |
if match: |
map[match.group(1)] = match.group(1) |
return map.keys() |
+ |
def getFilesInRevision(url, revision): |
- """ |
- Takes an svn url and gets the associated revision. |
- """ |
+ """Takes an svn url and gets the associated revision.""" |
command = 'svn log ' + url + " -r "+str(revision) + " -v" |
- svn_info = subprocess.Popen(command, |
- shell=True, |
- stdout=subprocess.PIPE, |
+ svn_info = subprocess.Popen(command, |
+ shell=True, |
+ stdout=subprocess.PIPE, |
stderr=subprocess.PIPE).stdout.readlines() |
- map = dict() |
+ map = {} |
for line in svn_info: |
match = re.search(r"[\n\r ]+[MADUC][\n\r ]+/(?:trunk|branches/\d+)/src([^ ]*)/([^ ]+)", line) |
- |
if match: |
map[match.group(1) + "/" + match.group(2)] = match.group(1) + "/" + match.group(2) |
return map.keys() |
+ |
def getBestMergePath(url, revision): |
- """ |
- Takes an svn url and gets the associated revision. |
- """ |
+ """Takes an svn url and gets the associated revision.""" |
command = 'svn log ' + url + " -r "+str(revision) + " -v" |
- svn_info = subprocess.Popen(command, |
- shell=True, |
- stdout=subprocess.PIPE, |
+ svn_info = subprocess.Popen(command, |
+ shell=True, |
+ stdout=subprocess.PIPE, |
stderr=subprocess.PIPE).stdout.readlines() |
best_path = None |
- |
for line in svn_info: |
match = re.search(r"[\n\r ]+[MADUC][\n\r ]+/.*/src(.*)/.+", line) |
if match: |
@@ -200,21 +185,20 @@ def getBestMergePath(url, revision): |
best_path = match.group(1) |
else: |
best_path = leastPath(match.group(1),best_path) |
-# print best_path |
return best_path |
+ |
def leastPath(a, b): |
if (not a) or (a == ""): |
return "" |
if (b == ""): |
return "" |
if (not b): |
- return a |
- |
+ return a |
+ |
a_list = a.lstrip("/").split("/") |
b_list = b.lstrip("/").split("/") |
- |
last_match = "" |
while((len(a_list) != 0) and (len(b_list) != 0)): |
a_value = a_list.pop(0) |
@@ -223,12 +207,12 @@ def leastPath(a, b): |
last_match = last_match + "/" + a_value |
else: |
break |
- |
+ |
return last_match |
+ |
def prompt(question): |
p = None |
- |
while not p: |
print question + " [y|n]:" |
p = sys.stdin.readline() |
@@ -237,7 +221,8 @@ def prompt(question): |
elif p.lower().startswith('y'): |
return True |
else: |
- p = None |
+ p = None |
+ |
def main(argv=None): |
BASE_URL = "svn://chrome-svn/chrome" |
@@ -267,23 +252,21 @@ def main(argv=None): |
revision = int(sys.argv[1]) |
if ((len(sys.argv) >= 4) and (sys.argv[2] in ['--revert','-r'])): |
BRANCH_URL = BASE_URL + "/branches/" + sys.argv[3] + "/src" |
- url = BRANCH_URL |
+ url = BRANCH_URL |
else: |
url = TRUNK_URL |
action = "Merge" |
- |
command = 'svn log ' + url + " -r "+str(revision) + " -v" |
os.system(command) |
- |
if not prompt("Is this the correct revision?"): |
sys.exit(0) |
- |
+ |
if (len(sys.argv) > 1): |
if sys.argv[2] in ['--merge','-m']: |
if (len(sys.argv) != 4): |
print "Please specify the branch # you want (i.e. 182) after --merge" |
sys.exit(0) |
- |
+ |
branch_url = "svn://chrome-svn/chrome/branches/" + sys.argv[3] + "/src" |
checkoutRevision(url, revision, branch_url) |
mergeRevision(url, revision) |
@@ -293,7 +276,7 @@ def main(argv=None): |
sys.exit(0) |
branch_url = "svn://chrome-svn/chrome/branches/" + sys.argv[3] + "/src" |
checkoutRevision(url, revision, branch_url) |
- mergeRevision(url, revision, True) |
+ mergeRevision(url, revision, True) |
elif sys.argv[2] in ['--revert','-r']: |
if (len(sys.argv) == 4): |
url = "svn://chrome-svn/chrome/branches/" + sys.argv[3] + "/src" |
@@ -305,10 +288,8 @@ def main(argv=None): |
sys.exit(0) |
os.chdir('./src') |
- |
- #Check the base url so we actually find the author who made the change |
+ # Check the base url so we actually find the author who made the change. |
author = getAuthor(BASE_URL, revision) |
- |
filename = str(revision)+".txt" |
out = open(filename,"w") |
out.write(action +" " + str(revision) + " - ") |
@@ -316,7 +297,6 @@ def main(argv=None): |
if (author): |
out.write("TBR=" + author) |
out.close() |
- |
os.system('gcl change ' + str(revision) + " " + filename) |
os.unlink(filename) |
print author |
@@ -336,6 +316,7 @@ def main(argv=None): |
os.system("gcl commit " + str(revision) + " --no_presubmit --force") |
else: |
sys.exit(0) |
- |
+ |
+ |
if __name__ == "__main__": |
- sys.exit(main()) |
+ sys.exit(main()) |