| OLD | NEW | 
|    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 argparse |    5 import argparse | 
|    6 import logging |    6 import logging | 
|    7 import os |    7 import os | 
|    8 import re |    8 import re | 
|    9 import shutil |    9 import shutil | 
|   10 import subprocess |   10 import subprocess | 
|   11 import sys |   11 import sys | 
|   12 from functools import partial |   12 from functools import partial | 
|   13 from StringIO import StringIO |   13 from StringIO import StringIO | 
|   14 from zipfile import ZipFile |   14 from zipfile import ZipFile | 
 |   15 from buildtools.localeTools import read_locale_config | 
|   15  |   16  | 
|   16 KNOWN_PLATFORMS = {'chrome', 'gecko', 'edge', 'generic'} |   17 KNOWN_PLATFORMS = {'chrome', 'gecko', 'edge', 'generic'} | 
|   17  |   18  | 
|   18 MAIN_PARSER = argparse.ArgumentParser( |   19 MAIN_PARSER = argparse.ArgumentParser( | 
|   19     description=__doc__, |   20     description=__doc__, | 
|   20     formatter_class=argparse.RawDescriptionHelpFormatter) |   21     formatter_class=argparse.RawDescriptionHelpFormatter) | 
|   21  |   22  | 
|   22 SUB_PARSERS = MAIN_PARSER.add_subparsers(title='Commands', dest='action', |   23 SUB_PARSERS = MAIN_PARSER.add_subparsers(title='Commands', dest='action', | 
|   23                                          metavar='[command]') |   24                                          metavar='[command]') | 
|   24  |   25  | 
|   25 ALL_COMMANDS = [] |   26 ALL_COMMANDS = [] | 
|   26  |   27  | 
|   27  |   28  | 
|   28 def make_argument(*args, **kwargs): |   29 def make_argument(*args, **kwargs): | 
|   29     def _make_argument(*args, **kwargs): |   30     def _make_argument(*args, **kwargs): | 
|   30         parser = kwargs.pop('parser') |   31         parser = kwargs.pop('parser') | 
|   31         parser.add_argument(*args, **kwargs) |   32         parser.add_argument(*args, **kwargs) | 
|   32  |   33  | 
|   33     return partial(_make_argument, *args, **kwargs) |   34     return partial(_make_argument, *args, **kwargs) | 
|   34  |   35  | 
|   35  |   36  | 
|   36 def argparse_command(valid_platforms=None, arguments=()): |   37 def argparse_command(valid_platforms=None, multi_platform=False, arguments=()): | 
|   37     def wrapper(func): |   38     def wrapper(func): | 
|   38         def func_wrapper(*args, **kwargs): |   39         def func_wrapper(*args, **kwargs): | 
|   39             return func(*args, **kwargs) |   40             return func(*args, **kwargs) | 
|   40  |   41  | 
|   41         short_desc, long_desc = func.__doc__.split(os.linesep + os.linesep, 1) |   42         short_desc, long_desc = func.__doc__.split(os.linesep + os.linesep, 1) | 
|   42  |   43  | 
|   43         ALL_COMMANDS.append({ |   44         ALL_COMMANDS.append({ | 
|   44             'name': func.__name__, |   45             'name': func.__name__, | 
|   45             'description': long_desc, |   46             'description': long_desc, | 
|   46             'help_text': short_desc, |   47             'help_text': short_desc, | 
|   47             'valid_platforms': valid_platforms or KNOWN_PLATFORMS, |   48             'valid_platforms': valid_platforms or KNOWN_PLATFORMS, | 
 |   49             'multi_platform': multi_platform, | 
|   48             'function': func, |   50             'function': func, | 
|   49             'arguments': arguments, |   51             'arguments': arguments, | 
|   50         }) |   52         }) | 
|   51         return func_wrapper |   53         return func_wrapper | 
|   52  |  | 
|   53     return wrapper |   54     return wrapper | 
|   54  |   55  | 
|   55  |   56  | 
|   56 def make_subcommand(name, description, help_text, function, arguments): |   57 def make_subcommand(name, description, help_text, function, arguments): | 
|   57     new_parser = SUB_PARSERS.add_parser( |   58     new_parser = SUB_PARSERS.add_parser( | 
|   58         name, description=description, help=help_text, |   59         name, description=description, help=help_text, | 
|   59         formatter_class=argparse.RawDescriptionHelpFormatter, |   60         formatter_class=argparse.RawDescriptionHelpFormatter, | 
|   60     ) |   61     ) | 
|   61  |   62  | 
|   62     for argument in arguments: |   63     for argument in arguments: | 
| (...skipping 23 matching lines...) Expand all  Loading... | 
|   86             types.add(p) |   87             types.add(p) | 
|   87  |   88  | 
|   88     if len(types) == 0: |   89     if len(types) == 0: | 
|   89         logging.error('No metadata file found in this repository. Expecting ' |   90         logging.error('No metadata file found in this repository. Expecting ' | 
|   90                       'one or more of {} to be present.'.format( |   91                       'one or more of {} to be present.'.format( | 
|   91                           ', '.join('metadata.' + p for p in KNOWN_PLATFORMS))) |   92                           ', '.join('metadata.' + p for p in KNOWN_PLATFORMS))) | 
|   92         build_available_subcommands._result = False |   93         build_available_subcommands._result = False | 
|   93         return False |   94         return False | 
|   94  |   95  | 
|   95     for command_params in ALL_COMMANDS: |   96     for command_params in ALL_COMMANDS: | 
 |   97         multi_platform = command_params.pop('multi_platform') | 
|   96         platforms = types.intersection(command_params.pop('valid_platforms')) |   98         platforms = types.intersection(command_params.pop('valid_platforms')) | 
|   97         if len(platforms) > 1: |   99         if len(platforms) > 1: | 
 |  100             if multi_platform: | 
 |  101                 help_text = ('Multiple types may be specifed (each preceded ' | 
 |  102                              'by -t/--type)') | 
 |  103                 action = 'append' | 
 |  104             else: | 
 |  105                 help_text = None | 
 |  106                 action = 'store' | 
 |  107  | 
|   98             command_params['arguments'] += ( |  108             command_params['arguments'] += ( | 
|   99                 make_argument('-t', '--type', dest='platform', required=True, |  109                 make_argument('-t', '--type', dest='platform', required=True, | 
|  100                               choices=platforms), |  110                               choices=platforms, action=action, | 
 |  111                               help=help_text), | 
|  101             ) |  112             ) | 
|  102             make_subcommand(**command_params) |  113             make_subcommand(**command_params) | 
|  103         elif len(platforms) == 1: |  114         elif len(platforms) == 1: | 
|  104             sub_parser = make_subcommand(**command_params) |  115             sub_parser = make_subcommand(**command_params) | 
|  105             sub_parser.set_defaults(platform=platforms.pop()) |  116             sub_parser.set_defaults(platform=platforms.pop()) | 
|  106  |  117  | 
|  107     build_available_subcommands._result = True |  118     build_available_subcommands._result = True | 
|  108     return True |  119     return True | 
|  109  |  120  | 
|  110  |  121  | 
| (...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  172     from buildtools.packager import getDevEnvPath |  183     from buildtools.packager import getDevEnvPath | 
|  173     devenv_dir = getDevEnvPath(base_dir, platform) |  184     devenv_dir = getDevEnvPath(base_dir, platform) | 
|  174  |  185  | 
|  175     shutil.rmtree(devenv_dir, ignore_errors=True) |  186     shutil.rmtree(devenv_dir, ignore_errors=True) | 
|  176  |  187  | 
|  177     file.seek(0) |  188     file.seek(0) | 
|  178     with ZipFile(file, 'r') as zip_file: |  189     with ZipFile(file, 'r') as zip_file: | 
|  179         zip_file.extractall(devenv_dir) |  190         zip_file.extractall(devenv_dir) | 
|  180  |  191  | 
|  181  |  192  | 
|  182 def read_locale_config(base_dir, platform, metadata): |  | 
|  183     if platform != 'generic': |  | 
|  184         import buildtools.packagerChrome as packager |  | 
|  185         locale_dir = os.path.join(base_dir, '_locales') |  | 
|  186         locale_config = { |  | 
|  187             'default_locale': packager.defaultLocale, |  | 
|  188         } |  | 
|  189     else: |  | 
|  190         locale_dir = os.path.join( |  | 
|  191             base_dir, *metadata.get('locales', 'base_path').split('/') |  | 
|  192         ) |  | 
|  193         locale_config = { |  | 
|  194             'default_locale': metadata.get('locales', 'default_locale') |  | 
|  195         } |  | 
|  196  |  | 
|  197     locale_config['base_path'] = locale_dir |  | 
|  198  |  | 
|  199     locales = [(locale.replace('_', '-'), os.path.join(locale_dir, locale)) |  | 
|  200                for locale in os.listdir(locale_dir)] |  | 
|  201     locale_config['locales'] = dict(locales) |  | 
|  202  |  | 
|  203     return locale_config |  | 
|  204  |  | 
|  205  |  | 
|  206 project_key_argument = make_argument( |  193 project_key_argument = make_argument( | 
|  207     'project_key', help='The crowdin project key.' |  194     'project_key', help='The crowdin project key.' | 
|  208 ) |  195 ) | 
|  209  |  196  | 
|  210  |  197  | 
|  211 @argparse_command( |  198 @argparse_command( | 
|  212     arguments=(project_key_argument, ) |  199     arguments=(project_key_argument, ) | 
|  213 ) |  200 ) | 
|  214 def setuptrans(base_dir, project_key, platform, **kwargs): |  201 def setuptrans(base_dir, project_key, platform, **kwargs): | 
|  215     """ |  202     """ | 
| (...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  332  |  319  | 
|  333  |  320  | 
|  334 def valid_version_format(value): |  321 def valid_version_format(value): | 
|  335     if re.search(r'[^\d\.]', value): |  322     if re.search(r'[^\d\.]', value): | 
|  336         raise argparse.ArgumentTypeError('Wrong version number format') |  323         raise argparse.ArgumentTypeError('Wrong version number format') | 
|  337  |  324  | 
|  338     return value |  325     return value | 
|  339  |  326  | 
|  340  |  327  | 
|  341 @argparse_command( |  328 @argparse_command( | 
|  342     valid_platforms={'chrome', 'edge'}, |  329     valid_platforms={'chrome', 'gecko', 'edge'}, multi_platform=True, | 
|  343     arguments=( |  330     arguments=( | 
|  344         make_argument( |  331         make_argument( | 
|  345             '-k', '--key', dest='key_file', |  332             '-k', '--key', dest='key_file', | 
|  346             help=('File containing private key and certificates required to ' |  333             help=('File containing private key and certificates required to ' | 
|  347                   'sign the release.')), |  334                   'sign the release.')), | 
|  348         make_argument( |  335         make_argument( | 
|  349             '-d', '--downloads-repository', dest='downloads_repository', |  336             '-d', '--downloads-repository', dest='downloads_repository', | 
|  350             help=('Directory containing downloads repository (if omitted ' |  337             help=('Directory containing downloads repository (if omitted ' | 
|  351                   '../downloads is assumed)')), |  338                   '../downloads is assumed)')), | 
|  352         make_argument( |  339         make_argument( | 
|  353             'version', help='Version number of the release', |  340             'version', help='Version number of the release', | 
|  354             type=valid_version_format) |  341             type=valid_version_format) | 
|  355     ) |  342     ) | 
|  356 ) |  343 ) | 
|  357 def release(base_dir, downloads_repository, key_file, platform, version, |  344 def release(base_dir, downloads_repository, key_file, platform, version, | 
|  358             **kwargs): |  345             **kwargs): | 
|  359     """ |  346     """ | 
|  360     Run release automation. |  347     Run release automation. | 
|  361  |  348  | 
|  362     Note: If you are not the project owner then you probably don't want to run |  349     Note: If you are not the project owner then you probably don't want to run | 
|  363     this! |  350     this! | 
|  364  |  351  | 
|  365     Run release automation: create downloads for the new version, tag source |  352     Run release automation: create downloads for the new version, tag source | 
|  366     code repository as well as downloads and buildtools repository. |  353     code repository as well as downloads and buildtools repository. | 
|  367     """ |  354     """ | 
|  368     if downloads_repository is None: |  355     if downloads_repository is None: | 
|  369         downloads_repository = os.path.join(base_dir, os.pardir, 'downloads') |  356         downloads_repository = os.path.join(base_dir, os.pardir, 'downloads') | 
|  370  |  357  | 
|  371     if platform == 'chrome' and key_file is None: |  358     if 'chrome' in platform and key_file is None: | 
|  372         logging.error('You must specify a key file for this release') |  359         logging.error('You must specify a key file for this release') | 
|  373         return |  360         return | 
|  374  |  361  | 
|  375     import buildtools.releaseAutomation as releaseAutomation |  362     import buildtools.releaseAutomation as releaseAutomation | 
|  376     releaseAutomation.run(base_dir, platform, version, key_file, |  363     releaseAutomation.run(base_dir, platform, version, key_file, | 
|  377                           downloads_repository) |  364                           downloads_repository) | 
|  378  |  365  | 
|  379  |  366  | 
|  380 @argparse_command(valid_platforms={'chrome'}) |  367 @argparse_command(valid_platforms={'chrome'}) | 
|  381 def updatepsl(base_dir, **kwargs): |  368 def updatepsl(base_dir, **kwargs): | 
| (...skipping 10 matching lines...) Expand all  Loading... | 
|  392     if build_available_subcommands(base_dir): |  379     if build_available_subcommands(base_dir): | 
|  393         MAIN_PARSER.set_defaults(base_dir=base_dir) |  380         MAIN_PARSER.set_defaults(base_dir=base_dir) | 
|  394  |  381  | 
|  395         # If no args are provided, this module is run directly from the command |  382         # If no args are provided, this module is run directly from the command | 
|  396         # line. argparse will take care of consuming sys.argv. |  383         # line. argparse will take care of consuming sys.argv. | 
|  397         arguments = MAIN_PARSER.parse_args(args if len(args) > 0 else None) |  384         arguments = MAIN_PARSER.parse_args(args if len(args) > 0 else None) | 
|  398  |  385  | 
|  399         function = arguments.function |  386         function = arguments.function | 
|  400         del arguments.function |  387         del arguments.function | 
|  401         function(**vars(arguments)) |  388         function(**vars(arguments)) | 
| OLD | NEW |