Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(96)

Side by Side Diff: recipes.py

Issue 2840283002: [recipes.py] refactor common argument parsing, directly validate --package (Closed)
Patch Set: remove redundant assert Created 3 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 #!/usr/bin/env python 1 #!/usr/bin/env python
2 # Copyright 2015 The LUCI Authors. All rights reserved. 2 # Copyright 2015 The LUCI Authors. All rights reserved.
3 # Use of this source code is governed under the Apache License, Version 2.0 3 # Use of this source code is governed under the Apache License, Version 2.0
4 # that can be found in the LICENSE file. 4 # that can be found in the LICENSE file.
5 5
6 """Tool to interact with recipe repositories. 6 """Tool to interact with recipe repositories.
7 7
8 This tool operates on the nearest ancestor directory containing an 8 This tool operates on the nearest ancestor directory containing an
9 infra/config/recipes.cfg. 9 infra/config/recipes.cfg.
10 """ 10 """
(...skipping 326 matching lines...) Expand 10 before | Expand all | Expand 10 after
337 def _op_properties_to_dict(pmap): 337 def _op_properties_to_dict(pmap):
338 """Creates a properties dictionary from an arguments_pb2.PropertyMap entry. 338 """Creates a properties dictionary from an arguments_pb2.PropertyMap entry.
339 339
340 Args: 340 Args:
341 pmap (arguments_pb2.PropertyMap): Map to convert to dictionary form. 341 pmap (arguments_pb2.PropertyMap): Map to convert to dictionary form.
342 Returns (dict): A dictionary derived from the properties in "pmap". 342 Returns (dict): A dictionary derived from the properties in "pmap".
343 """ 343 """
344 return dict((k, _op_property_value(pmap[k])) for k in pmap) 344 return dict((k, _op_property_value(pmap[k])) for k in pmap)
345 345
346 346
347 def main(): 347 def add_common_args(parser):
dnj 2017/04/26 21:08:15 Not appreciating why this is pulled out into a sep
348 parser = argparse.ArgumentParser( 348 from recipe_engine import package_io
349 description='Interact with the recipe system.') 349
350 def package_type(value):
351 if not os.path.exists(value):
352 raise argparse.ArgumentTypeError(
353 'Given recipes config file %s does not exist.' % (value,))
354 return package_io.PackageFile(value)
350 355
351 parser.add_argument( 356 parser.add_argument(
352 '--package', 357 '--package',
353 type=os.path.abspath, 358 type=package_type,
354 help='Path to recipes.cfg of the recipe package to operate on' 359 help='Path to recipes.cfg of the recipe package to operate on'
355 ', usually in infra/config/recipes.cfg') 360 ', usually in infra/config/recipes.cfg')
356 parser.add_argument( 361 parser.add_argument(
357 '--deps-path', 362 '--deps-path',
358 type=os.path.abspath, 363 type=os.path.abspath,
359 help='Path where recipe engine dependencies will be extracted. Specify ' 364 help='Path where recipe engine dependencies will be extracted. Specify '
360 '"-" to use a temporary directory for deps, which will be cleaned ' 365 '"-" to use a temporary directory for deps, which will be cleaned '
361 'up on exit.') 366 'up on exit.')
362 parser.add_argument( 367 parser.add_argument(
363 '--verbose', '-v', action='count', 368 '--verbose', '-v', action='count',
(...skipping 14 matching lines...) Expand all
378 parser.add_argument( 383 parser.add_argument(
379 '--disable-bootstrap', action='store_false', dest='use_bootstrap', 384 '--disable-bootstrap', action='store_false', dest='use_bootstrap',
380 help='Disables bootstrap (see --use-bootstrap)') 385 help='Disables bootstrap (see --use-bootstrap)')
381 parser.add_argument( 386 parser.add_argument(
382 '--operational-args-path', action='store', 387 '--operational-args-path', action='store',
383 type=os.path.abspath, 388 type=os.path.abspath,
384 help='The path to an operational Arguments file. If provided, this file ' 389 help='The path to an operational Arguments file. If provided, this file '
385 'must contain a JSONPB-encoded Arguments protobuf message, and will ' 390 'must contain a JSONPB-encoded Arguments protobuf message, and will '
386 'be integrated into the runtime parameters.') 391 'be integrated into the runtime parameters.')
387 392
393
394 def post_process_common_args(parser, args):
395 if args.command == "remote":
dnj 2017/04/26 21:08:15 Same here - why not just put this content at the c
396 # TODO(iannucci): this is a hack; remote doesn't behave like ANY other
397 # commands. A way to solve this will be to allow --package to take a remote
398 # repo and then simply remove the remote subcommand entirely.
399 return
400
401 if not args.package:
402 parser.error('%s requires --package' % args.command)
403
404
405 def main():
406 parser = argparse.ArgumentParser(
407 description='Interact with the recipe system.')
408
409 add_common_args(parser)
410
388 subp = parser.add_subparsers() 411 subp = parser.add_subparsers()
389 412
390 fetch_p = subp.add_parser( 413 fetch_p = subp.add_parser(
391 'fetch', 414 'fetch',
392 description='Fetch and update dependencies.') 415 description='Fetch and update dependencies.')
393 fetch_p.set_defaults(command='fetch') 416 fetch_p.set_defaults(command='fetch')
394 417
395 test_p = subp.add_parser( 418 test_p = subp.add_parser(
396 'test', 419 'test',
397 description='Generate or check expectations by simulation') 420 description='Generate or check expectations by simulation')
(...skipping 166 matching lines...) Expand 10 before | Expand all | Expand 10 after
564 'doc', 587 'doc',
565 description='List all known modules reachable from the current package, ' 588 description='List all known modules reachable from the current package, '
566 'with their documentation') 589 'with their documentation')
567 doc_p.add_argument('recipe', nargs='?', 590 doc_p.add_argument('recipe', nargs='?',
568 help='Restrict documentation to this recipe') 591 help='Restrict documentation to this recipe')
569 doc_p.add_argument('--kind', default='jsonpb', choices=doc_kinds, 592 doc_p.add_argument('--kind', default='jsonpb', choices=doc_kinds,
570 help='Output this kind of documentation') 593 help='Output this kind of documentation')
571 doc_p.set_defaults(command='doc') 594 doc_p.set_defaults(command='doc')
572 595
573 args = parser.parse_args() 596 args = parser.parse_args()
597 post_process_common_args(parser, args)
574 598
575 # Load/parse operational arguments. 599 # Load/parse operational arguments.
576 op_args = arguments_pb2.Arguments() 600 op_args = arguments_pb2.Arguments()
577 if args.operational_args_path is not None: 601 if args.operational_args_path is not None:
578 with open(args.operational_args_path) as fd: 602 with open(args.operational_args_path) as fd:
579 data = fd.read() 603 data = fd.read()
580 jsonpb.Parse(data, op_args) 604 jsonpb.Parse(data, op_args)
581 605
582 # TODO(iannucci): We should always do logging.basicConfig() (probably with 606 # TODO(iannucci): We should always do logging.basicConfig() (probably with
583 # logging.WARNING), even if no verbose is passed. However we need to be 607 # logging.WARNING), even if no verbose is passed. However we need to be
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after
667 691
668 692
669 def _real_main(args, op_args): 693 def _real_main(args, op_args):
670 from recipe_engine import package, package_io 694 from recipe_engine import package, package_io
671 695
672 # Commands which do not require config_file, package_deps, and other objects 696 # Commands which do not require config_file, package_deps, and other objects
673 # initialized later. 697 # initialized later.
674 if args.command == 'remote': 698 if args.command == 'remote':
675 return remote(args) 699 return remote(args)
676 700
677 assert args.package, 'No recipe config (--package) given.' 701 config_file = args.package
678 assert os.path.exists(args.package), ( 702 repo_root = package.InfraRepoConfig().from_recipes_cfg(args.package.path)
679 'Given recipes config file %s does not exist.' % args.package)
680 repo_root = package.InfraRepoConfig().from_recipes_cfg(args.package)
681 config_file = package_io.PackageFile(args.package)
682 703
683 try: 704 try:
684 # TODO(phajdan.jr): gracefully handle inconsistent deps when rolling. 705 # TODO(phajdan.jr): gracefully handle inconsistent deps when rolling.
685 # This fails if the starting point does not have consistent dependency 706 # This fails if the starting point does not have consistent dependency
686 # graph. When performing an automated roll, it'd make sense to attempt 707 # graph. When performing an automated roll, it'd make sense to attempt
687 # to automatically find a consistent state, rather than bailing out. 708 # to automatically find a consistent state, rather than bailing out.
688 # Especially that only some subcommands refer to package_deps. 709 # Especially that only some subcommands refer to package_deps.
689 package_deps = package.PackageDeps.create( 710 package_deps = package.PackageDeps.create(
690 repo_root, config_file, allow_fetch=not args.no_fetch, 711 repo_root, config_file, allow_fetch=not args.no_fetch,
691 deps_path=args.deps_path, overrides=args.project_override) 712 deps_path=args.deps_path, overrides=args.project_override)
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
746 767
747 if not isinstance(ret, int): 768 if not isinstance(ret, int):
748 if ret is None: 769 if ret is None:
749 ret = 0 770 ret = 0
750 else: 771 else:
751 print >> sys.stderr, ret 772 print >> sys.stderr, ret
752 ret = 1 773 ret = 1
753 sys.stdout.flush() 774 sys.stdout.flush()
754 sys.stderr.flush() 775 sys.stderr.flush()
755 os._exit(ret) 776 os._exit(ret)
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698