| OLD | NEW |
| 1 # Copyright 2013 The Chromium Authors. All rights reserved. | 1 # Copyright 2013 The Chromium Authors. All rights reserved. |
| 2 # Use of this source code is governed by a BSD-style license that can be | 2 # Use of this source code is governed by a BSD-style license that can be |
| 3 # found in the LICENSE file. | 3 # found in the LICENSE file. |
| 4 | 4 |
| 5 import ast | 5 import ast |
| 6 import contextlib | 6 import contextlib |
| 7 import fnmatch | 7 import fnmatch |
| 8 import json | 8 import json |
| 9 import os | 9 import os |
| 10 import pipes | 10 import pipes |
| (...skipping 206 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 217 CheckZipPath(name) | 217 CheckZipPath(name) |
| 218 if no_clobber: | 218 if no_clobber: |
| 219 output_path = os.path.join(path, name) | 219 output_path = os.path.join(path, name) |
| 220 if os.path.exists(output_path): | 220 if os.path.exists(output_path): |
| 221 raise Exception( | 221 raise Exception( |
| 222 'Path already exists from zip: %s %s %s' | 222 'Path already exists from zip: %s %s %s' |
| 223 % (zip_path, name, output_path)) | 223 % (zip_path, name, output_path)) |
| 224 z.extract(name, path) | 224 z.extract(name, path) |
| 225 | 225 |
| 226 | 226 |
| 227 def CreateHermeticZipInfo(zip_path): |
| 228 """Creates a ZipInfo with a zero'ed out timestamp.""" |
| 229 CheckZipPath(zip_path) |
| 230 zipinfo = zipfile.ZipInfo(filename=zip_path, date_time=HERMETIC_TIMESTAMP) |
| 231 zipinfo.external_attr = HERMETIC_FILE_ATTR |
| 232 return zipinfo |
| 233 |
| 234 |
| 227 def DoZip(inputs, output, base_dir=None): | 235 def DoZip(inputs, output, base_dir=None): |
| 228 """Creates a zip file from a list of files. | 236 """Creates a zip file from a list of files. |
| 229 | 237 |
| 230 Args: | 238 Args: |
| 231 inputs: A list of paths to zip, or a list of (zip_path, fs_path) tuples. | 239 inputs: A list of paths to zip, or a list of (zip_path, fs_path) tuples. |
| 232 output: Destination .zip file. | 240 output: Destination .zip file. |
| 233 base_dir: Prefix to strip from inputs. | 241 base_dir: Prefix to strip from inputs. |
| 234 """ | 242 """ |
| 235 input_tuples = [] | 243 input_tuples = [] |
| 236 for tup in inputs: | 244 for tup in inputs: |
| 237 if isinstance(tup, basestring): | 245 if isinstance(tup, basestring): |
| 238 tup = (os.path.relpath(tup, base_dir), tup) | 246 tup = (os.path.relpath(tup, base_dir), tup) |
| 239 input_tuples.append(tup) | 247 input_tuples.append(tup) |
| 240 | 248 |
| 241 # Sort by zip path to ensure stable zip ordering. | 249 # Sort by zip path to ensure stable zip ordering. |
| 242 input_tuples.sort(key=lambda tup: tup[0]) | 250 input_tuples.sort(key=lambda tup: tup[0]) |
| 243 with zipfile.ZipFile(output, 'w') as outfile: | 251 with zipfile.ZipFile(output, 'w') as outfile: |
| 244 for zip_path, fs_path in input_tuples: | 252 for zip_path, fs_path in input_tuples: |
| 245 CheckZipPath(zip_path) | |
| 246 zipinfo = zipfile.ZipInfo(filename=zip_path, date_time=HERMETIC_TIMESTAMP) | |
| 247 zipinfo.external_attr = HERMETIC_FILE_ATTR | |
| 248 with file(fs_path) as f: | 253 with file(fs_path) as f: |
| 249 contents = f.read() | 254 contents = f.read() |
| 250 outfile.writestr(zipinfo, contents) | 255 outfile.writestr(CreateHermeticZipInfo(zip_path), contents) |
| 251 | 256 |
| 252 | 257 |
| 253 def ZipDir(output, base_dir): | 258 def ZipDir(output, base_dir): |
| 254 """Creates a zip file from a directory.""" | 259 """Creates a zip file from a directory.""" |
| 255 inputs = [] | 260 inputs = [] |
| 256 for root, _, files in os.walk(base_dir): | 261 for root, _, files in os.walk(base_dir): |
| 257 for f in files: | 262 for f in files: |
| 258 inputs.append(os.path.join(root, f)) | 263 inputs.append(os.path.join(root, f)) |
| 259 DoZip(inputs, output, base_dir) | 264 DoZip(inputs, output, base_dir) |
| 260 | 265 |
| 261 | 266 |
| 262 def MatchesGlob(path, filters): | 267 def MatchesGlob(path, filters): |
| 263 """Returns whether the given path matches any of the given glob patterns.""" | 268 """Returns whether the given path matches any of the given glob patterns.""" |
| 264 return filters and any(fnmatch.fnmatch(path, f) for f in filters) | 269 return filters and any(fnmatch.fnmatch(path, f) for f in filters) |
| 265 | 270 |
| 266 | 271 |
| 267 def MergeZips(output, inputs, exclude_patterns=None, path_transform=None): | 272 def MergeZips(output, inputs, exclude_patterns=None, path_transform=None): |
| 268 path_transform = path_transform or (lambda p, z: p) | 273 path_transform = path_transform or (lambda p, z: p) |
| 269 added_names = set() | 274 added_names = set() |
| 270 | 275 |
| 271 with zipfile.ZipFile(output, 'w') as out_zip: | 276 with zipfile.ZipFile(output, 'w') as out_zip: |
| 272 for in_file in inputs: | 277 for in_file in inputs: |
| 273 with zipfile.ZipFile(in_file, 'r') as in_zip: | 278 with zipfile.ZipFile(in_file, 'r') as in_zip: |
| 274 for name in in_zip.namelist(): | 279 for name in in_zip.namelist(): |
| 280 # Ignore directories. |
| 281 if name[-1] == '/': |
| 282 continue |
| 275 dst_name = path_transform(name, in_file) | 283 dst_name = path_transform(name, in_file) |
| 276 already_added = dst_name in added_names | 284 already_added = dst_name in added_names |
| 277 if not already_added and not MatchesGlob(dst_name, exclude_patterns): | 285 if not already_added and not MatchesGlob(dst_name, exclude_patterns): |
| 278 zipinfo = zipfile.ZipInfo(filename=dst_name, | 286 out_zip.writestr(CreateHermeticZipInfo(dst_name), in_zip.read(name)) |
| 279 date_time=HERMETIC_TIMESTAMP) | |
| 280 zipinfo.external_attr = HERMETIC_FILE_ATTR | |
| 281 out_zip.writestr(zipinfo, in_zip.read(name)) | |
| 282 added_names.add(dst_name) | 287 added_names.add(dst_name) |
| 283 | 288 |
| 284 | 289 |
| 285 def PrintWarning(message): | 290 def PrintWarning(message): |
| 286 print 'WARNING: ' + message | 291 print 'WARNING: ' + message |
| 287 | 292 |
| 288 | 293 |
| 289 def PrintBigWarning(message): | 294 def PrintBigWarning(message): |
| 290 print '***** ' * 8 | 295 print '***** ' * 8 |
| 291 PrintWarning(message) | 296 PrintWarning(message) |
| (...skipping 154 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 446 | 451 |
| 447 md5_check.CallAndRecordIfStale( | 452 md5_check.CallAndRecordIfStale( |
| 448 on_stale_md5, | 453 on_stale_md5, |
| 449 record_path=record_path, | 454 record_path=record_path, |
| 450 input_paths=input_paths, | 455 input_paths=input_paths, |
| 451 input_strings=input_strings, | 456 input_strings=input_strings, |
| 452 output_paths=output_paths, | 457 output_paths=output_paths, |
| 453 force=force, | 458 force=force, |
| 454 pass_changes=True) | 459 pass_changes=True) |
| 455 | 460 |
| OLD | NEW |