Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1552)

Side by Side Diff: build/get_syzygy_binaries.py

Issue 337903002: Revert of Bring Syzygy binaries in using a script rather than as a dependency. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 6 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « DEPS ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 #!/usr/bin/env python 1 #!/usr/bin/env python
2 # Copyright 2014 The Chromium Authors. All rights reserved. 2 # Copyright 2014 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 """A utility script for downloading versioned Syzygy binaries.""" 6 """A utility script for downloading versioned Syzygy binaries."""
7 7
8 import cStringIO 8 import cStringIO
9 import hashlib 9 import hashlib
10 import errno
11 import json 10 import json
12 import logging 11 import logging
13 import optparse 12 import optparse
14 import os 13 import os
15 import re 14 import re
16 import shutil 15 import shutil
17 import stat
18 import sys
19 import subprocess 16 import subprocess
20 import urllib2 17 import urllib2
21 import zipfile 18 import zipfile
22 19
23 20
24 _LOGGER = logging.getLogger(os.path.basename(__file__)) 21 _LOGGER = logging.getLogger(os.path.basename(__file__))
25 22
26 # The URL where official builds are archived. 23 # The URL where official builds are archived.
27 _SYZYGY_ARCHIVE_URL = ('http://syzygy-archive.commondatastorage.googleapis.com/' 24 _SYZYGY_ARCHIVE_URL = ('http://syzygy-archive.commondatastorage.googleapis.com/'
28 'builds/official/%(revision)s') 25 'builds/official/%(revision)s')
(...skipping 139 matching lines...) Expand 10 before | Expand all | Expand 10 after
168 return (stored, False) 165 return (stored, False)
169 return (stored, True) 166 return (stored, True)
170 167
171 168
172 def _DirIsEmpty(path): 169 def _DirIsEmpty(path):
173 """Returns true if the given directory is empty, false otherwise.""" 170 """Returns true if the given directory is empty, false otherwise."""
174 for root, dirs, files in os.walk(path): 171 for root, dirs, files in os.walk(path):
175 return not dirs and not files 172 return not dirs and not files
176 173
177 174
178 def _RmTreeHandleReadOnly(func, path, exc):
179 """An error handling function for use with shutil.rmtree. This will
180 detect failures to remove read-only files, and will change their properties
181 prior to removing them. This is necessary on Windows as os.remove will return
182 an access error for read-only files, and git repos contain read-only
183 pack/index files.
184 """
185 excvalue = exc[1]
186 if func in (os.rmdir, os.remove) and excvalue.errno == errno.EACCES:
187 _LOGGER.debug('Removing read-only path: %s', path)
188 os.chmod(path, stat.S_IRWXU | stat.S_IRWXG | stat.S_IRWXO)
189 func(path)
190 else:
191 raise
192
193
194 def _RmTree(path):
195 """A wrapper of shutil.rmtree that handles read-only files."""
196 shutil.rmtree(path, ignore_errors=False, onerror=_RmTreeHandleReadOnly)
197
198
199 def _CleanState(output_dir, state, dry_run=False): 175 def _CleanState(output_dir, state, dry_run=False):
200 """Cleans up files/directories in |output_dir| that are referenced by 176 """Cleans up files/directories in |output_dir| that are referenced by
201 the given |state|. Raises an error if there are local changes. Returns a 177 the given |state|. Raises an error if there are local changes. Returns a
202 dictionary of files that were deleted. 178 dictionary of files that were deleted.
203 """ 179 """
204 _LOGGER.debug('Deleting files from previous installation.') 180 _LOGGER.debug('Deleting files from previous installation.')
205 deleted = {} 181 deleted = {}
206 182
207 # Generate a list of files to delete, relative to |output_dir|. 183 # Generate a list of files to delete, relative to |output_dir|.
208 contents = state['contents'] 184 contents = state['contents']
(...skipping 24 matching lines...) Expand all
233 if not dry_run: 209 if not dry_run:
234 os.unlink(fullpath) 210 os.unlink(fullpath)
235 211
236 # Sort directories from longest name to shortest. This lets us remove empty 212 # Sort directories from longest name to shortest. This lets us remove empty
237 # directories from the most nested paths first. 213 # directories from the most nested paths first.
238 dirs = sorted(dirs.keys(), key=lambda x: len(x), reverse=True) 214 dirs = sorted(dirs.keys(), key=lambda x: len(x), reverse=True)
239 for p in dirs: 215 for p in dirs:
240 if os.path.exists(p) and _DirIsEmpty(p): 216 if os.path.exists(p) and _DirIsEmpty(p):
241 _LOGGER.debug('Deleting empty directory "%s".', p) 217 _LOGGER.debug('Deleting empty directory "%s".', p)
242 if not dry_run: 218 if not dry_run:
243 _RmTree(p) 219 shutil.rmtree(p, False)
244 220
245 return deleted 221 return deleted
246 222
247 223
248 def _Download(url): 224 def _Download(url):
249 """Downloads the given URL and returns the contents as a string.""" 225 """Downloads the given URL and returns the contents as a string."""
250 response = urllib2.urlopen(url) 226 response = urllib2.urlopen(url)
251 if response.code != 200: 227 if response.code != 200:
252 raise RuntimeError('Failed to download "%s".' % url) 228 raise RuntimeError('Failed to download "%s".' % url)
253 return response.read() 229 return response.read()
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after
345 if not _REVISION_RE.match(options.revision): 321 if not _REVISION_RE.match(options.revision):
346 option_parser.error('Must specify a valid SVN or GIT revision.') 322 option_parser.error('Must specify a valid SVN or GIT revision.')
347 323
348 # This just makes output prettier to read. 324 # This just makes output prettier to read.
349 options.output_dir = os.path.normpath(options.output_dir) 325 options.output_dir = os.path.normpath(options.output_dir)
350 326
351 return options 327 return options
352 328
353 329
354 def main(): 330 def main():
355 # We only care about Windows platforms, as the Syzygy binaries aren't used
356 # elsewhere.
357 if sys.platform != 'win32':
358 return
359
360 options = _ParseCommandLine() 331 options = _ParseCommandLine()
361 332
362 if options.dry_run: 333 if options.dry_run:
363 _LOGGER.debug('Performing a dry-run.') 334 _LOGGER.debug('Performing a dry-run.')
364 335
365 # Load the current installation state, and validate it against the 336 # Load the current installation state, and validate it against the
366 # requested installation. 337 # requested installation.
367 state, is_consistent = _GetCurrentState(options.revision, options.output_dir) 338 state, is_consistent = _GetCurrentState(options.revision, options.output_dir)
368 339
369 # Decide whether or not an install is necessary. 340 # Decide whether or not an install is necessary.
370 if options.force: 341 if options.force:
371 _LOGGER.debug('Forcing reinstall of binaries.') 342 _LOGGER.debug('Forcing reinstall of binaries.')
372 elif is_consistent: 343 elif is_consistent:
373 # Avoid doing any work if the contents of the directory are consistent. 344 # Avoid doing any work if the contents of the directory are consistent.
374 _LOGGER.debug('State unchanged, no reinstall necessary.') 345 _LOGGER.debug('State unchanged, no reinstall necessary.')
375 return 346 return
376 347
377 # Under normal logging this is the only only message that will be reported. 348 # Under normal logging this is the only only message that will be reported.
378 _LOGGER.info('Installing revision %s Syzygy binaries.', 349 _LOGGER.info('Installing revision %s Syzygy binaries.',
379 options.revision[0:12]) 350 options.revision[0:12])
380 351
381 # Clean up the old state to begin with. 352 # Clean up the old state to begin with.
382 deleted = [] 353 deleted = []
383 if options.overwrite: 354 if options.overwrite:
384 if os.path.exists(options.output_dir): 355 if os.path.exists(options.output_dir):
385 # If overwrite was specified then take a heavy-handed approach. 356 # If overwrite was specified then take a heavy-handed approach.
386 _LOGGER.debug('Deleting entire installation directory.') 357 _LOGGER.debug('Deleting entire installation directory.')
387 if not options.dry_run: 358 if not options.dry_run:
388 _RmTree(options.output_dir) 359 shutil.rmtree(options.output_dir, False)
389 else: 360 else:
390 # Otherwise only delete things that the previous installation put in place, 361 # Otherwise only delete things that the previous installation put in place,
391 # and take care to preserve any local changes. 362 # and take care to preserve any local changes.
392 deleted = _CleanState(options.output_dir, state, options.dry_run) 363 deleted = _CleanState(options.output_dir, state, options.dry_run)
393 364
394 # Install the new binaries. In a dry-run this will actually download the 365 # Install the new binaries. In a dry-run this will actually download the
395 # archives, but it won't write anything to disk. 366 # archives, but it won't write anything to disk.
396 state = _InstallBinaries(options, deleted) 367 state = _InstallBinaries(options, deleted)
397 368
398 # Build and save the state for the directory. 369 # Build and save the state for the directory.
399 _SaveState(options.output_dir, state, options.dry_run) 370 _SaveState(options.output_dir, state, options.dry_run)
400 371
401 372
402 if __name__ == '__main__': 373 if __name__ == '__main__':
403 main() 374 main()
OLDNEW
« no previous file with comments | « DEPS ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698