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 |