| OLD | NEW |
| 1 #!/usr/bin/python | 1 #!/usr/bin/python |
| 2 # Copyright (c) 2009 The Chromium Authors. All rights reserved. | 2 # Copyright (c) 2009 The Chromium Authors. All rights reserved. |
| 3 # Use of this source code is governed by a BSD-style license that can be | 3 # Use of this source code is governed by a BSD-style license that can be |
| 4 # found in the LICENSE file. | 4 # found in the LICENSE file. |
| 5 | 5 |
| 6 # Author: mpcomplete | 6 import os |
| 7 # | 7 import re |
| 8 # This script updates and does a clean build of chrome for you. | 8 import subprocess |
| 9 # Usage: python chrome-update.py C:\path\to\chrome\trunk | 9 import sys |
| 10 # | 10 import urllib |
| 11 # It assumes the following: | |
| 12 # - You have gclient.bat and devenv.com in your path (use the wrapper batch | |
| 13 # file to ensure this). | |
| 14 | 11 |
| 15 import sys | 12 IS_WIN = sys.platform.startswith('win') |
| 16 import os | 13 BASE_URL = 'http://src.chromium.org/svn/trunk/tools/buildbot/scripts/' |
| 17 import subprocess | 14 COMPILE_URL = BASE_URL + 'slave/compile.py' |
| 18 import httplib | 15 UTILS_URL = BASE_URL + 'common/chromium_utils.py' |
| 19 import re | |
| 20 import shutil | |
| 21 import optparse | |
| 22 | 16 |
| 23 def Message(str): | |
| 24 """Prints a status message.""" | |
| 25 print "[chrome-update]", str | |
| 26 | 17 |
| 27 def FixupPath(path): | 18 def Fetch(url, file): |
| 28 """Returns the OS-ified version of a windows path.""" | 19 if not os.path.exists(file): |
| 29 return os.path.sep.join(path.split("\\")) | 20 urllib.urlretrieve(url, file) |
| 30 | 21 |
| 31 def GetRevision(): | 22 |
| 23 def GetLastestRevision(): |
| 32 """Returns the revision number of the last build that was archived, or | 24 """Returns the revision number of the last build that was archived, or |
| 33 None on failure.""" | 25 None on failure.""" |
| 34 HOST = "build.chromium.org" | 26 url = 'http://build.chromium.org/buildbot/continuous/' |
| 35 PATH = "/buildbot/continuous/LATEST/REVISION" | 27 if sys.platform.startswith('win'): |
| 36 EXPR = r"(\d+)" | 28 url += 'win/' |
| 37 | 29 elif sys.platform.startswith('linux'): |
| 38 connection = httplib.HTTPConnection(HOST) | 30 url += 'linux/' |
| 39 connection.request("GET", PATH) | 31 elif sys.platform.startswith('darwin'): |
| 40 response = connection.getresponse() | 32 url += 'mac/' |
| 41 text = response.read() | 33 else: |
| 42 match = re.search(EXPR, text) | 34 # This path is actually win. |
| 43 if match: | 35 pass |
| 44 return int(match.group(1)) | 36 url += 'LATEST/REVISION' |
| 37 text = urllib.urlopen(url).read() |
| 38 if text: |
| 39 match = re.search(r"(\d+)", text) |
| 40 if match: |
| 41 return int(match.group(1)) |
| 45 return None | 42 return None |
| 46 | 43 |
| 47 def SetRevisionForUpdate(chrome_root): | |
| 48 """Prepares environment so gclient syncs to a good revision, if possible.""" | |
| 49 # Find a buildable revision. | |
| 50 rev = GetRevision() | |
| 51 if rev == None: | |
| 52 Message("WARNING: Failed to find a buildable revision. Syncing to trunk.") | |
| 53 return "trunk" | |
| 54 | |
| 55 # Read the .gclient file. | |
| 56 gclient_file = chrome_root + FixupPath("\\.gclient") | |
| 57 if not os.path.exists(gclient_file): | |
| 58 Message("WARNING: Failed to find .gclient file. Syncing to trunk.") | |
| 59 return "trunk" | |
| 60 scope = {} | |
| 61 execfile(gclient_file, scope) | |
| 62 solutions = scope["solutions"] | |
| 63 | |
| 64 # Edit the url of the chrome 'src' solution, unless the user wants a | |
| 65 # specific revision. | |
| 66 for solution in solutions: | |
| 67 if solution["name"] == "src": | |
| 68 splitter = solution["url"].split("@") | |
| 69 if len(splitter) == 1: | |
| 70 solution["url"] = splitter[0] + "@" + str(rev) | |
| 71 else: | |
| 72 rev = int(splitter[1]) | |
| 73 break | |
| 74 | |
| 75 # Write out the new .gclient file. | |
| 76 gclient_override = gclient_file + "-update-chrome" | |
| 77 f = open(gclient_override, "w") | |
| 78 f.write("solutions = " + str(solutions)) | |
| 79 f.close() | |
| 80 | |
| 81 # Set the env var that the gclient tool looks for. | |
| 82 os.environ["GCLIENT_FILE"] = gclient_override | |
| 83 return rev | |
| 84 | 44 |
| 85 def DoUpdate(chrome_root): | 45 def DoUpdate(chrome_root): |
| 86 """gclient sync to the latest build.""" | 46 """gclient sync to the latest build.""" |
| 87 # gclient sync | 47 cmd = ["gclient", "sync"] |
| 88 rev = SetRevisionForUpdate(chrome_root) | 48 rev = GetLastestRevision() |
| 49 if rev: |
| 50 cmd.extend(['--revision', 'src@%d' % rev]) |
| 51 return subprocess.call(cmd, cwd=chrome_root, shell=IS_WIN) |
| 89 | 52 |
| 90 cmd = ["gclient.bat", "sync"] | |
| 91 Message("Updating to %s: %s" % (rev, cmd)) | |
| 92 sys.stdout.flush() | |
| 93 return subprocess.call(cmd, cwd=chrome_root) | |
| 94 | 53 |
| 95 def DoClean(chrome_root, type): | 54 def DoBuild(chrome_root, args): |
| 96 """Clean our build dir.""" | 55 """Download compile.py and run it.""" |
| 97 # rm -rf src/chrome/Debug | 56 compile = os.path.join(chrome_root, 'compile.py') |
| 98 rv = [0] | 57 Fetch(COMPILE_URL, compile) |
| 99 def onError(func, path, excinfo): | 58 Fetch(UTILS_URL, os.path.join(chrome_root, 'chromium_utils.py')) |
| 100 Message("Couldn't remove '%s': %s" % (path, excinfo)) | 59 cmd = ['python', compile] + args |
| 101 rv[0] = [1] | 60 return subprocess.call(cmd, cwd=chrome_root, shell=IS_WIN) |
| 102 | 61 |
| 103 build_path = chrome_root + FixupPath("\\src\\chrome\\" + type) | |
| 104 Message("Cleaning: %s" % build_path) | |
| 105 shutil.rmtree(build_path, False, onError) | |
| 106 return rv[0] | |
| 107 | 62 |
| 108 def DoBuild(chrome_root, chrome_sln, clean, type): | 63 def Main(args): |
| 109 """devenv /build what we just checked out.""" | 64 if len(args) < 3: |
| 110 if clean: | 65 print('Usage: chrome-update.py <path> [options]') |
| 111 rv = DoClean(chrome_root, type) | 66 print('See options from compile.py at') |
| 112 if rv != 0: | 67 print(' %s' % COMPILE_URL) |
| 113 Message("WARNING: Clean failed. Doing a build without clean.") | 68 print('\nFor more example, see the compile steps on the waterfall') |
| 69 return 1 |
| 114 | 70 |
| 115 # devenv chrome.sln /build Debug | 71 chrome_root = args[1] |
| 116 cmd = ["devenv.com", chrome_sln, "/build", type] | 72 if not os.path.isdir(chrome_root): |
| 73 print('Path to chrome root (%s) not found.' % chrome_root) |
| 74 return 1 |
| 117 | 75 |
| 118 Message("Building: %s" % cmd) | 76 rv = DoUpdate(chrome_root) |
| 119 sys.stdout.flush() | 77 if rv != 0: |
| 120 return subprocess.call(cmd, cwd=chrome_root) | 78 print('Update Failed. Bailing.') |
| 79 return rv |
| 121 | 80 |
| 122 def Main(): | 81 DoBuild(chrome_root, args[2:]) |
| 123 parser = optparse.OptionParser() | 82 print('Success!') |
| 124 parser.add_option("", "--clean", action="store_true", default=False, | 83 return 0 |
| 125 help="wipe Debug output directory before building") | |
| 126 parser.add_option("", "--solution", default="src\\chrome\\chrome.sln", | |
| 127 help="path to the .sln file to build (absolute, or " | |
| 128 "relative to chrome trunk") | |
| 129 parser.add_option("", "--release", action="store_true", default=False, | |
| 130 help="build the release configuration in addition of the " | |
| 131 "debug configuration.") | |
| 132 parser.add_option("", "--nosync", action="store_true", default=False, | |
| 133 help="doesn't sync before building") | |
| 134 parser.add_option("", "--print-latest", action="store_true", default=False, | |
| 135 help="print the latest buildable revision and exit") | |
| 136 options, args = parser.parse_args() | |
| 137 | 84 |
| 138 if options.print_latest: | |
| 139 print GetRevision() or "HEAD" | |
| 140 sys.exit(0) | |
| 141 | |
| 142 if not args: | |
| 143 Message("Usage: %s <path\\to\\chrome\\root> [options]" % sys.argv[0]) | |
| 144 sys.exit(1) | |
| 145 | |
| 146 chrome_root = args[0] | |
| 147 if not os.path.isdir(chrome_root): | |
| 148 Message("Path to chrome root (%s) not found." % repr(chrome_root)) | |
| 149 sys.exit(1) | |
| 150 | |
| 151 if not options.nosync: | |
| 152 rv = DoUpdate(chrome_root) | |
| 153 if rv != 0: | |
| 154 Message("Update Failed. Bailing.") | |
| 155 sys.exit(rv) | |
| 156 | |
| 157 chrome_sln = FixupPath(options.solution) | |
| 158 rv = DoBuild(chrome_root, chrome_sln, options.clean, "Debug") | |
| 159 if rv != 0: | |
| 160 Message("Debug build failed. Sad face :(") | |
| 161 | |
| 162 if options.release: | |
| 163 rv = DoBuild(chrome_root, chrome_sln, options.clean, "Release") | |
| 164 if rv != 0: | |
| 165 Message("Release build failed. Sad face :(") | |
| 166 | |
| 167 if rv != 0: | |
| 168 sys.exit(rv) | |
| 169 | |
| 170 Message("Success!") | |
| 171 | 85 |
| 172 if __name__ == "__main__": | 86 if __name__ == "__main__": |
| 173 Main() | 87 sys.exit(Main(sys.argv)) |
| OLD | NEW |