OLD | NEW |
1 # Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 # Copyright (c) 2012 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 os | 5 import os |
6 from io import BytesIO | 6 from io import BytesIO |
7 import re | 7 import re |
8 from zipfile import ZipFile | 8 from zipfile import ZipFile |
9 | 9 |
10 import compiled_file_system as compiled_fs | 10 import compiled_file_system as compiled_fs |
11 | 11 |
| 12 # Increment this if the data model changes for ExampleZipper. |
| 13 _VERSION = 1 |
| 14 |
12 class ExampleZipper(object): | 15 class ExampleZipper(object): |
13 """This class creates a zip file given a samples directory. | 16 """This class creates a zip file given a samples directory. |
14 """ | 17 """ |
15 def __init__(self, file_system, cache_factory, base_path): | 18 def __init__(self, file_system, compiled_fs_factory, base_path): |
16 self._base_path = base_path | 19 self._base_path = base_path.rstrip('/') |
17 self._zip_cache = cache_factory.Create(self._MakeZipFile, | 20 self._zip_cache = compiled_fs_factory.Create(self._MakeZipFile, |
18 compiled_fs.ZIP) | 21 ExampleZipper, |
| 22 version=_VERSION) |
19 self._file_system = file_system | 23 self._file_system = file_system |
20 | 24 |
21 def _MakeZipFile(self, base_dir, files): | 25 def _MakeZipFile(self, base_dir, files): |
22 zip_path = os.path.commonprefix(files).rsplit('/', 1)[-2] | 26 if 'manifest.json' not in files: |
23 prefix = zip_path.rsplit('/', 1)[-2] | |
24 if zip_path + '/manifest.json' not in files: | |
25 return None | 27 return None |
26 zip_bytes = BytesIO() | 28 zip_bytes = BytesIO() |
27 zip_file = ZipFile(zip_bytes, mode='w') | 29 zip_file = ZipFile(zip_bytes, mode='w') |
28 try: | 30 try: |
29 for name, file_contents in ( | 31 for name, file_contents in ( |
30 self._file_system.Read(files, binary=True).Get().iteritems()): | 32 self._file_system.Read(['%s%s' % (base_dir, f) for f in files], |
31 zip_file.writestr(name[len(prefix):].strip('/'), file_contents) | 33 binary=True).Get().iteritems()): |
| 34 # We want e.g. basic.zip to expand to basic/manifest.json etc, not |
| 35 # chrome/common/extensions/.../basic/manifest.json, so only use the |
| 36 # end of the path component when writing into the zip file. |
| 37 redundant_prefix = '%s/' % base_dir.rstrip('/').rsplit('/', 1)[0] |
| 38 zip_file.writestr(name[len(redundant_prefix):], file_contents) |
32 finally: | 39 finally: |
33 zip_file.close() | 40 zip_file.close() |
34 return zip_bytes.getvalue() | 41 return zip_bytes.getvalue() |
35 | 42 |
36 def Create(self, path): | 43 def Create(self, path): |
37 """ Creates a new zip file from the recursive contents of |path| | 44 """ Creates a new zip file from the recursive contents of |path| |
38 as returned by |_zip_cache|. | 45 as returned by |_zip_cache|. |
39 Paths within the zip file are given relative to and including |path|. | 46 Paths within the zip file are given relative to and including |path|. |
40 """ | 47 """ |
41 return self._zip_cache.GetFromFileListing( | 48 return self._zip_cache.GetFromFileListing( |
42 self._base_path + '/' + path) | 49 '%s/%s' % (self._base_path, path.strip('/'))) |
OLD | NEW |