OLD | NEW |
---|---|
1 #!/usr/bin/env python | 1 #!/usr/bin/env python |
2 # Copyright (c) 2012 The Chromium Authors. All rights reserved. | 2 # Copyright (c) 2012 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 """ | 6 """ |
7 This file holds a list of reasons why a particular build needs to be clobbered | 7 This file holds a list of reasons why a particular build needs to be clobbered |
8 (or a list of 'landmines'). | 8 (or a list of 'landmines'). |
9 | 9 |
10 This script runs every build as a hook. If it detects that the build should | 10 This script runs every build as a hook. If it detects that the build should |
11 be clobbered, it will touch the file <build_dir>/.landmine_triggered. The | 11 be clobbered, it will touch the file <build_dir>/.landmine_triggered. The |
12 various build scripts will then check for the presence of this file and clobber | 12 various build scripts will then check for the presence of this file and clobber |
13 accordingly. The script will also emit the reasons for the clobber to stdout. | 13 accordingly. The script will also emit the reasons for the clobber to stdout. |
14 | 14 |
15 A landmine is tripped when a builder checks out a different revision, and the | 15 A landmine is tripped when a builder checks out a different revision, and the |
16 diff between the new landmines and the old ones is non-null. At this point, the | 16 diff between the new landmines and the old ones is non-null. At this point, the |
17 build is clobbered. | 17 build is clobbered. |
18 """ | 18 """ |
19 | 19 |
20 import difflib | 20 import difflib |
21 import functools | 21 import functools |
22 import gyp_helper | 22 import gyp_helper |
23 import optparse | |
23 import os | 24 import os |
24 import shlex | 25 import shlex |
25 import sys | 26 import sys |
26 import time | 27 import time |
27 | 28 |
28 SRC_DIR = os.path.dirname(os.path.dirname(os.path.realpath(__file__))) | 29 SRC_DIR = os.path.dirname(os.path.dirname(os.path.realpath(__file__))) |
30 VERBOSE = 'LANDMINES_VERBOSE' in os.environ | |
29 | 31 |
30 def memoize(default=None): | 32 def memoize(default=None): |
31 """This decorator caches the return value of a parameterless pure function""" | 33 """This decorator caches the return value of a parameterless pure function""" |
32 def memoizer(func): | 34 def memoizer(func): |
33 val = [] | 35 val = [] |
34 @functools.wraps(func) | 36 @functools.wraps(func) |
35 def inner(): | 37 def inner(): |
36 if not val: | 38 if not val: |
37 ret = func() | 39 ret = func() |
38 val.append(ret if ret is not None else default) | 40 val.append(ret if ret is not None else default) |
39 print '%s -> %r' % (func.__name__, val[0]) | 41 if VERBOSE: |
42 print '%s -> %r' % (func.__name__, val[0]) | |
40 return val[0] | 43 return val[0] |
41 return inner | 44 return inner |
42 return memoizer | 45 return memoizer |
43 | 46 |
44 | 47 |
45 @memoize() | 48 @memoize() |
46 def IsWindows(): | 49 def IsWindows(): |
47 return sys.platform.startswith('win') or sys.platform == 'cygwin' | 50 return sys.platform.startswith('win') or sys.platform == 'cygwin' |
48 | 51 |
49 | 52 |
(...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
160 ret = os.path.join(SRC_DIR, 'out', target) | 163 ret = os.path.join(SRC_DIR, 'out', target) |
161 elif build_tool == 'msvs': | 164 elif build_tool == 'msvs': |
162 ret = os.path.join(SRC_DIR, 'build', target) | 165 ret = os.path.join(SRC_DIR, 'build', target) |
163 elif build_tool == 'scons': | 166 elif build_tool == 'scons': |
164 ret = os.path.join(SRC_DIR, 'sconsbuild', target) | 167 ret = os.path.join(SRC_DIR, 'sconsbuild', target) |
165 else: | 168 else: |
166 raise NotImplementedError() | 169 raise NotImplementedError() |
167 return os.path.abspath(ret) | 170 return os.path.abspath(ret) |
168 | 171 |
169 | 172 |
170 def main(argv): | 173 def GetOptions(): |
M-A Ruel
2012/11/14 23:12:01
I don't think it's useful to have a function just
| |
171 if len(argv) > 1: | 174 parser = optparse.OptionParser() |
172 print('Unknown arguments %s' % argv[1:]) | 175 parser.add_option('-v', '--verbose', action='store_true', default=False, |
M-A Ruel
2012/11/14 23:12:01
I prefer default='LANDMINES_VERBOSE' in os.environ
| |
173 return 1 | 176 help=('Emit some extra debugging information (default off). This option ' |
177 'is also enabled by the presence of a LANDMINES_VERBOSE environment ' | |
178 'variable.')) | |
179 options, args = parser.parse_args() | |
180 | |
181 if args: | |
182 parser.error('Unknown arguments %s' % args) | |
183 | |
184 return options | |
185 | |
186 | |
187 def main(): | |
188 global VERBOSE | |
189 options = GetOptions() | |
190 | |
191 VERBOSE = VERBOSE or options.verbose | |
174 | 192 |
M-A Ruel
2012/11/14 23:12:01
FYI, I usually put a main() where I do all the arg
| |
175 gyp_helper.apply_chromium_gyp_env() | 193 gyp_helper.apply_chromium_gyp_env() |
176 | 194 |
177 for target in ('Debug', 'Release'): | 195 for target in ('Debug', 'Release'): |
178 out_dir = get_target_build_dir(builder(), target, | 196 out_dir = get_target_build_dir(builder(), target, |
179 platform() == 'ios') | 197 platform() == 'ios') |
180 | 198 |
181 landmines_path = os.path.join(out_dir, '.landmines') | 199 landmines_path = os.path.join(out_dir, '.landmines') |
182 if not os.path.exists(out_dir): | 200 if not os.path.exists(out_dir): |
183 os.makedirs(out_dir) | 201 os.makedirs(out_dir) |
184 | 202 |
(...skipping 15 matching lines...) Expand all Loading... | |
200 with open(triggered, 'w') as f: | 218 with open(triggered, 'w') as f: |
201 f.writelines(diff) | 219 f.writelines(diff) |
202 elif os.path.exists(triggered): | 220 elif os.path.exists(triggered): |
203 # Remove false triggered landmines. | 221 # Remove false triggered landmines. |
204 os.remove(triggered) | 222 os.remove(triggered) |
205 | 223 |
206 return 0 | 224 return 0 |
207 | 225 |
208 | 226 |
209 if __name__ == '__main__': | 227 if __name__ == '__main__': |
210 sys.exit(main(sys.argv)) | 228 sys.exit(main()) |
OLD | NEW |