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

Delta Between Two Patch Sets: packagerChrome.py

Issue 29562599: Issue 5751 - Removing legacy gecko support (Closed)
Left Patch Set: Created Oct. 2, 2017, 10:33 a.m.
Right Patch Set: Rebase against current master ( 489:293593da6033 ) Created Oct. 10, 2017, 9:25 a.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
« build.py ('K') | « packager.py ('k') | packagerGecko.py » ('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 errno 5 import errno
6 import io 6 import io
7 import json 7 import json
8 import os 8 import os
9 import re 9 import re
10 from StringIO import StringIO 10 from StringIO import StringIO
11 import struct 11 import struct
12 import sys 12 import sys
13 import collections 13 import collections
14 import glob
14 15
15 from packager import (readMetadata, getDefaultFileName, getBuildVersion, 16 from packager import (readMetadata, getDefaultFileName, getBuildVersion,
16 getTemplate, Files) 17 getTemplate, Files)
17 18
18 defaultLocale = 'en_US' 19 defaultLocale = 'en_US'
19 20
20 21
21 def getIgnoredFiles(params): 22 def getIgnoredFiles(params):
22 return {'store.description'} 23 return {'store.description'}
23 24
(...skipping 160 matching lines...) Expand 10 before | Expand all | Expand 10 after
184 185
185 186
186 def toJson(data): 187 def toJson(data):
187 return json.dumps( 188 return json.dumps(
188 data, ensure_ascii=False, sort_keys=True, 189 data, ensure_ascii=False, sort_keys=True,
189 indent=2, separators=(',', ': ') 190 indent=2, separators=(',', ': ')
190 ).encode('utf-8') + '\n' 191 ).encode('utf-8') + '\n'
191 192
192 193
193 def import_locales(params, files): 194 def import_locales(params, files):
194 import localeTools 195 for item in params['metadata'].items('import_locales'):
195 196 filename, keys = item
196 # FIXME: localeTools doesn't use real Chrome locales, it uses dash as 197 for sourceFile in glob.glob(os.path.join(os.path.dirname(item.source),
197 # separator instead. 198 *filename.split('/'))):
198 convert_locale_code = lambda code: code.replace('-', '_') 199 locale = sourceFile.split(os.path.sep)[-2]
199 200 targetFile = os.path.join('_locales', locale, 'messages.json')
200 # We need to map Chrome locales to Gecko locales. Start by mapping Chrome 201 data = json.loads(files.get(targetFile, '{}').decode('utf-8'))
201 # locales to themselves, merely with the dash as separator.
202 locale_mapping = {convert_locale_code(l): l for l in localeTools.chromeLocal es}
203
204 # Convert values to Crowdin locales first (use Chrome => Crowdin mapping).
205 for chrome_locale, crowdin_locale in localeTools.langMappingChrome.iteritems ():
206 locale_mapping[convert_locale_code(chrome_locale)] = crowdin_locale
207
208 # Now convert values to Gecko locales (use Gecko => Crowdin mapping).
209 reverse_mapping = {v: k for k, v in locale_mapping.iteritems()}
210 for gecko_locale, crowdin_locale in localeTools.langMappingGecko.iteritems() :
211 if crowdin_locale in reverse_mapping:
212 locale_mapping[reverse_mapping[crowdin_locale]] = gecko_locale
213
214 for target, source in locale_mapping.iteritems():
215 targetFile = '_locales/%s/messages.json' % target
216 if not targetFile in files:
217 continue
218
219 for item in params['metadata'].items('import_locales'):
220 fileName, keys = item
221 parts = map(lambda n: source if n == '*' else n, fileName.split('/') )
222 sourceFile = os.path.join(os.path.dirname(item.source), *parts)
223 incompleteMarker = os.path.join(os.path.dirname(sourceFile), '.incom plete')
224 if not os.path.exists(sourceFile) or os.path.exists(incompleteMarker ):
225 continue
226
227 data = json.loads(files[targetFile].decode('utf-8'))
228 202
229 try: 203 try:
230 with io.open(sourceFile, 'r', encoding='utf-8') as handle: 204 with io.open(sourceFile, 'r', encoding='utf-8') as handle:
231 sourceData = json.load(handle) 205 sourceData = json.load(handle)
232 206
233 # Resolve wildcard imports 207 # Resolve wildcard imports
234 if keys == '*' or keys == '=*': 208 if keys == '*':
235 importList = sourceData.keys() 209 importList = sourceData.keys()
236 importList = filter(lambda k: not k.startswith('_'), importL ist) 210 importList = filter(lambda k: not k.startswith('_'), importL ist)
237 if keys == '=*':
238 importList = map(lambda k: '=' + k, importList)
239 keys = ' '.join(importList) 211 keys = ' '.join(importList)
240 212
241 for stringID in keys.split(): 213 for stringID in keys.split():
242 noMangling = False
243 if stringID.startswith('='):
244 stringID = stringID[1:]
245 noMangling = True
246
247 if stringID in sourceData: 214 if stringID in sourceData:
248 if noMangling: 215 if stringID in data:
249 key = re.sub(r'\W', '_', stringID) 216 print ('Warning: locale string {} defined multiple'
250 else: 217 ' times').format(stringID)
251 key = re.sub(r'\..*', '', parts[-1]) + '_' + re.sub( r'\W', '_', stringID) 218
252 if key in data: 219 data[stringID] = sourceData[stringID]
253 print 'Warning: locale string %s defined multiple ti mes' % key
254
255 data[key] = sourceData[stringID]
256 except Exception as e: 220 except Exception as e:
257 print 'Warning: error importing locale data from %s: %s' % (sour ceFile, e) 221 print 'Warning: error importing locale data from %s: %s' % (sour ceFile, e)
258 222
259 files[targetFile] = toJson(data) 223 files[targetFile] = toJson(data)
260 224
261 225
262 def truncate(text, length_limit): 226 def truncate(text, length_limit):
263 if len(text) <= length_limit: 227 if len(text) <= length_limit:
264 return text 228 return text
265 return text[:length_limit - 1].rstrip() + u'\u2026' 229 return text[:length_limit - 1].rstrip() + u'\u2026'
266 230
267 231
268 def fixTranslationsForChrome(files): 232 def fix_translations_for_chrome(files):
269 defaults = {} 233 defaults = {}
270 data = json.loads(files['_locales/%s/messages.json' % defaultLocale]) 234 data = json.loads(files['_locales/%s/messages.json' % defaultLocale])
271 for match in re.finditer(r'__MSG_(\S+)__', files['manifest.json']): 235 for match in re.finditer(r'__MSG_(\S+)__', files['manifest.json']):
272 name = match.group(1) 236 name = match.group(1)
273 defaults[name] = data[name] 237 defaults[name] = data[name]
274 238
275 limits = {} 239 limits = {}
276 manifest = json.loads(files['manifest.json']) 240 manifest = json.loads(files['manifest.json'])
277 for key, limit in (('name', 45), ('description', 132), ('short_name', 12)): 241 for key, limit in (('name', 45), ('description', 132), ('short_name', 12)):
278 match = re.search(r'__MSG_(\S+)__', manifest.get(key, '')) 242 match = re.search(r'__MSG_(\S+)__', manifest.get(key, ''))
279 if match: 243 if match:
280 limits[match.group(1)] = limit 244 limits[match.group(1)] = limit
281 245
282 for path in list(files): 246 for path in list(files):
283 match = re.search(r'^_locales/(?:es_(AR|CL|(MX))|[^/]+)/(.*)', path) 247 match = re.search(r'^_locales/(?:es_(AR|CL|(MX))|[^/]+)/(.*)', path)
284 if match: 248 if not match:
285 isLatAm, isMexican, filename = match.groups() 249 continue
286 250
287 # The Chrome Web Store requires messages used in manifest.json to be 251 # The Chrome Web Store requires messages used in manifest.json to
288 # present in all languages, and enforces length limits on extension 252 # be present in all languages, and enforces length limits on
289 # name and description. 253 # extension name and description.
290 if filename == 'messages.json': 254 is_latam, is_mexican, filename = match.groups()
291 data = json.loads(files[path]) 255 if filename == 'messages.json':
292 for name, info in defaults.iteritems(): 256 data = json.loads(files[path])
293 data.setdefault(name, info) 257 for name, info in defaults.iteritems():
294 for name, limit in limits.iteritems(): 258 data.setdefault(name, info)
295 info = data.get(name) 259 for name, limit in limits.iteritems():
296 if info: 260 info = data.get(name)
297 info['message'] = truncate(info['message'], limit) 261 if info:
298 files[path] = toJson(data) 262 info['message'] = truncate(info['message'], limit)
299 263 files[path] = toJson(data)
300 # Chrome combines Latin American dialects of Spanish into es-419. 264
301 if isLatAm: 265 # Chrome combines Latin American dialects of Spanish into es-419.
302 data = files.pop(path) 266 if is_latam:
303 if isMexican: 267 data = files.pop(path)
304 files['_locales/es_419/' + filename] = data 268 if is_mexican:
269 files['_locales/es_419/' + filename] = data
305 270
306 271
307 def signBinary(zipdata, keyFile): 272 def signBinary(zipdata, keyFile):
308 from Crypto.Hash import SHA 273 from Crypto.Hash import SHA
309 from Crypto.PublicKey import RSA 274 from Crypto.PublicKey import RSA
310 from Crypto.Signature import PKCS1_v1_5 275 from Crypto.Signature import PKCS1_v1_5
311 276
312 try: 277 try:
313 with open(keyFile, 'rb') as file: 278 with open(keyFile, 'rb') as file:
314 key = RSA.importKey(file.read()) 279 key = RSA.importKey(file.read())
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
374 files.preprocess( 339 files.preprocess(
375 [f for f, _ in metadata.items('preprocess')], 340 [f for f, _ in metadata.items('preprocess')],
376 {'needsExt': True} 341 {'needsExt': True}
377 ) 342 )
378 343
379 if metadata.has_section('import_locales'): 344 if metadata.has_section('import_locales'):
380 import_locales(params, files) 345 import_locales(params, files)
381 346
382 files['manifest.json'] = createManifest(params, files) 347 files['manifest.json'] = createManifest(params, files)
383 if type == 'chrome': 348 if type == 'chrome':
384 fixTranslationsForChrome(files) 349 fix_translations_for_chrome(files)
385 350
386 if devenv: 351 if devenv:
387 import buildtools 352 import buildtools
388 import random 353 import random
389 files.read(os.path.join(buildtools.__path__[0], 'chromeDevenvPoller__.js '), relpath='devenvPoller__.js') 354 files.read(os.path.join(buildtools.__path__[0], 'chromeDevenvPoller__.js '), relpath='devenvPoller__.js')
390 files['devenvVersion__'] = str(random.random()) 355 files['devenvVersion__'] = str(random.random())
391 356
392 if metadata.has_option('general', 'testScripts'): 357 if metadata.has_option('general', 'testScripts'):
393 files['qunit/index.html'] = createScriptPage( 358 files['qunit/index.html'] = createScriptPage(
394 params, 'testIndex.html.tmpl', ('general', 'testScripts') 359 params, 'testIndex.html.tmpl', ('general', 'testScripts')
395 ) 360 )
396 361
397 zipdata = files.zipToString() 362 zipdata = files.zipToString()
398 signature = None 363 signature = None
399 pubkey = None 364 pubkey = None
400 if keyFile != None: 365 if keyFile != None:
401 signature = signBinary(zipdata, keyFile) 366 signature = signBinary(zipdata, keyFile)
402 pubkey = getPublicKey(keyFile) 367 pubkey = getPublicKey(keyFile)
403 writePackage(outFile, pubkey, signature, zipdata) 368 writePackage(outFile, pubkey, signature, zipdata)
LEFTRIGHT

Powered by Google App Engine
This is Rietveld