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

Side by Side Diff: build.py

Issue 29562599: Issue 5751 - Removing legacy gecko support (Closed)
Patch Set: Rebasing, addressing comments Created Oct. 5, 2017, 10:05 a.m.
Left:
Right:
Use n/p to move between diff chunks; N/P to move between comments.
Jump to:
View unified diff | Download patch
« no previous file with comments | « LocaleTester.pm ('k') | lib/hooks.js » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 os 5 import os
6 import sys 6 import sys
7 import re 7 import re
8 import subprocess 8 import subprocess
9 import shutil 9 import shutil
10 import buildtools 10 import buildtools
11 from getopt import getopt, GetoptError 11 from getopt import getopt, GetoptError
12 from StringIO import StringIO 12 from StringIO import StringIO
13 from zipfile import ZipFile 13 from zipfile import ZipFile
14 14
15 knownTypes = ('gecko', 'gecko-webext', 'chrome', 'safari', 'generic', 'edge') 15 knownTypes = ('gecko-webext', 'chrome', 'safari', 'generic', 'edge')
16 16
17 17
18 class Command(object): 18 class Command(object):
19 name = property(lambda self: self._name) 19 name = property(lambda self: self._name)
20 shortDescription = property( 20 shortDescription = property(
21 lambda self: self._shortDescription, 21 lambda self: self._shortDescription,
22 lambda self, value: self.__dict__.update({'_shortDescription': value}) 22 lambda self, value: self.__dict__.update({'_shortDescription': value})
23 ) 23 )
24 description = property( 24 description = property(
25 lambda self: self._description, 25 lambda self: self._description,
(...skipping 145 matching lines...) Expand 10 before | Expand all | Expand 10 after
171 'name': command.name, 171 'name': command.name,
172 'params': command.params, 172 'params': command.params,
173 'description': description, 173 'description': description,
174 'options': '\n'.join(options) 174 'options': '\n'.join(options)
175 } 175 }
176 176
177 177
178 def runBuild(baseDir, scriptName, opts, args, type): 178 def runBuild(baseDir, scriptName, opts, args, type):
179 kwargs = {} 179 kwargs = {}
180 for option, value in opts: 180 for option, value in opts:
181 if option in {'-l', '--locales'} and type == 'gecko': 181 if option in {'-b', '--build'}:
182 kwargs['locales'] = value.split(',')
183 elif option in {'-b', '--build'}:
184 kwargs['buildNum'] = value 182 kwargs['buildNum'] = value
185 no_gecko_build = type not in {'gecko', 'gecko-webext'} 183 if type != 'gecko-webext' and not kwargs['buildNum'].isdigit():
186 if no_gecko_build and not kwargs['buildNum'].isdigit():
187 raise TypeError('Build number must be numerical') 184 raise TypeError('Build number must be numerical')
188 elif option in {'-k', '--key'}: 185 elif option in {'-k', '--key'}:
189 kwargs['keyFile'] = value 186 kwargs['keyFile'] = value
190 elif option in {'-m', '--multi-compartment'} and type == 'gecko':
191 kwargs['multicompartment'] = True
192 elif option in {'-r', '--release'}: 187 elif option in {'-r', '--release'}:
193 kwargs['releaseBuild'] = True 188 kwargs['releaseBuild'] = True
194 if len(args) > 0: 189 if len(args) > 0:
195 kwargs['outFile'] = args[0] 190 kwargs['outFile'] = args[0]
196 191
197 if type == 'gecko': 192 if type in {'chrome', 'gecko-webext'}:
198 import buildtools.packagerGecko as packager
199 elif type in {'chrome', 'gecko-webext'}:
200 import buildtools.packagerChrome as packager 193 import buildtools.packagerChrome as packager
201 elif type == 'safari': 194 elif type == 'safari':
202 import buildtools.packagerSafari as packager 195 import buildtools.packagerSafari as packager
203 elif type == 'edge': 196 elif type == 'edge':
204 import buildtools.packagerEdge as packager 197 import buildtools.packagerEdge as packager
205 198
206 packager.createBuild(baseDir, type=type, **kwargs) 199 packager.createBuild(baseDir, type=type, **kwargs)
207 200
208 201
209 def runAutoInstall(baseDir, scriptName, opts, args, type):
210 if len(args) == 0:
211 print 'Port of the Extension Auto-Installer needs to be specified'
212 usage(scriptName, type, 'autoinstall')
213 return
214
215 multicompartment = False
216 for option, value in opts:
217 if option in ('-m', '--multi-compartment'):
218 multicompartment = True
219
220 if ':' in args[0]:
221 host, port = args[0].rsplit(':', 1)
222 else:
223 host, port = ('localhost', args[0])
224
225 import buildtools.packagerGecko as packager
226 packager.autoInstall(baseDir, type, host, port, multicompartment=multicompar tment)
227
228
229 def createDevEnv(baseDir, scriptName, opts, args, type): 202 def createDevEnv(baseDir, scriptName, opts, args, type):
230 if type == 'safari': 203 if type == 'safari':
231 import buildtools.packagerSafari as packager 204 import buildtools.packagerSafari as packager
232 else: 205 else:
233 import buildtools.packagerChrome as packager 206 import buildtools.packagerChrome as packager
234 207
235 file = StringIO() 208 file = StringIO()
236 packager.createBuild(baseDir, type=type, outFile=file, devenv=True, releaseB uild=True) 209 packager.createBuild(baseDir, type=type, outFile=file, devenv=True, releaseB uild=True)
237 210
238 from buildtools.packager import getDevEnvPath 211 from buildtools.packager import getDevEnvPath
239 devenv_dir = getDevEnvPath(baseDir, type) 212 devenv_dir = getDevEnvPath(baseDir, type)
240 213
241 shutil.rmtree(devenv_dir, ignore_errors=True) 214 shutil.rmtree(devenv_dir, ignore_errors=True)
242 215
243 file.seek(0) 216 file.seek(0)
244 with ZipFile(file, 'r') as zip_file: 217 with ZipFile(file, 'r') as zip_file:
245 zip_file.extractall(devenv_dir) 218 zip_file.extractall(devenv_dir)
246 219
247 220
248 def readLocaleConfig(baseDir, type, metadata): 221 def readLocaleConfig(baseDir, type, metadata):
249 if type == 'gecko': 222 if type != 'generic':
250 import buildtools.packagerGecko as packager
251 localeDir = packager.getLocalesDir(baseDir)
252 localeConfig = {
253 'name_format': 'BCP-47',
254 'file_format': 'gecko-dtd',
255 'default_locale': packager.defaultLocale
256 }
257 elif type in {'chrome', 'gecko-webext'}:
258 import buildtools.packagerChrome as packager 223 import buildtools.packagerChrome as packager
259 localeDir = os.path.join(baseDir, '_locales') 224 localeDir = os.path.join(baseDir, '_locales')
260 localeConfig = { 225 localeConfig = {
261 'name_format': 'ISO-15897',
262 'file_format': 'chrome-json',
263 'default_locale': packager.defaultLocale, 226 'default_locale': packager.defaultLocale,
264 } 227 }
265 else: 228 else:
266 localeDir = os.path.join( 229 localeDir = os.path.join(
267 baseDir, *metadata.get('locales', 'base_path').split('/') 230 baseDir, *metadata.get('locales', 'base_path').split('/')
268 ) 231 )
269 localeConfig = { 232 localeConfig = {
270 'name_format': metadata.get('locales', 'name_format'),
271 'file_format': metadata.get('locales', 'file_format'),
272 'default_locale': metadata.get('locales', 'default_locale') 233 'default_locale': metadata.get('locales', 'default_locale')
273 } 234 }
274 235
275 localeConfig['base_path'] = localeDir 236 localeConfig['base_path'] = localeDir
276 237
277 locales = [(locale, os.path.join(localeDir, locale)) 238 locales = [(locale.replace('_', '-'), os.path.join(localeDir, locale))
278 for locale in os.listdir(localeDir)] 239 for locale in os.listdir(localeDir)]
279 if localeConfig['name_format'] == 'ISO-15897':
280 locales = [(locale.replace('_', '-'), localePath)
281 for locale, localePath in locales]
282 localeConfig['locales'] = dict(locales) 240 localeConfig['locales'] = dict(locales)
283 241
284 return localeConfig 242 return localeConfig
285 243
286 244
287 def setupTranslations(baseDir, scriptName, opts, args, type): 245 def setupTranslations(baseDir, scriptName, opts, args, type):
288 if len(args) < 1: 246 if len(args) < 1:
289 print 'Project key is required to update translation master files.' 247 print 'Project key is required to update translation master files.'
290 usage(scriptName, type, 'setuptrans') 248 usage(scriptName, type, 'setuptrans')
291 return 249 return
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
333 key = args[0] 291 key = args[0]
334 292
335 from buildtools.packager import readMetadata 293 from buildtools.packager import readMetadata
336 metadata = readMetadata(baseDir, type) 294 metadata = readMetadata(baseDir, type)
337 295
338 basename = metadata.get('general', 'basename') 296 basename = metadata.get('general', 'basename')
339 localeConfig = readLocaleConfig(baseDir, type, metadata) 297 localeConfig = readLocaleConfig(baseDir, type, metadata)
340 298
341 import buildtools.localeTools as localeTools 299 import buildtools.localeTools as localeTools
342 for locale, localeDir in localeConfig['locales'].iteritems(): 300 for locale, localeDir in localeConfig['locales'].iteritems():
343 if locale != localeConfig['default_locale'].replace('_', '-'): 301 if locale != localeConfig['default_locale'].replace('_', '-'):
tlucas 2017/10/05 10:10:30 Note: result of rebasing
344 localeTools.uploadTranslations(localeConfig, metadata, localeDir, lo cale, 302 localeTools.uploadTranslations(localeConfig, metadata, localeDir, lo cale,
345 basename, key) 303 basename, key)
346 304
347 305
348 def getTranslations(baseDir, scriptName, opts, args, type): 306 def getTranslations(baseDir, scriptName, opts, args, type):
349 if len(args) < 1: 307 if len(args) < 1:
350 print 'Project key is required to update translation master files.' 308 print 'Project key is required to update translation master files.'
351 usage(scriptName, type, 'translate') 309 usage(scriptName, type, 'translate')
352 return 310 return
353 311
354 key = args[0] 312 key = args[0]
355 313
356 from buildtools.packager import readMetadata 314 from buildtools.packager import readMetadata
357 metadata = readMetadata(baseDir, type) 315 metadata = readMetadata(baseDir, type)
358 316
359 basename = metadata.get('general', 'basename') 317 basename = metadata.get('general', 'basename')
360 localeConfig = readLocaleConfig(baseDir, type, metadata) 318 localeConfig = readLocaleConfig(baseDir, type, metadata)
361 319
362 import buildtools.localeTools as localeTools 320 import buildtools.localeTools as localeTools
363 localeTools.getTranslations(localeConfig, basename, key) 321 localeTools.getTranslations(localeConfig, basename, key)
364 322
365 323
366 def showDescriptions(baseDir, scriptName, opts, args, type):
367 locales = None
368 for option, value in opts:
369 if option in ('-l', '--locales'):
370 locales = value.split(',')
371
372 import buildtools.packagerGecko as packager
373 if locales == None:
374 locales = packager.getLocales(baseDir)
375 elif locales == 'all':
376 locales = packager.getLocales(baseDir, True)
377
378 data = packager.readLocaleMetadata(baseDir, locales)
379 localeCodes = data.keys()
380 localeCodes.sort()
381 for localeCode in localeCodes:
382 locale = data[localeCode]
383 print ('''%s
384 %s
385 %s
386 %s
387 %s
388 ''' % (localeCode,
389 locale['name'] if 'name' in locale else 'None',
390 locale['description'] if 'description' in locale else 'None',
391 locale['description.short'] if 'description.short' in locale else 'N one',
392 locale['description.long'] if 'description.long' in locale else 'Non e',
393 )).encode('utf-8')
394
395
396 def generateDocs(baseDir, scriptName, opts, args, type): 324 def generateDocs(baseDir, scriptName, opts, args, type):
397 if len(args) == 0: 325 if len(args) == 0:
398 print 'No target directory specified for the documentation' 326 print 'No target directory specified for the documentation'
399 usage(scriptName, type, 'docs') 327 usage(scriptName, type, 'docs')
400 return 328 return
401 targetDir = args[0] 329 targetDir = args[0]
402 330
403 source_dir = os.path.join(baseDir, 'lib') 331 source_dir = os.path.join(baseDir, 'lib')
404 sources = [source_dir] 332 sources = [source_dir]
405 333
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
456 import buildtools.publicSuffixListUpdater as publicSuffixListUpdater 384 import buildtools.publicSuffixListUpdater as publicSuffixListUpdater
457 publicSuffixListUpdater.updatePSL(baseDir) 385 publicSuffixListUpdater.updatePSL(baseDir)
458 386
459 with addCommand(lambda baseDir, scriptName, opts, args, type: usage(scriptName, type), ('help', '-h', '--help')) as command: 387 with addCommand(lambda baseDir, scriptName, opts, args, type: usage(scriptName, type), ('help', '-h', '--help')) as command:
460 command.shortDescription = 'Show this message' 388 command.shortDescription = 'Show this message'
461 389
462 with addCommand(runBuild, 'build') as command: 390 with addCommand(runBuild, 'build') as command:
463 command.shortDescription = 'Create a build' 391 command.shortDescription = 'Create a build'
464 command.description = 'Creates an extension build with given file name. If o utput_file is missing a default name will be chosen.' 392 command.description = 'Creates an extension build with given file name. If o utput_file is missing a default name will be chosen.'
465 command.params = '[options] [output_file]' 393 command.params = '[options] [output_file]'
466 command.addOption('Only include the given locales (if omitted: all locales n ot marked as incomplete)', short='l', long='locales', value='l1,l2,l3', types=(' gecko'))
467 command.addOption('Use given build number (if omitted the build number will be retrieved from Mercurial)', short='b', long='build', value='num') 394 command.addOption('Use given build number (if omitted the build number will be retrieved from Mercurial)', short='b', long='build', value='num')
468 command.addOption('File containing private key and certificates required to sign the package', short='k', long='key', value='file', types=('chrome', 'safari ')) 395 command.addOption('File containing private key and certificates required to sign the package', short='k', long='key', value='file', types=('chrome', 'safari '))
469 command.addOption('Create a build for leak testing', short='m', long='multi- compartment', types=('gecko'))
470 command.addOption('Create a release build', short='r', long='release') 396 command.addOption('Create a release build', short='r', long='release')
471 command.supportedTypes = ('gecko', 'gecko-webext', 'chrome', 'safari', 'edge ') 397 command.supportedTypes = ('gecko-webext', 'chrome', 'safari', 'edge')
472
473 with addCommand(runAutoInstall, 'autoinstall') as command:
474 command.shortDescription = 'Install extension automatically'
475 command.description = 'Will automatically install the extension in a browser running Extension Auto-Installer. If host parameter is omitted assumes that the browser runs on localhost.'
476 command.params = '[<host>:]<port>'
477 command.addOption('Create a build for leak testing', short='m', long='multi- compartment')
478 command.supportedTypes = ('gecko')
479 398
480 with addCommand(createDevEnv, 'devenv') as command: 399 with addCommand(createDevEnv, 'devenv') as command:
481 command.shortDescription = 'Set up a development environment' 400 command.shortDescription = 'Set up a development environment'
482 command.description = 'Will set up or update the devenv folder as an unpacke d extension folder for development.' 401 command.description = 'Will set up or update the devenv folder as an unpacke d extension folder for development.'
483 command.supportedTypes = ('gecko-webext', 'chrome', 'safari') 402 command.supportedTypes = ('gecko-webext', 'chrome', 'safari')
484 403
485 with addCommand(setupTranslations, 'setuptrans') as command: 404 with addCommand(setupTranslations, 'setuptrans') as command:
486 command.shortDescription = 'Sets up translation languages' 405 command.shortDescription = 'Sets up translation languages'
487 command.description = 'Sets up translation languages for the project on crow din.net.' 406 command.description = 'Sets up translation languages for the project on crow din.net.'
488 command.params = '[options] project-key' 407 command.params = '[options] project-key'
489 command.supportedTypes = ('gecko', 'chrome', 'generic')
490 408
491 with addCommand(updateTranslationMaster, 'translate') as command: 409 with addCommand(updateTranslationMaster, 'translate') as command:
492 command.shortDescription = 'Updates translation master files' 410 command.shortDescription = 'Updates translation master files'
493 command.description = 'Updates the translation master files in the project o n crowdin.net.' 411 command.description = 'Updates the translation master files in the project o n crowdin.net.'
494 command.params = '[options] project-key' 412 command.params = '[options] project-key'
495 command.supportedTypes = ('gecko', 'chrome', 'generic')
496 413
497 with addCommand(uploadTranslations, 'uploadtrans') as command: 414 with addCommand(uploadTranslations, 'uploadtrans') as command:
498 command.shortDescription = 'Uploads existing translations' 415 command.shortDescription = 'Uploads existing translations'
499 command.description = 'Uploads already existing translations to the project on crowdin.net.' 416 command.description = 'Uploads already existing translations to the project on crowdin.net.'
500 command.params = '[options] project-key' 417 command.params = '[options] project-key'
501 command.supportedTypes = ('gecko', 'chrome', 'generic')
502 418
503 with addCommand(getTranslations, 'gettranslations') as command: 419 with addCommand(getTranslations, 'gettranslations') as command:
504 command.shortDescription = 'Downloads translation updates' 420 command.shortDescription = 'Downloads translation updates'
505 command.description = 'Downloads updated translations from crowdin.net.' 421 command.description = 'Downloads updated translations from crowdin.net.'
506 command.params = '[options] project-key' 422 command.params = '[options] project-key'
507 command.supportedTypes = ('gecko', 'chrome', 'generic')
508
509 with addCommand(showDescriptions, 'showdesc') as command:
510 command.shortDescription = 'Print description strings for all locales'
511 command.description = 'Display description strings for all locales as specif ied in the corresponding meta.properties files.'
512 command.addOption('Only include the given locales', short='l', long='locales ', value='l1,l2,l3')
513 command.params = '[options]'
514 command.supportedTypes = ('gecko')
515 423
516 with addCommand(generateDocs, 'docs') as command: 424 with addCommand(generateDocs, 'docs') as command:
517 command.shortDescription = 'Generate documentation (requires node.js)' 425 command.shortDescription = 'Generate documentation (requires node.js)'
518 command.description = ('Generate documentation files and write them into ' 426 command.description = ('Generate documentation files and write them into '
519 'the specified directory.') 427 'the specified directory.')
520 command.addOption('Suppress JsDoc output', short='q', long='quiet') 428 command.addOption('Suppress JsDoc output', short='q', long='quiet')
521 command.params = '[options] <directory>' 429 command.params = '[options] <directory>'
522 command.supportedTypes = ('gecko', 'chrome') 430 command.supportedTypes = ('chrome')
Vasily Kuznetsov 2017/10/05 20:58:11 Even though we did have strings instead of tuples
tlucas 2017/10/06 09:06:49 Done.
523 431
524 with addCommand(runReleaseAutomation, 'release') as command: 432 with addCommand(runReleaseAutomation, 'release') as command:
525 command.shortDescription = 'Run release automation' 433 command.shortDescription = 'Run release automation'
526 command.description = 'Note: If you are not the project owner then you ' "probably don't want to run this!\n\n" 'Runs release automation: crea tes downloads for the new version, tags ' 'source code repository as well as downloads and buildtools repository.' 434 command.description = 'Note: If you are not the project owner then you ' "probably don't want to run this!\n\n" 'Runs release automation: crea tes downloads for the new version, tags ' 'source code repository as well as downloads and buildtools repository.'
527 command.addOption('File containing private key and certificates required to sign the release.', short='k', long='key', value='file', types=('chrome', 'safar i', 'edge')) 435 command.addOption('File containing private key and certificates required to sign the release.', short='k', long='key', value='file', types=('chrome', 'safar i', 'edge'))
528 command.addOption('Directory containing downloads repository (if omitted ../ downloads is assumed)', short='d', long='downloads', value='dir') 436 command.addOption('Directory containing downloads repository (if omitted ../ downloads is assumed)', short='d', long='downloads', value='dir')
529 command.params = '[options] <version>' 437 command.params = '[options] <version>'
530 command.supportedTypes = ('gecko', 'chrome', 'safari', 'edge') 438 command.supportedTypes = ('chrome', 'safari', 'edge')
531 439
532 with addCommand(updatePSL, 'updatepsl') as command: 440 with addCommand(updatePSL, 'updatepsl') as command:
533 command.shortDescription = 'Updates Public Suffix List' 441 command.shortDescription = 'Updates Public Suffix List'
534 command.description = 'Downloads Public Suffix List (see http://publicsuffix .org/) and generates lib/publicSuffixList.js from it.' 442 command.description = 'Downloads Public Suffix List (see http://publicsuffix .org/) and generates lib/publicSuffixList.js from it.'
535 command.supportedTypes = ('chrome',) 443 command.supportedTypes = ('chrome',)
536 444
537 445
538 def getType(baseDir, scriptName, args): 446 def getType(baseDir, scriptName, args):
539 # Look for an explicit type parameter (has to be the first parameter) 447 # Look for an explicit type parameter (has to be the first parameter)
540 if len(args) >= 2 and args[0] == '-t': 448 if len(args) >= 2 and args[0] == '-t':
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
600 if option in ('-h', '--help'): 508 if option in ('-h', '--help'):
601 usage(scriptName, type, command) 509 usage(scriptName, type, command)
602 sys.exit() 510 sys.exit()
603 commands[command](baseDir, scriptName, opts, args, type) 511 commands[command](baseDir, scriptName, opts, args, type)
604 else: 512 else:
605 print 'Command %s is not supported for this application type' % comm and 513 print 'Command %s is not supported for this application type' % comm and
606 usage(scriptName, type) 514 usage(scriptName, type)
607 else: 515 else:
608 print 'Command %s is unrecognized' % command 516 print 'Command %s is unrecognized' % command
609 usage(scriptName, type) 517 usage(scriptName, type)
OLDNEW
« no previous file with comments | « LocaleTester.pm ('k') | lib/hooks.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld