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 |
11 import re | 11 import re |
12 import shlex | 12 import shlex |
13 import shutil | 13 import shutil |
14 import stat | |
14 import subprocess | 15 import subprocess |
15 import sys | 16 import sys |
16 import tempfile | 17 import tempfile |
17 import zipfile | 18 import zipfile |
18 | 19 |
19 # Some clients do not add //build/android/gyp to PYTHONPATH. | 20 # Some clients do not add //build/android/gyp to PYTHONPATH. |
20 import md5_check # pylint: disable=relative-import | 21 import md5_check # pylint: disable=relative-import |
21 | 22 |
22 sys.path.append(os.path.join(os.path.dirname(__file__), os.pardir, os.pardir)) | 23 sys.path.append(os.path.join(os.path.dirname(__file__), os.pardir, os.pardir)) |
23 from pylib.constants import host_paths | 24 from pylib.constants import host_paths |
(...skipping 167 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
191 return device_state.strip() == 'device' | 192 return device_state.strip() == 'device' |
192 | 193 |
193 | 194 |
194 def CheckZipPath(name): | 195 def CheckZipPath(name): |
195 if os.path.normpath(name) != name: | 196 if os.path.normpath(name) != name: |
196 raise Exception('Non-canonical zip path: %s' % name) | 197 raise Exception('Non-canonical zip path: %s' % name) |
197 if os.path.isabs(name): | 198 if os.path.isabs(name): |
198 raise Exception('Absolute zip path: %s' % name) | 199 raise Exception('Absolute zip path: %s' % name) |
199 | 200 |
200 | 201 |
202 def IsSymlink(zip_file, name): | |
203 zi = zip_file.getinfo(name) | |
204 | |
205 # The two high-order bytes of ZipInfo.external_attr represent | |
206 # UNIX permissions and file type bits. | |
207 if stat.S_ISLNK(zi.external_attr >> 16L): | |
jbudorick
2016/01/30 17:33:37
nit: just
return stat.S_ISLNK(zi.external_attr
Mostyn Bramley-Moore
2016/01/30 17:41:25
Done.
| |
208 return True | |
209 | |
210 return False | |
211 | |
212 | |
201 def ExtractAll(zip_path, path=None, no_clobber=True, pattern=None, | 213 def ExtractAll(zip_path, path=None, no_clobber=True, pattern=None, |
202 predicate=None): | 214 predicate=None): |
203 if path is None: | 215 if path is None: |
204 path = os.getcwd() | 216 path = os.getcwd() |
205 elif not os.path.exists(path): | 217 elif not os.path.exists(path): |
206 MakeDirectory(path) | 218 MakeDirectory(path) |
207 | 219 |
208 with zipfile.ZipFile(zip_path) as z: | 220 with zipfile.ZipFile(zip_path) as z: |
209 for name in z.namelist(): | 221 for name in z.namelist(): |
210 if name.endswith('/'): | 222 if name.endswith('/'): |
211 continue | 223 continue |
212 if pattern is not None: | 224 if pattern is not None: |
213 if not fnmatch.fnmatch(name, pattern): | 225 if not fnmatch.fnmatch(name, pattern): |
214 continue | 226 continue |
215 if predicate and not predicate(name): | 227 if predicate and not predicate(name): |
216 continue | 228 continue |
217 CheckZipPath(name) | 229 CheckZipPath(name) |
218 if no_clobber: | 230 if no_clobber: |
219 output_path = os.path.join(path, name) | 231 output_path = os.path.join(path, name) |
220 if os.path.exists(output_path): | 232 if os.path.exists(output_path): |
221 raise Exception( | 233 raise Exception( |
222 'Path already exists from zip: %s %s %s' | 234 'Path already exists from zip: %s %s %s' |
223 % (zip_path, name, output_path)) | 235 % (zip_path, name, output_path)) |
224 z.extract(name, path) | 236 if IsSymlink(z, name): |
237 dest = os.path.join(path, name) | |
238 MakeDirectory(os.path.dirname(dest)) | |
239 os.symlink(z.read(name), dest) | |
240 else: | |
241 z.extract(name, path) | |
225 | 242 |
226 | 243 |
227 def AddToZipHermetic(zip_file, zip_path, src_path=None, data=None, | 244 def AddToZipHermetic(zip_file, zip_path, src_path=None, data=None, |
228 compress=None): | 245 compress=None): |
229 """Adds a file to the given ZipFile with a hard-coded modified time. | 246 """Adds a file to the given ZipFile with a hard-coded modified time. |
230 | 247 |
231 Args: | 248 Args: |
232 zip_file: ZipFile instance to add the file to. | 249 zip_file: ZipFile instance to add the file to. |
233 zip_path: Destination path within the zip file. | 250 zip_path: Destination path within the zip file. |
234 src_path: Path of the source file. Mutually exclusive with |data|. | 251 src_path: Path of the source file. Mutually exclusive with |data|. |
(...skipping 241 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
476 | 493 |
477 md5_check.CallAndRecordIfStale( | 494 md5_check.CallAndRecordIfStale( |
478 on_stale_md5, | 495 on_stale_md5, |
479 record_path=record_path, | 496 record_path=record_path, |
480 input_paths=input_paths, | 497 input_paths=input_paths, |
481 input_strings=input_strings, | 498 input_strings=input_strings, |
482 output_paths=output_paths, | 499 output_paths=output_paths, |
483 force=force, | 500 force=force, |
484 pass_changes=True) | 501 pass_changes=True) |
485 | 502 |
OLD | NEW |