| 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 |