OLD | NEW |
(Empty) | |
| 1 #!/usr/bin/python |
| 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 |
| 4 # found in the LICENSE file. |
| 5 |
| 6 # Author: mpcomplete |
| 7 # |
| 8 # This script updates and does a clean build of chrome for you. |
| 9 # Usage: python chrome-update.py C:\path\to\chrome\trunk |
| 10 # |
| 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 |
| 15 import sys |
| 16 import os |
| 17 import subprocess |
| 18 import httplib |
| 19 import re |
| 20 import shutil |
| 21 import optparse |
| 22 |
| 23 def Message(str): |
| 24 """Prints a status message.""" |
| 25 print "[chrome-update]", str |
| 26 |
| 27 def FixupPath(path): |
| 28 """Returns the OS-ified version of a windows path.""" |
| 29 return os.path.sep.join(path.split("\\")) |
| 30 |
| 31 def GetRevision(): |
| 32 """Returns the revision number of the last build that was archived, or |
| 33 None on failure.""" |
| 34 HOST = "build.chromium.org" |
| 35 PATH = "/buildbot/continuous/LATEST/REVISION" |
| 36 EXPR = r"(\d+)" |
| 37 |
| 38 connection = httplib.HTTPConnection(HOST) |
| 39 connection.request("GET", PATH) |
| 40 response = connection.getresponse() |
| 41 text = response.read() |
| 42 match = re.search(EXPR, text) |
| 43 if match: |
| 44 return int(match.group(1)) |
| 45 return None |
| 46 |
| 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 |
| 85 def DoUpdate(chrome_root): |
| 86 """gclient sync to the latest build.""" |
| 87 # gclient sync |
| 88 rev = SetRevisionForUpdate(chrome_root) |
| 89 |
| 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 |
| 95 def DoClean(chrome_root, type): |
| 96 """Clean our build dir.""" |
| 97 # rm -rf src/chrome/Debug |
| 98 rv = [0] |
| 99 def onError(func, path, excinfo): |
| 100 Message("Couldn't remove '%s': %s" % (path, excinfo)) |
| 101 rv[0] = [1] |
| 102 |
| 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 |
| 108 def DoBuild(chrome_root, chrome_sln, clean, type): |
| 109 """devenv /build what we just checked out.""" |
| 110 if clean: |
| 111 rv = DoClean(chrome_root, type) |
| 112 if rv != 0: |
| 113 Message("WARNING: Clean failed. Doing a build without clean.") |
| 114 |
| 115 # devenv chrome.sln /build Debug |
| 116 cmd = ["devenv.com", chrome_sln, "/build", type] |
| 117 |
| 118 Message("Building: %s" % cmd) |
| 119 sys.stdout.flush() |
| 120 return subprocess.call(cmd, cwd=chrome_root) |
| 121 |
| 122 def Main(): |
| 123 parser = optparse.OptionParser() |
| 124 parser.add_option("", "--clean", action="store_true", default=False, |
| 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 |
| 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 |
| 148 if not options.nosync: |
| 149 rv = DoUpdate(chrome_root) |
| 150 if rv != 0: |
| 151 Message("Update Failed. Bailing.") |
| 152 sys.exit(rv) |
| 153 |
| 154 chrome_sln = FixupPath(options.solution) |
| 155 rv = DoBuild(chrome_root, chrome_sln, options.clean, "Debug") |
| 156 if rv != 0: |
| 157 Message("Debug build failed. Sad face :(") |
| 158 |
| 159 if options.release: |
| 160 rv = DoBuild(chrome_root, chrome_sln, options.clean, "Release") |
| 161 if rv != 0: |
| 162 Message("Release build failed. Sad face :(") |
| 163 |
| 164 if rv != 0: |
| 165 sys.exit(rv) |
| 166 |
| 167 Message("Success!") |
| 168 |
| 169 if __name__ == "__main__": |
| 170 Main() |
OLD | NEW |