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

Side by Side Diff: build.py

Issue 29611593: Issue 5996 - Release consistent versions across WebExtensions (Closed) Base URL: https://codereview.adblockplus.org/29609559/
Patch Set: Refactoring release decision Created Nov. 23, 2017, 11:57 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 | « no previous file | localeTools.py » ('j') | releaseAutomation.py » ('J')
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 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
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
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
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
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))
OLDNEW
« no previous file with comments | « no previous file | localeTools.py » ('j') | releaseAutomation.py » ('J')

Powered by Google App Engine
This is Rietveld