Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 Loading... | |
| 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( |
| 313 filepath, prevdict, read_only, algo, collapse_symlinks=False): | |
|
M-A Ruel
2017/04/27 17:44:02
no default please
kjlubick
2017/04/27 17:55:37
Done.
| |
| 313 """Processes an input file, a dependency, and return meta data about it. | 314 """Processes an input file, a dependency, and return meta data about it. |
| 314 | 315 |
| 315 Behaviors: | 316 Behaviors: |
| 316 - Retrieves the file mode, file size, file timestamp, file link | 317 - 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 | 318 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. | 319 content if the path points to a file and not a symlink. |
| 319 | 320 |
| 320 Arguments: | 321 Arguments: |
| 321 filepath: File to act on. | 322 filepath: File to act on. |
| 322 prevdict: the previous dictionary. It is used to retrieve the cached sha-1 | 323 prevdict: the previous dictionary. It is used to retrieve the cached sha-1 |
| 323 to skip recalculating the hash. Optional. | 324 to skip recalculating the hash. Optional. |
| 324 read_only: If 1 or 2, the file mode is manipulated. In practice, only save | 325 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 | 326 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 | 327 windows, mode is not set since all files are 'executable' by |
| 327 default. | 328 default. |
| 328 algo: Hashing algorithm used. | 329 algo: Hashing algorithm used. |
|
M-A Ruel
2017/04/27 17:44:02
update
kjlubick
2017/04/27 17:55:37
Done.
| |
| 329 | 330 |
| 330 Returns: | 331 Returns: |
| 331 The necessary dict to create a entry in the 'files' section of an .isolated | 332 The necessary dict to create a entry in the 'files' section of an .isolated |
| 332 file. | 333 file. |
| 333 """ | 334 """ |
| 334 # TODO(maruel): None is not a valid value. | 335 # TODO(maruel): None is not a valid value. |
| 335 assert read_only in (None, 0, 1, 2), read_only | 336 assert read_only in (None, 0, 1, 2), read_only |
| 336 out = {} | 337 out = {} |
| 337 # Always check the file stat and check if it is a link. The timestamp is used | 338 # 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. | 339 # 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. | 340 # 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 | 341 # 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. | 342 # manually while its content changed. We don't protect against that use case. |
| 342 try: | 343 try: |
| 343 filestats = os.lstat(filepath) | 344 filestats = None |
|
M-A Ruel
2017/04/27 17:44:02
not needed
kjlubick
2017/04/27 17:55:37
Done.
| |
| 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 Loading... | |
| 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 |
| OLD | NEW |