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 |