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

Side by Side Diff: recipes.py

Issue 2839353003: [recipes.py] move remote arg parsing to its module (Closed)
Patch Set: rebase 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 | « recipe_engine/remote.py ('k') | unittests/remote_test.py » ('j') | 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 202 matching lines...) Expand 10 before | Expand all | Expand 10 after
213 step_runner.SubprocessStepRunner(stream_engine, engine_flags), 213 step_runner.SubprocessStepRunner(stream_engine, engine_flags),
214 universe_view, engine_flags=engine_flags, 214 universe_view, engine_flags=engine_flags,
215 emit_initial_properties=emit_initial_properties) 215 emit_initial_properties=emit_initial_properties)
216 finally: 216 finally:
217 os.chdir(old_cwd) 217 os.chdir(old_cwd)
218 218
219 return handle_recipe_return( 219 return handle_recipe_return(
220 ret, args.output_result_json, stream_engine, engine_flags) 220 ret, args.output_result_json, stream_engine, engine_flags)
221 221
222 222
223 def remote(args):
224 from recipe_engine import remote
225
226 return remote.main(args)
227
228
229 class ProjectOverrideAction(argparse.Action): 223 class ProjectOverrideAction(argparse.Action):
230 def __call__(self, parser, namespace, values, option_string=None): 224 def __call__(self, parser, namespace, values, option_string=None):
231 p = values.split('=', 2) 225 p = values.split('=', 2)
232 if len(p) != 2: 226 if len(p) != 2:
233 raise ValueError('Override must have the form: repo=path') 227 raise ValueError('Override must have the form: repo=path')
234 project_id, path = p 228 project_id, path = p
235 229
236 v = getattr(namespace, self.dest, None) 230 v = getattr(namespace, self.dest, None)
237 if v is None: 231 if v is None:
238 v = {} 232 v = {}
(...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after
344 help='Use bootstrap/bootstrap.py to create a isolated python virtualenv' 338 help='Use bootstrap/bootstrap.py to create a isolated python virtualenv'
345 ' with required python dependencies.') 339 ' with required python dependencies.')
346 parser.add_argument( 340 parser.add_argument(
347 '--disable-bootstrap', action='store_false', dest='use_bootstrap', 341 '--disable-bootstrap', action='store_false', dest='use_bootstrap',
348 help='Disables bootstrap (see --use-bootstrap)') 342 help='Disables bootstrap (see --use-bootstrap)')
349 343
350 def operational_args_type(value): 344 def operational_args_type(value):
351 with open(value) as fd: 345 with open(value) as fd:
352 return jsonpb.ParseDict(json.load(fd), arguments_pb2.Arguments()) 346 return jsonpb.ParseDict(json.load(fd), arguments_pb2.Arguments())
353 347
354 parser.set_defaults(operational_args=arguments_pb2.Arguments()) 348 parser.set_defaults(
349 operational_args=arguments_pb2.Arguments(),
350 bare_command=False, # don't call postprocess_func, don't use package_deps
dnj 2017/04/27 16:38:40 add a TODO here, remove this when "remote" command
351 )
355 352
356 parser.add_argument( 353 parser.add_argument(
357 '--operational-args-path', 354 '--operational-args-path',
358 dest='operational_args', 355 dest='operational_args',
359 type=operational_args_type, 356 type=operational_args_type,
360 help='The path to an operational Arguments file. If provided, this file ' 357 help='The path to an operational Arguments file. If provided, this file '
361 'must contain a JSONPB-encoded Arguments protobuf message, and will ' 358 'must contain a JSONPB-encoded Arguments protobuf message, and will '
362 'be integrated into the runtime parameters.') 359 'be integrated into the runtime parameters.')
363 360
364 def post_process_args(parser, args): 361 def post_process_args(parser, args):
365 if args.command == 'remote': 362 if args.bare_command:
366 # TODO(iannucci): this is a hack; remote doesn't behave like ANY other 363 # TODO(iannucci): this is gross, and only for the remote subcommand;
367 # commands. A way to solve this will be to allow --package to take 364 # remote doesn't behave like ANY other commands. A way to solve this will
368 # a remote repo and then simply remove the remote subcommand entirely. 365 # be to allow --package to take a remote repo and then simply remove the
369 return 366 # remote subcommand entirely.
370 367 if args.package is not None:
371 if not args.package: 368 parser.error('%s forbids --package' % args.command)
372 parser.error('%s requires --package' % args.command) 369 else:
370 if not args.package:
371 parser.error('%s requires --package' % args.command)
373 372
374 return post_process_args 373 return post_process_args
375 374
376 375
377 def main(): 376 def main():
378 parser = argparse.ArgumentParser( 377 parser = argparse.ArgumentParser(
379 description='Interact with the recipe system.') 378 description='Interact with the recipe system.')
380 379
381 common_postprocess_func = add_common_args(parser) 380 common_postprocess_func = add_common_args(parser)
382 381
383 from recipe_engine import fetch, lint_test, bundle, depgraph, autoroll 382 from recipe_engine import fetch, lint_test, bundle, depgraph, autoroll
384 to_add = [fetch, lint_test, bundle, depgraph, autoroll] 383 from recipe_engine import remote
dnj 2017/04/27 16:38:40 Since you're adding a lot of optional flags, can w
384 to_add = [fetch, lint_test, bundle, depgraph, autoroll, remote]
385 385
386 subp = parser.add_subparsers() 386 subp = parser.add_subparsers()
387 for module in to_add: 387 for module in to_add:
388 module.add_subparser(subp) 388 module.add_subparser(subp)
389 389
390 test_p = subp.add_parser( 390 test_p = subp.add_parser(
391 'test', 391 'test',
392 description='Generate or check expectations by simulation') 392 description='Generate or check expectations by simulation')
393 test_p.set_defaults(command='test') 393 test_p.set_defaults(command='test')
394 test_p.add_argument('args', nargs=argparse.REMAINDER) 394 test_p.add_argument('args', nargs=argparse.REMAINDER)
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
457 'recipe', 457 'recipe',
458 help='The recipe to execute') 458 help='The recipe to execute')
459 run_p.add_argument( 459 run_p.add_argument(
460 'props', 460 'props',
461 nargs=argparse.REMAINDER, 461 nargs=argparse.REMAINDER,
462 type=parse_prop, 462 type=parse_prop,
463 help='A list of property pairs; e.g. mastername=chromium.linux ' 463 help='A list of property pairs; e.g. mastername=chromium.linux '
464 'issue=12345. The property value will be decoded as JSON, but if ' 464 'issue=12345. The property value will be decoded as JSON, but if '
465 'this decoding fails the value will be interpreted as a string.') 465 'this decoding fails the value will be interpreted as a string.')
466 466
467
468 remote_p = subp.add_parser(
469 'remote',
470 description='Invoke a recipe command from specified repo and revision')
471 remote_p.set_defaults(command='remote')
472 remote_p.add_argument(
473 '--repository', required=True,
474 help='URL of a git repository to fetch')
475 remote_p.add_argument(
476 '--revision',
477 help=(
478 'Git commit hash to check out; defaults to latest revision on master'
479 ' (refs/heads/master)'
480 ))
481 remote_p.add_argument(
482 '--workdir',
483 type=os.path.abspath,
484 help='The working directory of repo checkout')
485 remote_p.add_argument(
486 '--use-gitiles', action='store_true',
487 help='Use Gitiles-specific way to fetch repo (potentially cheaper for '
488 'large repos)')
489 remote_p.add_argument(
490 'remote_args', nargs='*',
491 help='Arguments to pass to fetched repo\'s recipes.py')
492
493
494 refs_p = subp.add_parser( 467 refs_p = subp.add_parser(
495 'refs', 468 'refs',
496 description='List places referencing given recipe module(s).') 469 description='List places referencing given recipe module(s).')
497 refs_p.set_defaults(command='refs') 470 refs_p.set_defaults(command='refs')
498 refs_p.add_argument('modules', nargs='+', help='Module(s) to query for') 471 refs_p.add_argument('modules', nargs='+', help='Module(s) to query for')
499 refs_p.add_argument('--transitive', action='store_true', 472 refs_p.add_argument('--transitive', action='store_true',
500 help='Compute transitive closure of the references') 473 help='Compute transitive closure of the references')
501 474
502 doc_kinds=('binarypb', 'jsonpb', 'textpb', 'markdown(github)', 475 doc_kinds=('binarypb', 'jsonpb', 'textpb', 'markdown(github)',
503 'markdown(gitiles)') 476 'markdown(gitiles)')
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after
599 # wrong, log the error, but don't actually raise anything. 572 # wrong, log the error, but don't actually raise anything.
600 def on_error(_function, path, excinfo): 573 def on_error(_function, path, excinfo):
601 logging.error('Error cleaning up temporary deps file: %s', path, 574 logging.error('Error cleaning up temporary deps file: %s', path,
602 exc_info=excinfo) 575 exc_info=excinfo)
603 shutil.rmtree(temp_deps_dir, onerror=on_error) 576 shutil.rmtree(temp_deps_dir, onerror=on_error)
604 577
605 578
606 def _real_main(args): 579 def _real_main(args):
607 from recipe_engine import package 580 from recipe_engine import package
608 581
609 # Commands which do not require config_file, package_deps, and other objects 582 if args.bare_command:
610 # initialized later. 583 return args.func(None, args)
611 if args.command == 'remote':
612 return remote(args)
613 584
614 config_file = args.package 585 config_file = args.package
615 repo_root = package.InfraRepoConfig().from_recipes_cfg(args.package.path) 586 repo_root = package.InfraRepoConfig().from_recipes_cfg(args.package.path)
616 587
617 try: 588 try:
618 # TODO(phajdan.jr): gracefully handle inconsistent deps when rolling. 589 # TODO(phajdan.jr): gracefully handle inconsistent deps when rolling.
619 # This fails if the starting point does not have consistent dependency 590 # This fails if the starting point does not have consistent dependency
620 # graph. When performing an automated roll, it'd make sense to attempt 591 # graph. When performing an automated roll, it'd make sense to attempt
621 # to automatically find a consistent state, rather than bailing out. 592 # to automatically find a consistent state, rather than bailing out.
622 # Especially that only some subcommands refer to package_deps. 593 # Especially that only some subcommands refer to package_deps.
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
671 642
672 if not isinstance(ret, int): 643 if not isinstance(ret, int):
673 if ret is None: 644 if ret is None:
674 ret = 0 645 ret = 0
675 else: 646 else:
676 print >> sys.stderr, ret 647 print >> sys.stderr, ret
677 ret = 1 648 ret = 1
678 sys.stdout.flush() 649 sys.stdout.flush()
679 sys.stderr.flush() 650 sys.stderr.flush()
680 os._exit(ret) 651 os._exit(ret)
OLDNEW
« no previous file with comments | « recipe_engine/remote.py ('k') | unittests/remote_test.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698