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

Side by Side Diff: build/android/gyp/util/build_utils.py

Issue 1452843002: Use hermetic timestamps in apkbuilder.py and refactor helper function (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: rebase Created 5 years, 1 month 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 | « build/android/gyp/java_google_api_keys.py ('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 # 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
11 import re 11 import re
12 import shlex 12 import shlex
13 import shutil 13 import shutil
14 import subprocess 14 import subprocess
15 import sys 15 import sys
16 import tempfile 16 import tempfile
17 import zipfile 17 import zipfile
18 18
19 # Some clients do not add //build/android/gyp to PYTHONPATH. 19 # Some clients do not add //build/android/gyp to PYTHONPATH.
20 import md5_check # pylint: disable=relative-import 20 import md5_check # pylint: disable=relative-import
21 21
22 sys.path.append(os.path.join(os.path.dirname(__file__), os.pardir, os.pardir)) 22 sys.path.append(os.path.join(os.path.dirname(__file__), os.pardir, os.pardir))
23 from pylib import constants 23 from pylib import constants
24 24
25 COLORAMA_ROOT = os.path.join(constants.DIR_SOURCE_ROOT, 25 COLORAMA_ROOT = os.path.join(constants.DIR_SOURCE_ROOT,
26 'third_party', 'colorama', 'src') 26 'third_party', 'colorama', 'src')
27 # aapt should ignore OWNERS files in addition the default ignore pattern. 27 # aapt should ignore OWNERS files in addition the default ignore pattern.
28 AAPT_IGNORE_PATTERN = ('!OWNERS:!.svn:!.git:!.ds_store:!*.scc:.*:<dir>_*:' + 28 AAPT_IGNORE_PATTERN = ('!OWNERS:!.svn:!.git:!.ds_store:!*.scc:.*:<dir>_*:' +
29 '!CVS:!thumbs.db:!picasa.ini:!*~:!*.d.stamp') 29 '!CVS:!thumbs.db:!picasa.ini:!*~:!*.d.stamp')
30 HERMETIC_TIMESTAMP = (2001, 1, 1, 0, 0, 0) 30 _HERMETIC_TIMESTAMP = (2001, 1, 1, 0, 0, 0)
31 HERMETIC_FILE_ATTR = (0644 << 16L) 31 _HERMETIC_FILE_ATTR = (0644 << 16L)
32 32
33 33
34 @contextlib.contextmanager 34 @contextlib.contextmanager
35 def TempDir(): 35 def TempDir():
36 dirname = tempfile.mkdtemp() 36 dirname = tempfile.mkdtemp()
37 try: 37 try:
38 yield dirname 38 yield dirname
39 finally: 39 finally:
40 shutil.rmtree(dirname) 40 shutil.rmtree(dirname)
41 41
(...skipping 175 matching lines...) Expand 10 before | Expand all | Expand 10 after
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): 227 def AddToZipHermetic(zip_file, zip_path, src_path=None, data=None,
228 """Creates a ZipInfo with a zero'ed out timestamp.""" 228 compress=None):
229 """Adds a file to the given ZipFile with a hard-coded modified time.
230
231 Args:
232 zip_file: ZipFile instance to add the file to.
233 zip_path: Destination path within the zip file.
234 src_path: Path of the source file. Mutually exclusive with |data|.
235 data: File data as a string.
236 compress: Whether to enable compression. Default is take from ZipFile
237 constructor.
238 """
239 assert (src_path is None) != (data is None), (
240 '|src_path| and |data| are mutually exclusive.')
229 CheckZipPath(zip_path) 241 CheckZipPath(zip_path)
230 zipinfo = zipfile.ZipInfo(filename=zip_path, date_time=HERMETIC_TIMESTAMP) 242 zipinfo = zipfile.ZipInfo(filename=zip_path, date_time=_HERMETIC_TIMESTAMP)
231 zipinfo.external_attr = HERMETIC_FILE_ATTR 243 zipinfo.external_attr = _HERMETIC_FILE_ATTR
232 return zipinfo 244
245 if src_path:
246 with file(src_path) as f:
247 data = f.read()
248
249 # zipfile will deflate even when it makes the file bigger. To avoid
250 # growing files, disable compression at an arbitrary cut off point.
251 if len(data) < 16:
252 compress = False
253
254 # None converts to ZIP_STORED, when passed explicitly rather than the
255 # default passed to the ZipFile constructor.
256 args = []
257 if compress is not None:
258 args.append(zipfile.ZIP_DEFLATED if compress else zipfile.ZIP_STORED)
259 zip_file.writestr(zipinfo, data, *args)
233 260
234 261
235 def DoZip(inputs, output, base_dir=None): 262 def DoZip(inputs, output, base_dir=None):
236 """Creates a zip file from a list of files. 263 """Creates a zip file from a list of files.
237 264
238 Args: 265 Args:
239 inputs: A list of paths to zip, or a list of (zip_path, fs_path) tuples. 266 inputs: A list of paths to zip, or a list of (zip_path, fs_path) tuples.
240 output: Destination .zip file. 267 output: Destination .zip file.
241 base_dir: Prefix to strip from inputs. 268 base_dir: Prefix to strip from inputs.
242 """ 269 """
243 input_tuples = [] 270 input_tuples = []
244 for tup in inputs: 271 for tup in inputs:
245 if isinstance(tup, basestring): 272 if isinstance(tup, basestring):
246 tup = (os.path.relpath(tup, base_dir), tup) 273 tup = (os.path.relpath(tup, base_dir), tup)
247 input_tuples.append(tup) 274 input_tuples.append(tup)
248 275
249 # Sort by zip path to ensure stable zip ordering. 276 # Sort by zip path to ensure stable zip ordering.
250 input_tuples.sort(key=lambda tup: tup[0]) 277 input_tuples.sort(key=lambda tup: tup[0])
251 with zipfile.ZipFile(output, 'w') as outfile: 278 with zipfile.ZipFile(output, 'w') as outfile:
252 for zip_path, fs_path in input_tuples: 279 for zip_path, fs_path in input_tuples:
253 with file(fs_path) as f: 280 AddToZipHermetic(outfile, zip_path, src_path=fs_path)
254 contents = f.read()
255 outfile.writestr(CreateHermeticZipInfo(zip_path), contents)
256 281
257 282
258 def ZipDir(output, base_dir): 283 def ZipDir(output, base_dir):
259 """Creates a zip file from a directory.""" 284 """Creates a zip file from a directory."""
260 inputs = [] 285 inputs = []
261 for root, _, files in os.walk(base_dir): 286 for root, _, files in os.walk(base_dir):
262 for f in files: 287 for f in files:
263 inputs.append(os.path.join(root, f)) 288 inputs.append(os.path.join(root, f))
264 DoZip(inputs, output, base_dir) 289 DoZip(inputs, output, base_dir)
265 290
(...skipping 10 matching lines...) Expand all
276 with zipfile.ZipFile(output, 'w') as out_zip: 301 with zipfile.ZipFile(output, 'w') as out_zip:
277 for in_file in inputs: 302 for in_file in inputs:
278 with zipfile.ZipFile(in_file, 'r') as in_zip: 303 with zipfile.ZipFile(in_file, 'r') as in_zip:
279 for name in in_zip.namelist(): 304 for name in in_zip.namelist():
280 # Ignore directories. 305 # Ignore directories.
281 if name[-1] == '/': 306 if name[-1] == '/':
282 continue 307 continue
283 dst_name = path_transform(name, in_file) 308 dst_name = path_transform(name, in_file)
284 already_added = dst_name in added_names 309 already_added = dst_name in added_names
285 if not already_added and not MatchesGlob(dst_name, exclude_patterns): 310 if not already_added and not MatchesGlob(dst_name, exclude_patterns):
286 out_zip.writestr(CreateHermeticZipInfo(dst_name), in_zip.read(name)) 311 AddToZipHermetic(out_zip, dst_name, data=in_zip.read(name))
287 added_names.add(dst_name) 312 added_names.add(dst_name)
288 313
289 314
290 def PrintWarning(message): 315 def PrintWarning(message):
291 print 'WARNING: ' + message 316 print 'WARNING: ' + message
292 317
293 318
294 def PrintBigWarning(message): 319 def PrintBigWarning(message):
295 print '***** ' * 8 320 print '***** ' * 8
296 PrintWarning(message) 321 PrintWarning(message)
(...skipping 154 matching lines...) Expand 10 before | Expand all | Expand 10 after
451 476
452 md5_check.CallAndRecordIfStale( 477 md5_check.CallAndRecordIfStale(
453 on_stale_md5, 478 on_stale_md5,
454 record_path=record_path, 479 record_path=record_path,
455 input_paths=input_paths, 480 input_paths=input_paths,
456 input_strings=input_strings, 481 input_strings=input_strings,
457 output_paths=output_paths, 482 output_paths=output_paths,
458 force=force, 483 force=force,
459 pass_changes=True) 484 pass_changes=True)
460 485
OLDNEW
« no previous file with comments | « build/android/gyp/java_google_api_keys.py ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698