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

Side by Side Diff: build/get_syzygy_binaries.py

Issue 306543006: 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: Fix to script to handle read-only git files. 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
« DEPS ('K') | « 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
10 import json 11 import json
11 import logging 12 import logging
12 import optparse 13 import optparse
13 import os 14 import os
14 import re 15 import re
15 import shutil 16 import shutil
17 import stat
16 import subprocess 18 import subprocess
17 import urllib2 19 import urllib2
18 import zipfile 20 import zipfile
19 21
20 22
21 _LOGGER = logging.getLogger(os.path.basename(__file__)) 23 _LOGGER = logging.getLogger(os.path.basename(__file__))
22 24
23 # The URL where official builds are archived. 25 # The URL where official builds are archived.
24 _SYZYGY_ARCHIVE_URL = ('http://syzygy-archive.commondatastorage.googleapis.com/' 26 _SYZYGY_ARCHIVE_URL = ('http://syzygy-archive.commondatastorage.googleapis.com/'
25 'builds/official/%(revision)s') 27 'builds/official/%(revision)s')
(...skipping 139 matching lines...) Expand 10 before | Expand all | Expand 10 after
165 return (stored, False) 167 return (stored, False)
166 return (stored, True) 168 return (stored, True)
167 169
168 170
169 def _DirIsEmpty(path): 171 def _DirIsEmpty(path):
170 """Returns true if the given directory is empty, false otherwise.""" 172 """Returns true if the given directory is empty, false otherwise."""
171 for root, dirs, files in os.walk(path): 173 for root, dirs, files in os.walk(path):
172 return not dirs and not files 174 return not dirs and not files
173 175
174 176
177 def _RmTreeHandleReadOnly(func, path, exc):
178 """An error handling function for use with shutil.rmtree. This will
179 detect failures to remove read-only files, and will change their properties
180 prior to removing them. This is necessary on Windows as os.remove will return
181 an access error for read-only files, and git repos contain read-only
182 pack/index files.
183 """
184 excvalue = exc[1]
185 if func in (os.rmdir, os.remove) and excvalue.errno == errno.EACCES:
186 _LOGGER.debug('Removing read-only file: %s', path)
Sigurður Ásgeirsson 2014/05/28 15:24:12 nit: ...or directory...?
chrisha 2014/05/28 15:40:50 Done.
187 os.chmod(path, stat.S_IRWXU | stat.S_IRWXG | stat.S_IRWXO)
188 func(path)
189 else:
190 raise
191
192
193 def _RmTree(path):
194 """A wrapper of shutil.rmtree that handles read-only files."""
195 shutil.rmtree(path, ignore_errors=False, onerror=_RmTreeHandleReadOnly)
196
197
175 def _CleanState(output_dir, state, dry_run=False): 198 def _CleanState(output_dir, state, dry_run=False):
176 """Cleans up files/directories in |output_dir| that are referenced by 199 """Cleans up files/directories in |output_dir| that are referenced by
177 the given |state|. Raises an error if there are local changes. Returns a 200 the given |state|. Raises an error if there are local changes. Returns a
178 dictionary of files that were deleted. 201 dictionary of files that were deleted.
179 """ 202 """
180 _LOGGER.debug('Deleting files from previous installation.') 203 _LOGGER.debug('Deleting files from previous installation.')
181 deleted = {} 204 deleted = {}
182 205
183 # Generate a list of files to delete, relative to |output_dir|. 206 # Generate a list of files to delete, relative to |output_dir|.
184 contents = state['contents'] 207 contents = state['contents']
(...skipping 24 matching lines...) Expand all
209 if not dry_run: 232 if not dry_run:
210 os.unlink(fullpath) 233 os.unlink(fullpath)
211 234
212 # Sort directories from longest name to shortest. This lets us remove empty 235 # Sort directories from longest name to shortest. This lets us remove empty
213 # directories from the most nested paths first. 236 # directories from the most nested paths first.
214 dirs = sorted(dirs.keys(), key=lambda x: len(x), reverse=True) 237 dirs = sorted(dirs.keys(), key=lambda x: len(x), reverse=True)
215 for p in dirs: 238 for p in dirs:
216 if os.path.exists(p) and _DirIsEmpty(p): 239 if os.path.exists(p) and _DirIsEmpty(p):
217 _LOGGER.debug('Deleting empty directory "%s".', p) 240 _LOGGER.debug('Deleting empty directory "%s".', p)
218 if not dry_run: 241 if not dry_run:
219 shutil.rmtree(p, False) 242 _RmTree(p)
220 243
221 return deleted 244 return deleted
222 245
223 246
224 def _Download(url): 247 def _Download(url):
225 """Downloads the given URL and returns the contents as a string.""" 248 """Downloads the given URL and returns the contents as a string."""
226 response = urllib2.urlopen(url) 249 response = urllib2.urlopen(url)
227 if response.code != 200: 250 if response.code != 200:
228 raise RuntimeError('Failed to download "%s".' % url) 251 raise RuntimeError('Failed to download "%s".' % url)
229 return response.read() 252 return response.read()
(...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after
349 _LOGGER.info('Installing revision %s Syzygy binaries.', 372 _LOGGER.info('Installing revision %s Syzygy binaries.',
350 options.revision[0:12]) 373 options.revision[0:12])
351 374
352 # Clean up the old state to begin with. 375 # Clean up the old state to begin with.
353 deleted = [] 376 deleted = []
354 if options.overwrite: 377 if options.overwrite:
355 if os.path.exists(options.output_dir): 378 if os.path.exists(options.output_dir):
356 # If overwrite was specified then take a heavy-handed approach. 379 # If overwrite was specified then take a heavy-handed approach.
357 _LOGGER.debug('Deleting entire installation directory.') 380 _LOGGER.debug('Deleting entire installation directory.')
358 if not options.dry_run: 381 if not options.dry_run:
359 shutil.rmtree(options.output_dir, False) 382 _RmTree(options.output_dir)
360 else: 383 else:
361 # Otherwise only delete things that the previous installation put in place, 384 # Otherwise only delete things that the previous installation put in place,
362 # and take care to preserve any local changes. 385 # and take care to preserve any local changes.
363 deleted = _CleanState(options.output_dir, state, options.dry_run) 386 deleted = _CleanState(options.output_dir, state, options.dry_run)
364 387
365 # Install the new binaries. In a dry-run this will actually download the 388 # Install the new binaries. In a dry-run this will actually download the
366 # archives, but it won't write anything to disk. 389 # archives, but it won't write anything to disk.
367 state = _InstallBinaries(options, deleted) 390 state = _InstallBinaries(options, deleted)
368 391
369 # Build and save the state for the directory. 392 # Build and save the state for the directory.
370 _SaveState(options.output_dir, state, options.dry_run) 393 _SaveState(options.output_dir, state, options.dry_run)
371 394
372 395
373 if __name__ == '__main__': 396 if __name__ == '__main__':
374 main() 397 main()
OLDNEW
« DEPS ('K') | « DEPS ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698