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 """Windows can't run .sh files, so this is a Python implementation of | 6 """Windows can't run .sh files, so this is a Python implementation of |
7 update.sh. This script should replace update.sh on all platforms eventually.""" | 7 update.sh. This script should replace update.sh on all platforms eventually.""" |
8 | 8 |
9 import os | 9 import os |
10 import re | 10 import re |
11 import shutil | 11 import shutil |
12 import subprocess | 12 import subprocess |
| 13 import stat |
13 import sys | 14 import sys |
| 15 import time |
14 | 16 |
15 # Do NOT CHANGE this if you don't know what you're doing -- see | 17 # Do NOT CHANGE this if you don't know what you're doing -- see |
16 # https://code.google.com/p/chromium/wiki/UpdatingClang | 18 # https://code.google.com/p/chromium/wiki/UpdatingClang |
17 # Reverting problematic clang rolls is safe, though. | 19 # Reverting problematic clang rolls is safe, though. |
18 # Note: this revision is only used for Windows. Other platforms use update.sh. | 20 # Note: this revision is only used for Windows. Other platforms use update.sh. |
19 LLVM_WIN_REVISION = 'HEAD' | 21 LLVM_WIN_REVISION = 'HEAD' |
20 | 22 |
21 # ASan on Windows is useful enough to use it even while the clang/win is still | 23 # ASan on Windows is useful enough to use it even while the clang/win is still |
22 # in bringup. Use a pinned revision to make it slightly more stable. | 24 # in bringup. Use a pinned revision to make it slightly more stable. |
23 if (re.search(r'\b(asan)=1', os.environ.get('GYP_DEFINES', '')) and | 25 if (re.search(r'\b(asan)=1', os.environ.get('GYP_DEFINES', '')) and |
(...skipping 27 matching lines...) Expand all Loading... |
51 | 53 |
52 | 54 |
53 def WriteStampFile(s): | 55 def WriteStampFile(s): |
54 """Write s to the stamp file.""" | 56 """Write s to the stamp file.""" |
55 if not os.path.exists(LLVM_BUILD_DIR): | 57 if not os.path.exists(LLVM_BUILD_DIR): |
56 os.makedirs(LLVM_BUILD_DIR) | 58 os.makedirs(LLVM_BUILD_DIR) |
57 with open(STAMP_FILE, 'w') as f: | 59 with open(STAMP_FILE, 'w') as f: |
58 f.write(s) | 60 f.write(s) |
59 | 61 |
60 | 62 |
61 def DeleteFiles(dir, pattern): | 63 def RmTree(dir): |
62 """Delete all files in dir matching pattern.""" | 64 """Delete dir.""" |
63 n = 0 | 65 def ChmodAndRetry(func, path, _): |
64 regex = re.compile(r'^' + pattern + r'$') | 66 # Subversion can leave read-only files around. |
65 for root, _, files in os.walk(dir): | 67 if not os.access(path, os.W_OK): |
66 for f in files: | 68 os.chmod(path, stat.S_IWUSR) |
67 if regex.match(f): | 69 return func(path) |
68 os.remove(os.path.join(root, f)) | 70 raise |
69 n += 1 | 71 |
70 return n | 72 shutil.rmtree(dir, onerror=ChmodAndRetry) |
71 | 73 |
72 | 74 |
73 def ClobberChromiumBuildFiles(): | 75 def ClobberChromiumBuildFiles(): |
74 """Clobber Chomium build files.""" | 76 """Clobber Chomium build files.""" |
75 print 'Clobbering Chromium build files...' | 77 print 'Clobbering Chromium build files...' |
76 out_dir = os.path.join(CHROMIUM_DIR, 'out') | 78 out_dir = os.path.join(CHROMIUM_DIR, 'out') |
77 if os.path.isdir(out_dir): | 79 if os.path.isdir(out_dir): |
78 shutil.rmtree(out_dir) | 80 RmTree(out_dir) |
79 print 'Removed Chromium out dir: %s.' % (out_dir) | 81 print 'Removed Chromium out dir: %s.' % (out_dir) |
80 | 82 |
81 | 83 |
82 def RunCommand(command, tries=1): | 84 def RunCommand(command, fail_hard=True): |
83 """Run a command, possibly with multiple retries.""" | 85 """Run command and return success (True) or failure; or if fail_hard is |
84 for i in range(0, tries): | 86 True, exit on failure.""" |
85 print 'Running %s (try #%d)' % (str(command), i + 1) | 87 |
86 if subprocess.call(command, shell=True) == 0: | 88 print 'Running %s' % (str(command)) |
87 return | 89 if subprocess.call(command, shell=True) == 0: |
88 print 'Failed.' | 90 return True |
89 sys.exit(1) | 91 print 'Failed.' |
| 92 if fail_hard: |
| 93 sys.exit(1) |
| 94 return False |
90 | 95 |
91 | 96 |
92 def CopyFile(src, dst): | 97 def CopyFile(src, dst): |
93 """Copy a file from src to dst.""" | 98 """Copy a file from src to dst.""" |
94 shutil.copy(src, dst) | 99 shutil.copy(src, dst) |
95 print "Copying %s to %s" % (src, dst) | 100 print "Copying %s to %s" % (src, dst) |
96 | 101 |
97 | 102 |
98 def CopyDirectoryContents(src, dst, filename_filter=None): | 103 def CopyDirectoryContents(src, dst, filename_filter=None): |
99 """Copy the files from directory src to dst | 104 """Copy the files from directory src to dst |
100 with an optional filename filter.""" | 105 with an optional filename filter.""" |
101 if not os.path.exists(dst): | 106 if not os.path.exists(dst): |
102 os.makedirs(dst) | 107 os.makedirs(dst) |
103 for root, _, files in os.walk(src): | 108 for root, _, files in os.walk(src): |
104 for f in files: | 109 for f in files: |
105 if filename_filter and not re.match(filename_filter, f): | 110 if filename_filter and not re.match(filename_filter, f): |
106 continue | 111 continue |
107 CopyFile(os.path.join(root, f), dst) | 112 CopyFile(os.path.join(root, f), dst) |
108 | 113 |
109 | 114 |
110 def Checkout(name, url, dir): | 115 def Checkout(name, url, dir): |
111 """Checkout the SVN module at url into dir. Use name for the log message.""" | 116 """Checkout the SVN module at url into dir. Use name for the log message.""" |
112 print "Checking out %s r%s into '%s'" % (name, LLVM_WIN_REVISION, dir) | 117 print "Checking out %s r%s into '%s'" % (name, LLVM_WIN_REVISION, dir) |
113 RunCommand(['svn', 'checkout', '--force', | 118 |
114 url + '@' + LLVM_WIN_REVISION, dir], tries=2) | 119 command = ['svn', 'checkout', '--force', url + '@' + LLVM_WIN_REVISION, dir] |
| 120 if RunCommand(command, fail_hard=False): |
| 121 return |
| 122 |
| 123 if os.path.isdir(dir): |
| 124 print "Removing %s." % (dir) |
| 125 RmTree(dir) |
| 126 |
| 127 print "Retrying." |
| 128 RunCommand(command) |
115 | 129 |
116 | 130 |
117 def AddCMakeToPath(): | 131 def AddCMakeToPath(): |
118 """Look for CMake and add it to PATH if it's not there already.""" | 132 """Look for CMake and add it to PATH if it's not there already.""" |
119 try: | 133 try: |
120 # First check if cmake is already on PATH. | 134 # First check if cmake is already on PATH. |
121 subprocess.call(['cmake', '--version']) | 135 subprocess.call(['cmake', '--version']) |
122 return | 136 return |
123 except OSError as e: | 137 except OSError as e: |
124 if e.errno != os.errno.ENOENT: | 138 if e.errno != os.errno.ENOENT: |
(...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
261 | 275 |
262 if re.search(r'\b(make_clang_dir)=', os.environ.get('GYP_DEFINES', '')): | 276 if re.search(r'\b(make_clang_dir)=', os.environ.get('GYP_DEFINES', '')): |
263 print 'Skipping Clang update (make_clang_dir= was set in GYP_DEFINES).' | 277 print 'Skipping Clang update (make_clang_dir= was set in GYP_DEFINES).' |
264 return 0 | 278 return 0 |
265 | 279 |
266 return UpdateClang() | 280 return UpdateClang() |
267 | 281 |
268 | 282 |
269 if __name__ == '__main__': | 283 if __name__ == '__main__': |
270 sys.exit(main()) | 284 sys.exit(main()) |
OLD | NEW |