Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code

Delta Between Two Patch Sets: packagerEdge.py

Issue 29345751: Issue 4028 - Add support for Edge extensions to buildtools (Closed)
Left Patch Set: Address comments on patch set 8 Created Oct. 11, 2016, 3:52 p.m.
Right Patch Set: Address Windows Store issues with blockmap and devbuild display name Created Oct. 14, 2016, 12:07 p.m.
Left:
Right:
Use n/p to move between diff chunks; N/P to move between comments.
Jump to:
Left: Side by side diff | Download
Right: Side by side diff | Download
« no previous file with change/comment | « packagerChrome.py ('k') | templates/Info.plist.tmpl » ('j') | no next file with change/comment »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
LEFTRIGHT
1 # This Source Code Form is subject to the terms of the Mozilla Public 1 # This Source Code Form is subject to the terms of the Mozilla Public
2 # License, v. 2.0. If a copy of the MPL was not distributed with this 2 # License, v. 2.0. If a copy of the MPL was not distributed with this
3 # file, You can obtain one at http://mozilla.org/MPL/2.0/. 3 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
4 4
5 import base64 5 import base64
6 import hashlib 6 import hashlib
7 import json 7 import json
8 import mimetypes 8 import mimetypes
9 import os 9 import os
10 import sys
11 import zipfile 10 import zipfile
12 11
13 import packager 12 import packager
14 import packagerChrome 13 import packagerChrome
15 14
16 # Files and directories expected inside of the .APPX archive. 15 # Files and directories expected inside of the .APPX archive.
17 MANIFEST = 'AppxManifest.xml' 16 MANIFEST = 'AppxManifest.xml'
18 CONTENT_TYPES = '[Content_Types].xml' 17 CONTENT_TYPES = '[Content_Types].xml'
19 BLOCKMAP = 'AppxBlockMap.xml' 18 BLOCKMAP = 'AppxBlockMap.xml'
20 EXTENSION_DIR = 'Extension' 19 EXTENSION_DIR = 'Extension'
(...skipping 26 matching lines...) Expand all
47 'lfh_size': _lfh_size(filename), 46 'lfh_size': _lfh_size(filename),
48 'blocks': [ 47 'blocks': [
49 {'hash': base64.b64encode(hashlib.sha256(block).digest())} 48 {'hash': base64.b64encode(hashlib.sha256(block).digest())}
50 for block in blocks 49 for block in blocks
51 ] 50 ]
52 } 51 }
53 52
54 53
55 def create_appx_blockmap(files): 54 def create_appx_blockmap(files):
56 """Create APPX blockmap for the list of files.""" 55 """Create APPX blockmap for the list of files."""
56 # We don't support AppxBlockmap.xml generation for compressed zip files at
57 # the moment. The only way to reliably calculate the compressed size of
58 # each 64k chunk in the zip file is to override the relevant parts of
59 # `zipfile` library. We have chosen to not do it so we produce an
60 # uncompressed zip file that is later repackaged by Windows Store with
61 # compression.
57 template = _get_template_for(BLOCKMAP) 62 template = _get_template_for(BLOCKMAP)
58 files = [_make_blockmap_entry(n, d) for n, d in files.items()] 63 files = [_make_blockmap_entry(n, d) for n, d in files.items()]
59 return template.render(files=files).encode('utf-8') 64 return template.render(files=files).encode('utf-8')
60 65
61 66
62 def load_translation(files, locale): 67 def load_translation(files, locale):
63 """Load translation strings for locale from files.""" 68 """Load translation strings for locale from files."""
64 path = '{}/_locales/{}/messages.json'.format(EXTENSION_DIR, locale) 69 path = '{}/_locales/{}/messages.json'.format(EXTENSION_DIR, locale)
65 return json.loads(files[path]) 70 return json.loads(files[path])
66 71
67 72
68 def create_appx_manifest(params, files): 73 def pad_version(version):
74 """Make sure version number has 4 groups of digits."""
75 groups = (version.split('.') + ['0', '0', '0'])[:4]
76 return '.'.join(groups)
77
78
79 def create_appx_manifest(params, files, release_build=False):
69 """Create AppxManifest.xml.""" 80 """Create AppxManifest.xml."""
70 params = dict(params) 81 params = dict(params)
71 metadata = params['metadata'] 82 metadata = params['metadata']
72 w = params['windows_version'] = {} 83 w = params['windows_version'] = {}
73 w['min'], w['max'] = metadata.get('compat', 'windows').split('/') 84 w['min'], w['max'] = metadata.get('compat', 'windows').split('/')
74 params.update(metadata.items('general')) 85 params.update(metadata.items('general'))
86 params['version'] = pad_version(params['version'])
75 87
76 translation = load_translation(files, defaultLocale) 88 translation = load_translation(files, defaultLocale)
77 params['display_name'] = translation['name'] 89 name_key = 'name' if release_build else 'name_devbuild'
78 params['description'] = translation['description'] 90 params['display_name'] = translation[name_key]['message']
91 params['description'] = translation['description']['message']
79 92
80 for size in ['44', '50', '150']: 93 for size in ['44', '50', '150']:
81 path = '{}/logo_{}.png'.format(ASSETS_DIR, size) 94 path = '{}/logo_{}.png'.format(ASSETS_DIR, size)
82 if path not in files: 95 if path not in files:
83 raise KeyError(path + 'is not found in files') 96 raise KeyError(path + 'is not found in files')
84 params['logo_' + size] = path.replace('/', '\\') 97 params['logo_' + size] = path.replace('/', '\\')
85
86 expected_id = '{}.{}'.format(params['author'],
87 params['display_name']).replace(' ', '')
88 if params['app_id'] != expected_id:
89 sys.stderr.write(
90 "WARNING: app_id doesn't match author and display_name: "
91 "'{app_id}' and '{author}' + '{display_name}'\n".format(**params)
92 )
93 98
94 template = _get_template_for(MANIFEST) 99 template = _get_template_for(MANIFEST)
95 return template.render(params).encode('utf-8') 100 return template.render(params).encode('utf-8')
96 101
97 102
98 def move_files_to_extension(files): 103 def move_files_to_extension(files):
99 """Move all files into `Extension` folder for APPX packaging.""" 104 """Move all files into `Extension` folder for APPX packaging."""
100 # We sort the files to ensure that 'Extension/xyz' is moved before 'xyz'. 105 # We sort the files to ensure that 'Extension/xyz' is moved before 'xyz'.
101 # If 'xyz' is moved first, it would overwrite 'Extension/xyz' and its 106 # If 'xyz' is moved first, it would overwrite 'Extension/xyz' and its
102 # original content would be lost. 107 # original content would be lost.
(...skipping 28 matching lines...) Expand all
131 metadata = packager.readMetadata(baseDir, type) 136 metadata = packager.readMetadata(baseDir, type)
132 version = packager.getBuildVersion(baseDir, metadata, releaseBuild, 137 version = packager.getBuildVersion(baseDir, metadata, releaseBuild,
133 buildNum) 138 buildNum)
134 139
135 outfile = outFile or packager.getDefaultFileName(metadata, version, 'appx') 140 outfile = outFile or packager.getDefaultFileName(metadata, version, 'appx')
136 141
137 params = { 142 params = {
138 'type': type, 143 'type': type,
139 'baseDir': baseDir, 144 'baseDir': baseDir,
140 'releaseBuild': releaseBuild, 145 'releaseBuild': releaseBuild,
141 'version': version, 146 'version': version,
Sebastian Noack 2016/10/12 14:43:27 As figured out during testing, and discussed on IR
Vasily Kuznetsov 2016/10/13 11:56:36 I've done it inside of appx manifest generation in
142 'devenv': devenv, 147 'devenv': devenv,
143 'metadata': metadata, 148 'metadata': metadata,
144 } 149 }
145 150
146 files = packager.Files(packagerChrome.getPackageFiles(params), 151 files = packager.Files(packagerChrome.getPackageFiles(params),
147 packagerChrome.getIgnoredFiles(params)) 152 packagerChrome.getIgnoredFiles(params))
148 153
149 if metadata.has_section('mapping'): 154 if metadata.has_section('mapping'):
150 mapped = metadata.items('mapping') 155 mapped = metadata.items('mapping')
151 files.readMappedFiles(mapped) 156 files.readMappedFiles(mapped)
(...skipping 12 matching lines...) Expand all
164 169
165 files['manifest.json'] = packagerChrome.createManifest(params, files) 170 files['manifest.json'] = packagerChrome.createManifest(params, files)
166 171
167 move_files_to_extension(files) 172 move_files_to_extension(files)
168 173
169 if metadata.has_section('appx_assets'): 174 if metadata.has_section('appx_assets'):
170 for name, path in metadata.items('appx_assets'): 175 for name, path in metadata.items('appx_assets'):
171 path = os.path.join(baseDir, path) 176 path = os.path.join(baseDir, path)
172 files.read(path, '{}/{}'.format(ASSETS_DIR, name)) 177 files.read(path, '{}/{}'.format(ASSETS_DIR, name))
173 178
174 files[MANIFEST] = create_appx_manifest(params, files) 179 files[MANIFEST] = create_appx_manifest(params, files, releaseBuild)
180 files[BLOCKMAP] = create_appx_blockmap(files)
175 files[CONTENT_TYPES] = create_content_types_map(files.keys() + [BLOCKMAP]) 181 files[CONTENT_TYPES] = create_content_types_map(files.keys() + [BLOCKMAP])
176 182
177 # We don't support AppxBlockmap.xml generation for compressed zip files at
178 # the moment. The only way to reliably calculate the compressed size of
179 # each 64k chunk in the zip file is to override the relevant parts of
180 # `zipfile` library. We have chosen to not do it so we produce an
181 # uncompressed zip file that is later repackaged by Windows Store with
182 # compression.
183 files[BLOCKMAP] = create_appx_blockmap(files)
184 files.zip(outfile, compression=zipfile.ZIP_STORED) 183 files.zip(outfile, compression=zipfile.ZIP_STORED)
LEFTRIGHT

Powered by Google App Engine
This is Rietveld