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

Side by Side Diff: client/isolated_format.py

Issue 2844063005: Add option to collapse symlinks in isolate.py (Closed)
Patch Set: Add -L Created 3 years, 7 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 | « client/isolate.py ('k') | client/isolateserver.py » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 # Copyright 2014 The LUCI Authors. All rights reserved. 1 # Copyright 2014 The LUCI Authors. All rights reserved.
2 # Use of this source code is governed under the Apache License, Version 2.0 2 # Use of this source code is governed under the Apache License, Version 2.0
3 # that can be found in the LICENSE file. 3 # that can be found in the LICENSE file.
4 4
5 """Understands .isolated files and can do local operations on them.""" 5 """Understands .isolated files and can do local operations on them."""
6 6
7 import hashlib 7 import hashlib
8 import json 8 import json
9 import logging 9 import logging
10 import os 10 import os
(...skipping 291 matching lines...) Expand 10 before | Expand all | Expand 10 after
302 expand_directory_and_symlink( 302 expand_directory_and_symlink(
303 indir, relfile, blacklist, follow_symlinks)) 303 indir, relfile, blacklist, follow_symlinks))
304 except MappingError as e: 304 except MappingError as e:
305 if not ignore_broken_items: 305 if not ignore_broken_items:
306 raise 306 raise
307 logging.info('warning: %s', e) 307 logging.info('warning: %s', e)
308 return outfiles 308 return outfiles
309 309
310 310
311 @tools.profile 311 @tools.profile
312 def file_to_metadata(filepath, prevdict, read_only, algo): 312 def file_to_metadata(filepath, prevdict, read_only, algo, collapse_symlinks):
313 """Processes an input file, a dependency, and return meta data about it. 313 """Processes an input file, a dependency, and return meta data about it.
314 314
315 Behaviors: 315 Behaviors:
316 - Retrieves the file mode, file size, file timestamp, file link 316 - Retrieves the file mode, file size, file timestamp, file link
317 destination if it is a file link and calcultate the SHA-1 of the file's 317 destination if it is a file link and calcultate the SHA-1 of the file's
318 content if the path points to a file and not a symlink. 318 content if the path points to a file and not a symlink.
319 319
320 Arguments: 320 Arguments:
321 filepath: File to act on. 321 filepath: File to act on.
322 prevdict: the previous dictionary. It is used to retrieve the cached sha-1 322 prevdict: the previous dictionary. It is used to retrieve the cached sha-1
323 to skip recalculating the hash. Optional. 323 to skip recalculating the hash. Optional.
324 read_only: If 1 or 2, the file mode is manipulated. In practice, only save 324 read_only: If 1 or 2, the file mode is manipulated. In practice, only save
325 one of 4 modes: 0755 (rwx), 0644 (rw), 0555 (rx), 0444 (r). On 325 one of 4 modes: 0755 (rwx), 0644 (rw), 0555 (rx), 0444 (r). On
326 windows, mode is not set since all files are 'executable' by 326 windows, mode is not set since all files are 'executable' by
327 default. 327 default.
328 algo: Hashing algorithm used. 328 algo: Hashing algorithm used.
329 collapse_symlinks: True if symlinked files should be treated like they were
330 the normal underlying file.
329 331
330 Returns: 332 Returns:
331 The necessary dict to create a entry in the 'files' section of an .isolated 333 The necessary dict to create a entry in the 'files' section of an .isolated
332 file. 334 file.
333 """ 335 """
334 # TODO(maruel): None is not a valid value. 336 # TODO(maruel): None is not a valid value.
335 assert read_only in (None, 0, 1, 2), read_only 337 assert read_only in (None, 0, 1, 2), read_only
336 out = {} 338 out = {}
337 # Always check the file stat and check if it is a link. The timestamp is used 339 # Always check the file stat and check if it is a link. The timestamp is used
338 # to know if the file's content/symlink destination should be looked into. 340 # to know if the file's content/symlink destination should be looked into.
339 # E.g. only reuse from prevdict if the timestamp hasn't changed. 341 # E.g. only reuse from prevdict if the timestamp hasn't changed.
340 # There is the risk of the file's timestamp being reset to its last value 342 # There is the risk of the file's timestamp being reset to its last value
341 # manually while its content changed. We don't protect against that use case. 343 # manually while its content changed. We don't protect against that use case.
342 try: 344 try:
343 filestats = os.lstat(filepath) 345 if collapse_symlinks:
346 # os.stat follows symbolic links
347 filestats = os.stat(filepath)
348 else:
349 # os.lstat does not follow symbolic links, and thus preserves them.
350 filestats = os.lstat(filepath)
344 except OSError: 351 except OSError:
345 # The file is not present. 352 # The file is not present.
346 raise MappingError('%s is missing' % filepath) 353 raise MappingError('%s is missing' % filepath)
347 is_link = stat.S_ISLNK(filestats.st_mode) 354 is_link = stat.S_ISLNK(filestats.st_mode)
348 355
349 if sys.platform != 'win32': 356 if sys.platform != 'win32':
350 # Ignore file mode on Windows since it's not really useful there. 357 # Ignore file mode on Windows since it's not really useful there.
351 filemode = stat.S_IMODE(filestats.st_mode) 358 filemode = stat.S_IMODE(filestats.st_mode)
352 # Remove write access for group and all access to 'others'. 359 # Remove write access for group and all access to 'others'.
353 filemode &= ~(stat.S_IWGRP | stat.S_IRWXO) 360 filemode &= ~(stat.S_IWGRP | stat.S_IRWXO)
(...skipping 213 matching lines...) Expand 10 before | Expand all | Expand 10 after
567 data['files'] = dict( 574 data['files'] = dict(
568 (k.replace(wrong_path_sep, os.path.sep), v) 575 (k.replace(wrong_path_sep, os.path.sep), v)
569 for k, v in data['files'].iteritems()) 576 for k, v in data['files'].iteritems())
570 for v in data['files'].itervalues(): 577 for v in data['files'].itervalues():
571 if 'l' in v: 578 if 'l' in v:
572 v['l'] = v['l'].replace(wrong_path_sep, os.path.sep) 579 v['l'] = v['l'].replace(wrong_path_sep, os.path.sep)
573 if 'relative_cwd' in data: 580 if 'relative_cwd' in data:
574 data['relative_cwd'] = data['relative_cwd'].replace( 581 data['relative_cwd'] = data['relative_cwd'].replace(
575 wrong_path_sep, os.path.sep) 582 wrong_path_sep, os.path.sep)
576 return data 583 return data
OLDNEW
« no previous file with comments | « client/isolate.py ('k') | client/isolateserver.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698