LEFT | RIGHT |
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', 'chrome', 'safari', 'generic', 'edge') | 15 knownTypes = ('gecko', '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 149 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
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 {'-l', '--locales'} and type == 'gecko': |
182 kwargs['locales'] = value.split(',') | 182 kwargs['locales'] = value.split(',') |
183 elif option in {'-b', '--build'}: | 183 elif option in {'-b', '--build'}: |
184 kwargs['buildNum'] = value | 184 kwargs['buildNum'] = value |
185 if type != 'gecko' and not kwargs['buildNum'].isdigit(): | 185 no_gecko_build = type not in {'gecko', 'gecko-webext'} |
| 186 if no_gecko_build and not kwargs['buildNum'].isdigit(): |
186 raise TypeError('Build number must be numerical') | 187 raise TypeError('Build number must be numerical') |
187 elif option in {'-k', '--key'}: | 188 elif option in {'-k', '--key'}: |
188 kwargs['keyFile'] = value | 189 kwargs['keyFile'] = value |
189 elif option in {'-m', '--multi-compartment'} and type == 'gecko': | 190 elif option in {'-m', '--multi-compartment'} and type == 'gecko': |
190 kwargs['multicompartment'] = True | 191 kwargs['multicompartment'] = True |
191 elif option in {'-r', '--release'}: | 192 elif option in {'-r', '--release'}: |
192 kwargs['releaseBuild'] = True | 193 kwargs['releaseBuild'] = True |
193 if len(args) > 0: | 194 if len(args) > 0: |
194 kwargs['outFile'] = args[0] | 195 kwargs['outFile'] = args[0] |
195 | 196 |
196 if type == 'gecko': | 197 if type == 'gecko': |
197 import buildtools.packagerGecko as packager | 198 import buildtools.packagerGecko as packager |
198 elif type == 'chrome': | 199 elif type in {'chrome', 'gecko-webext'}: |
199 import buildtools.packagerChrome as packager | 200 import buildtools.packagerChrome as packager |
200 elif type == 'safari': | 201 elif type == 'safari': |
201 import buildtools.packagerSafari as packager | 202 import buildtools.packagerSafari as packager |
202 elif type == 'edge': | 203 elif type == 'edge': |
203 import buildtools.packagerEdge as packager | 204 import buildtools.packagerEdge as packager |
204 | 205 |
205 packager.createBuild(baseDir, type=type, **kwargs) | 206 packager.createBuild(baseDir, type=type, **kwargs) |
206 | 207 |
207 | 208 |
208 def runAutoInstall(baseDir, scriptName, opts, args, type): | 209 def runAutoInstall(baseDir, scriptName, opts, args, type): |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
249 def readLocaleConfig(baseDir, type, metadata): | 250 def readLocaleConfig(baseDir, type, metadata): |
250 if type == 'gecko': | 251 if type == 'gecko': |
251 import buildtools.packagerGecko as packager | 252 import buildtools.packagerGecko as packager |
252 localeDir = packager.getLocalesDir(baseDir) | 253 localeDir = packager.getLocalesDir(baseDir) |
253 localeConfig = { | 254 localeConfig = { |
254 'name_format': 'BCP-47', | 255 'name_format': 'BCP-47', |
255 'file_format': 'gecko-dtd', | 256 'file_format': 'gecko-dtd', |
256 'target_platforms': {'gecko'}, | 257 'target_platforms': {'gecko'}, |
257 'default_locale': packager.defaultLocale | 258 'default_locale': packager.defaultLocale |
258 } | 259 } |
259 elif type == 'chrome': | 260 elif type in {'chrome', 'gecko-webext'}: |
260 import buildtools.packagerChrome as packager | 261 import buildtools.packagerChrome as packager |
261 localeDir = os.path.join(baseDir, '_locales') | 262 localeDir = os.path.join(baseDir, '_locales') |
262 localeConfig = { | 263 localeConfig = { |
263 'name_format': 'ISO-15897', | 264 'name_format': 'ISO-15897', |
264 'file_format': 'chrome-json', | 265 'file_format': 'chrome-json', |
265 'target_platforms': {'chrome'}, | 266 'target_platforms': {'chrome'}, |
266 'default_locale': packager.defaultLocale, | 267 'default_locale': packager.defaultLocale, |
267 } | 268 } |
268 else: | 269 else: |
269 localeDir = os.path.join( | 270 localeDir = os.path.join( |
(...skipping 135 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
405 return | 406 return |
406 targetDir = args[0] | 407 targetDir = args[0] |
407 | 408 |
408 source_dir = os.path.join(baseDir, 'lib') | 409 source_dir = os.path.join(baseDir, 'lib') |
409 sources = [source_dir] | 410 sources = [source_dir] |
410 | 411 |
411 # JSDoc struggles wih huge objects: https://github.com/jsdoc3/jsdoc/issues/9
76 | 412 # JSDoc struggles wih huge objects: https://github.com/jsdoc3/jsdoc/issues/9
76 |
412 if type == 'chrome': | 413 if type == 'chrome': |
413 sources = [os.path.join(source_dir, filename) for filename in os.listdir
(source_dir) if filename != 'publicSuffixList.js'] | 414 sources = [os.path.join(source_dir, filename) for filename in os.listdir
(source_dir) if filename != 'publicSuffixList.js'] |
414 | 415 |
415 config = os.path.join(os.path.dirname(__file__), 'jsdoc.conf') | 416 buildtools_path = os.path.dirname(__file__) |
416 command = ['jsdoc', '--destination', targetDir, '--configure', config] + sou
rces | 417 config = os.path.join(buildtools_path, 'jsdoc.conf') |
| 418 |
| 419 command = ['npm', 'run-script', 'jsdoc', '--', '--destination', targetDir, |
| 420 '--configure', config] + sources |
417 if any(opt in ('-q', '--quiet') for opt, _ in opts): | 421 if any(opt in ('-q', '--quiet') for opt, _ in opts): |
418 process = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=subpr
ocess.PIPE) | 422 process = subprocess.Popen(command, stdout=subprocess.PIPE, |
| 423 stderr=subprocess.PIPE, cwd=buildtools_path) |
419 stderr = process.communicate()[1] | 424 stderr = process.communicate()[1] |
420 retcode = process.poll() | 425 retcode = process.poll() |
421 if retcode: | 426 if retcode: |
422 sys.stderr.write(stderr) | 427 sys.stderr.write(stderr) |
423 raise subprocess.CalledProcessError(command, retcode) | 428 raise subprocess.CalledProcessError(command, retcode) |
424 else: | 429 else: |
425 subprocess.check_call(command) | 430 subprocess.check_call(command, cwd=buildtools_path) |
426 | 431 |
427 | 432 |
428 def runReleaseAutomation(baseDir, scriptName, opts, args, type): | 433 def runReleaseAutomation(baseDir, scriptName, opts, args, type): |
429 keyFile = None | 434 keyFile = None |
430 downloadsRepo = os.path.join(baseDir, '..', 'downloads') | 435 downloadsRepo = os.path.join(baseDir, '..', 'downloads') |
431 for option, value in opts: | 436 for option, value in opts: |
432 if option in ('-k', '--key'): | 437 if option in ('-k', '--key'): |
433 keyFile = value | 438 keyFile = value |
434 elif option in ('-d', '--downloads'): | 439 elif option in ('-d', '--downloads'): |
435 downloadsRepo = value | 440 downloadsRepo = value |
(...skipping 26 matching lines...) Expand all Loading... |
462 | 467 |
463 with addCommand(runBuild, 'build') as command: | 468 with addCommand(runBuild, 'build') as command: |
464 command.shortDescription = 'Create a build' | 469 command.shortDescription = 'Create a build' |
465 command.description = 'Creates an extension build with given file name. If o
utput_file is missing a default name will be chosen.' | 470 command.description = 'Creates an extension build with given file name. If o
utput_file is missing a default name will be chosen.' |
466 command.params = '[options] [output_file]' | 471 command.params = '[options] [output_file]' |
467 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')) | 472 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')) |
468 command.addOption('Use given build number (if omitted the build number will
be retrieved from Mercurial)', short='b', long='build', value='num') | 473 command.addOption('Use given build number (if omitted the build number will
be retrieved from Mercurial)', short='b', long='build', value='num') |
469 command.addOption('File containing private key and certificates required to
sign the package', short='k', long='key', value='file', types=('chrome', 'safari
')) | 474 command.addOption('File containing private key and certificates required to
sign the package', short='k', long='key', value='file', types=('chrome', 'safari
')) |
470 command.addOption('Create a build for leak testing', short='m', long='multi-
compartment', types=('gecko')) | 475 command.addOption('Create a build for leak testing', short='m', long='multi-
compartment', types=('gecko')) |
471 command.addOption('Create a release build', short='r', long='release') | 476 command.addOption('Create a release build', short='r', long='release') |
472 command.supportedTypes = ('gecko', 'chrome', 'safari', 'edge') | 477 command.supportedTypes = ('gecko', 'gecko-webext', 'chrome', 'safari', 'edge
') |
473 | 478 |
474 with addCommand(runAutoInstall, 'autoinstall') as command: | 479 with addCommand(runAutoInstall, 'autoinstall') as command: |
475 command.shortDescription = 'Install extension automatically' | 480 command.shortDescription = 'Install extension automatically' |
476 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.' | 481 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.' |
477 command.params = '[<host>:]<port>' | 482 command.params = '[<host>:]<port>' |
478 command.addOption('Create a build for leak testing', short='m', long='multi-
compartment') | 483 command.addOption('Create a build for leak testing', short='m', long='multi-
compartment') |
479 command.supportedTypes = ('gecko') | 484 command.supportedTypes = ('gecko') |
480 | 485 |
481 with addCommand(createDevEnv, 'devenv') as command: | 486 with addCommand(createDevEnv, 'devenv') as command: |
482 command.shortDescription = 'Set up a development environment' | 487 command.shortDescription = 'Set up a development environment' |
483 command.description = 'Will set up or update the devenv folder as an unpacke
d extension folder for development.' | 488 command.description = 'Will set up or update the devenv folder as an unpacke
d extension folder for development.' |
484 command.supportedTypes = ('chrome', 'safari', 'edge') | 489 command.supportedTypes = ('gecko-webext', 'chrome', 'safari', 'edge') |
485 | 490 |
486 with addCommand(setupTranslations, 'setuptrans') as command: | 491 with addCommand(setupTranslations, 'setuptrans') as command: |
487 command.shortDescription = 'Sets up translation languages' | 492 command.shortDescription = 'Sets up translation languages' |
488 command.description = 'Sets up translation languages for the project on crow
din.net.' | 493 command.description = 'Sets up translation languages for the project on crow
din.net.' |
489 command.params = '[options] project-key' | 494 command.params = '[options] project-key' |
490 command.supportedTypes = ('gecko', 'chrome', 'generic') | 495 command.supportedTypes = ('gecko', 'chrome', 'generic') |
491 | 496 |
492 with addCommand(updateTranslationMaster, 'translate') as command: | 497 with addCommand(updateTranslationMaster, 'translate') as command: |
493 command.shortDescription = 'Updates translation master files' | 498 command.shortDescription = 'Updates translation master files' |
494 command.description = 'Updates the translation master files in the project o
n crowdin.net.' | 499 command.description = 'Updates the translation master files in the project o
n crowdin.net.' |
(...skipping 14 matching lines...) Expand all Loading... |
509 | 514 |
510 with addCommand(showDescriptions, 'showdesc') as command: | 515 with addCommand(showDescriptions, 'showdesc') as command: |
511 command.shortDescription = 'Print description strings for all locales' | 516 command.shortDescription = 'Print description strings for all locales' |
512 command.description = 'Display description strings for all locales as specif
ied in the corresponding meta.properties files.' | 517 command.description = 'Display description strings for all locales as specif
ied in the corresponding meta.properties files.' |
513 command.addOption('Only include the given locales', short='l', long='locales
', value='l1,l2,l3') | 518 command.addOption('Only include the given locales', short='l', long='locales
', value='l1,l2,l3') |
514 command.params = '[options]' | 519 command.params = '[options]' |
515 command.supportedTypes = ('gecko') | 520 command.supportedTypes = ('gecko') |
516 | 521 |
517 with addCommand(generateDocs, 'docs') as command: | 522 with addCommand(generateDocs, 'docs') as command: |
518 command.shortDescription = 'Generate documentation (requires node.js)' | 523 command.shortDescription = 'Generate documentation (requires node.js)' |
519 command.description = 'Generate documentation files and write them into the
specified directory. This operation requires JsDoc 3 to be installed.' | 524 command.description = ('Generate documentation files and write them into ' |
| 525 'the specified directory.') |
520 command.addOption('Suppress JsDoc output', short='q', long='quiet') | 526 command.addOption('Suppress JsDoc output', short='q', long='quiet') |
521 command.params = '[options] <directory>' | 527 command.params = '[options] <directory>' |
522 command.supportedTypes = ('gecko', 'chrome') | 528 command.supportedTypes = ('gecko', 'chrome') |
523 | 529 |
524 with addCommand(runReleaseAutomation, 'release') as command: | 530 with addCommand(runReleaseAutomation, 'release') as command: |
525 command.shortDescription = 'Run release automation' | 531 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.' | 532 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')) | 533 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') | 534 command.addOption('Directory containing downloads repository (if omitted ../
downloads is assumed)', short='d', long='downloads', value='dir') |
529 command.params = '[options] <version>' | 535 command.params = '[options] <version>' |
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
600 if option in ('-h', '--help'): | 606 if option in ('-h', '--help'): |
601 usage(scriptName, type, command) | 607 usage(scriptName, type, command) |
602 sys.exit() | 608 sys.exit() |
603 commands[command](baseDir, scriptName, opts, args, type) | 609 commands[command](baseDir, scriptName, opts, args, type) |
604 else: | 610 else: |
605 print 'Command %s is not supported for this application type' % comm
and | 611 print 'Command %s is not supported for this application type' % comm
and |
606 usage(scriptName, type) | 612 usage(scriptName, type) |
607 else: | 613 else: |
608 print 'Command %s is unrecognized' % command | 614 print 'Command %s is unrecognized' % command |
609 usage(scriptName, type) | 615 usage(scriptName, type) |
LEFT | RIGHT |