OLD | NEW |
| (Empty) |
1 #!/usr/bin/env python | |
2 # Copyright (c) 2014 The WebRTC project authors. All Rights Reserved. | |
3 # | |
4 # Use of this source code is governed by a BSD-style license | |
5 # that can be found in the LICENSE file in the root of the source | |
6 # tree. An additional intellectual property rights grant can be found | |
7 # in the file PATENTS. All contributing project authors may | |
8 # be found in the AUTHORS file in the root of the source tree. | |
9 | |
10 """Script to download a Chromium checkout into the workspace. | |
11 | |
12 The script downloads a full Chromium Git clone and its DEPS. | |
13 | |
14 The following environment variable can be used to alter the behavior: | |
15 * CHROMIUM_NO_HISTORY - If set to 1, a Git checkout with no history will be | |
16 downloaded. This is consumes less bandwidth and disk space but is known to be | |
17 slower in general if you have a high-speed connection. | |
18 | |
19 After a successful sync has completed, a .last_sync_chromium file is written to | |
20 the chromium directory. While it exists, no more gclient sync operations will be | |
21 performed until the --target-revision changes or the SCRIPT_VERSION constant is | |
22 incremented. The file can be removed manually to force a new sync. | |
23 """ | |
24 | |
25 import argparse | |
26 import os | |
27 import shutil | |
28 import subprocess | |
29 import sys | |
30 import textwrap | |
31 | |
32 # Bump this whenever the algorithm changes and you need bots/devs to re-sync, | |
33 # ignoring the .last_sync_chromium file | |
34 SCRIPT_VERSION = 8 | |
35 | |
36 ROOT_DIR = os.path.dirname(os.path.abspath(__file__)) | |
37 CHROMIUM_NO_HISTORY = 'CHROMIUM_NO_HISTORY' | |
38 | |
39 # Duplicated from depot_tools/gclient.py since we cannot depend on that: | |
40 DEPS_OS_CHOICES = { | |
41 "win32": "win", | |
42 "win": "win", | |
43 "cygwin": "win", | |
44 "darwin": "mac", | |
45 "mac": "mac", | |
46 "unix": "unix", | |
47 "linux": "unix", | |
48 "linux2": "unix", | |
49 "linux3": "unix", | |
50 "android": "android", | |
51 } | |
52 | |
53 def _parse_gclient_dict(): | |
54 gclient_dict = {} | |
55 try: | |
56 main_gclient = os.path.join(os.path.dirname(ROOT_DIR), '.gclient') | |
57 with open(main_gclient, 'rb') as deps_content: | |
58 exec(deps_content, gclient_dict) | |
59 except Exception as e: | |
60 print >> sys.stderr, 'error while parsing .gclient:', e | |
61 return gclient_dict | |
62 | |
63 | |
64 def get_cache_dir(): | |
65 return _parse_gclient_dict().get('cache_dir') | |
66 | |
67 | |
68 def get_target_os_list(): | |
69 # Always add the currently running OS since the --deps option will override | |
70 # that if specified: | |
71 target_os_list = [DEPS_OS_CHOICES.get(sys.platform, 'unix')] | |
72 # Add any target_os entries from .gclient. | |
73 target_os_list += _parse_gclient_dict().get('target_os', []) | |
74 return ','.join(target_os_list) | |
75 | |
76 | |
77 def main(): | |
78 CR_DIR = os.path.join(ROOT_DIR, 'chromium') | |
79 | |
80 p = argparse.ArgumentParser() | |
81 p.add_argument('--target-revision', required=True, | |
82 help='The target chromium git revision [REQUIRED]') | |
83 p.add_argument('--chromium-dir', default=CR_DIR, | |
84 help=('The path to the chromium directory to sync ' | |
85 '(default: %(default)r)')) | |
86 opts = p.parse_args() | |
87 opts.chromium_dir = os.path.abspath(opts.chromium_dir) | |
88 | |
89 target_os_list = get_target_os_list() | |
90 | |
91 # Do a quick check to see if we were successful last time to make runhooks | |
92 # sooper fast. | |
93 flag_file = os.path.join(opts.chromium_dir, '.last_sync_chromium') | |
94 flag_file_content = '\n'.join([ | |
95 str(SCRIPT_VERSION), | |
96 opts.target_revision, | |
97 repr(target_os_list), | |
98 ]) | |
99 if (os.path.exists(os.path.join(opts.chromium_dir, 'src')) and | |
100 os.path.exists(flag_file)): | |
101 with open(flag_file, 'r') as f: | |
102 if f.read() == flag_file_content: | |
103 print 'Chromium already up to date: ', opts.target_revision | |
104 return 0 | |
105 os.unlink(flag_file) | |
106 | |
107 # Workaround to avoid sync failure due move in | |
108 # https://codereview.chromium.org/1155743013 | |
109 # TODO(kjellander): Remove this after the summer of 2015. | |
110 freetype_src = os.path.join(CR_DIR, 'src', 'third_party', 'freetype-android', | |
111 'src') | |
112 if os.path.isdir(freetype_src): | |
113 shutil.rmtree(freetype_src) | |
114 | |
115 # Avoid downloading NaCl toolchain as part of the Chromium hooks. | |
116 gclient_cmd = 'gclient.bat' if sys.platform.startswith('win') else 'gclient' | |
117 args = [ | |
118 gclient_cmd, 'sync', '--force', '--nohooks', '--revision', | |
119 'src@' + opts.target_revision | |
120 ] | |
121 | |
122 if os.environ.get('CHROME_HEADLESS') == '1': | |
123 # Running on a buildbot. | |
124 args.append('-vvv') | |
125 | |
126 if sys.platform.startswith('win'): | |
127 cache_path = os.path.join(os.path.splitdrive(ROOT_DIR)[0] + os.path.sep, | |
128 'b', 'git-cache') | |
129 else: | |
130 cache_path = '/b/git-cache' | |
131 else: | |
132 # Verbose, but not as verbose as on the buildbots. | |
133 args.append('-v') | |
134 | |
135 # Support developers setting the cache_dir in .gclient. | |
136 cache_path = get_cache_dir() | |
137 | |
138 # Allow for users with poor internet connections to download a Git clone | |
139 # without history (saves several gigs but is generally slower and doesn't work | |
140 # with the Git cache). | |
141 if os.environ.get(CHROMIUM_NO_HISTORY) == '1': | |
142 if cache_path: | |
143 print >> sys.stderr, ( | |
144 'You cannot use "no-history" mode for syncing Chrome (i.e. set the ' | |
145 '%s environment variable to 1) when you have cache_dir configured in ' | |
146 'your .gclient.' % CHROMIUM_NO_HISTORY) | |
147 return 1 | |
148 args.append('--no-history') | |
149 gclient_entries_file = os.path.join(opts.chromium_dir, '.gclient_entries') | |
150 else: | |
151 # Write a temporary .gclient file that has the cache_dir variable added. | |
152 gclientfile = os.path.join(opts.chromium_dir, '.gclient') | |
153 with open(gclientfile, 'rb') as spec: | |
154 spec = spec.read().splitlines() | |
155 spec[-1] = 'cache_dir = %r' % (cache_path,) | |
156 with open(gclientfile + '.tmp', 'wb') as f: | |
157 f.write('\n'.join(spec)) | |
158 | |
159 args += [ | |
160 '--gclientfile', '.gclient.tmp', | |
161 '--delete_unversioned_trees', '--reset', '--upstream' | |
162 ] | |
163 gclient_entries_file = os.path.join(opts.chromium_dir, | |
164 '.gclient.tmp_entries') | |
165 | |
166 # To avoid gclient sync problems when DEPS entries have been removed we must | |
167 # wipe the gclient's entries file that contains cached URLs for all DEPS. | |
168 if os.path.exists(gclient_entries_file): | |
169 os.unlink(gclient_entries_file) | |
170 | |
171 if target_os_list: | |
172 args += ['--deps=' + target_os_list] | |
173 | |
174 print textwrap.dedent("""\ | |
175 +---------------------------------------------------------------------+ | |
176 | NOTICE: This sync of Chromium will take a long time as several | | |
177 | gigabytes of data are downloaded. If this is your initial | | |
178 | sync and it's interrupted, try running 'gclient sync' again.| | |
179 | If that fails, wipe everything clean and start over again. | | |
180 +---------------------------------------------------------------------+""") | |
181 print 'Running "%s" in %s' % (' '.join(args), opts.chromium_dir) | |
182 ret = subprocess.call(args, cwd=opts.chromium_dir) | |
183 if ret == 0: | |
184 with open(flag_file, 'wb') as f: | |
185 f.write(flag_file_content) | |
186 | |
187 return ret | |
188 | |
189 | |
190 if __name__ == '__main__': | |
191 sys.exit(main()) | |
OLD | NEW |