| OLD | NEW |
| 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 223 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 234 | 234 |
| 235 if v.get(project_id): | 235 if v.get(project_id): |
| 236 raise ValueError('An override is already defined for [%s] (%s)' % ( | 236 raise ValueError('An override is already defined for [%s] (%s)' % ( |
| 237 project_id, v[project_id])) | 237 project_id, v[project_id])) |
| 238 path = os.path.abspath(os.path.expanduser(path)) | 238 path = os.path.abspath(os.path.expanduser(path)) |
| 239 if not os.path.isdir(path): | 239 if not os.path.isdir(path): |
| 240 raise ValueError('Override path [%s] is not a directory' % (path,)) | 240 raise ValueError('Override path [%s] is not a directory' % (path,)) |
| 241 v[project_id] = path | 241 v[project_id] = path |
| 242 | 242 |
| 243 | 243 |
| 244 def refs(config_file, package_deps, args): | |
| 245 from recipe_engine import refs | |
| 246 from recipe_engine import loader | |
| 247 | |
| 248 universe = loader.RecipeUniverse(package_deps, config_file) | |
| 249 | |
| 250 refs.main(universe, package_deps.root_package, args.modules, args.transitive) | |
| 251 | |
| 252 | |
| 253 def doc(config_file, package_deps, args): | 244 def doc(config_file, package_deps, args): |
| 254 from recipe_engine import doc | 245 from recipe_engine import doc |
| 255 from recipe_engine import loader | 246 from recipe_engine import loader |
| 256 | 247 |
| 257 universe = loader.RecipeUniverse(package_deps, config_file) | 248 universe = loader.RecipeUniverse(package_deps, config_file) |
| 258 universe_view = loader.UniverseView(universe, package_deps.root_package) | 249 universe_view = loader.UniverseView(universe, package_deps.root_package) |
| 259 | 250 |
| 260 doc.main(universe_view, args.recipe, args.kind) | 251 doc.main(universe_view, args.recipe, args.kind) |
| 261 | 252 |
| 262 | 253 |
| (...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 373 return post_process_args | 364 return post_process_args |
| 374 | 365 |
| 375 | 366 |
| 376 def main(): | 367 def main(): |
| 377 parser = argparse.ArgumentParser( | 368 parser = argparse.ArgumentParser( |
| 378 description='Interact with the recipe system.') | 369 description='Interact with the recipe system.') |
| 379 | 370 |
| 380 common_postprocess_func = add_common_args(parser) | 371 common_postprocess_func = add_common_args(parser) |
| 381 | 372 |
| 382 from recipe_engine import fetch, lint_test, bundle, depgraph, autoroll | 373 from recipe_engine import fetch, lint_test, bundle, depgraph, autoroll |
| 383 from recipe_engine import remote | 374 from recipe_engine import remote, refs |
| 384 to_add = [fetch, lint_test, bundle, depgraph, autoroll, remote] | 375 to_add = [fetch, lint_test, bundle, depgraph, autoroll, remote, refs] |
| 385 | 376 |
| 386 subp = parser.add_subparsers() | 377 subp = parser.add_subparsers() |
| 387 for module in to_add: | 378 for module in to_add: |
| 388 module.add_subparser(subp) | 379 module.add_subparser(subp) |
| 389 | 380 |
| 390 test_p = subp.add_parser( | 381 test_p = subp.add_parser( |
| 391 'test', | 382 'test', |
| 392 description='Generate or check expectations by simulation') | 383 description='Generate or check expectations by simulation') |
| 393 test_p.set_defaults(command='test') | 384 test_p.set_defaults(command='test') |
| 394 test_p.add_argument('args', nargs=argparse.REMAINDER) | 385 test_p.add_argument('args', nargs=argparse.REMAINDER) |
| (...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 457 'recipe', | 448 'recipe', |
| 458 help='The recipe to execute') | 449 help='The recipe to execute') |
| 459 run_p.add_argument( | 450 run_p.add_argument( |
| 460 'props', | 451 'props', |
| 461 nargs=argparse.REMAINDER, | 452 nargs=argparse.REMAINDER, |
| 462 type=parse_prop, | 453 type=parse_prop, |
| 463 help='A list of property pairs; e.g. mastername=chromium.linux ' | 454 help='A list of property pairs; e.g. mastername=chromium.linux ' |
| 464 'issue=12345. The property value will be decoded as JSON, but if ' | 455 'issue=12345. The property value will be decoded as JSON, but if ' |
| 465 'this decoding fails the value will be interpreted as a string.') | 456 'this decoding fails the value will be interpreted as a string.') |
| 466 | 457 |
| 467 refs_p = subp.add_parser( | |
| 468 'refs', | |
| 469 description='List places referencing given recipe module(s).') | |
| 470 refs_p.set_defaults(command='refs') | |
| 471 refs_p.add_argument('modules', nargs='+', help='Module(s) to query for') | |
| 472 refs_p.add_argument('--transitive', action='store_true', | |
| 473 help='Compute transitive closure of the references') | |
| 474 | |
| 475 doc_kinds=('binarypb', 'jsonpb', 'textpb', 'markdown(github)', | 458 doc_kinds=('binarypb', 'jsonpb', 'textpb', 'markdown(github)', |
| 476 'markdown(gitiles)') | 459 'markdown(gitiles)') |
| 477 doc_p = subp.add_parser( | 460 doc_p = subp.add_parser( |
| 478 'doc', | 461 'doc', |
| 479 description='List all known modules reachable from the current package, ' | 462 description='List all known modules reachable from the current package, ' |
| 480 'with their documentation') | 463 'with their documentation') |
| 481 doc_p.add_argument('recipe', nargs='?', | 464 doc_p.add_argument('recipe', nargs='?', |
| 482 help='Restrict documentation to this recipe') | 465 help='Restrict documentation to this recipe') |
| 483 doc_p.add_argument('--kind', default='jsonpb', choices=doc_kinds, | 466 doc_p.add_argument('--kind', default='jsonpb', choices=doc_kinds, |
| 484 help='Output this kind of documentation') | 467 help='Output this kind of documentation') |
| (...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 599 # an infra failure, rather than a test failure. | 582 # an infra failure, rather than a test failure. |
| 600 return 2 | 583 return 2 |
| 601 | 584 |
| 602 if hasattr(args, 'func'): | 585 if hasattr(args, 'func'): |
| 603 return args.func(package_deps, args) | 586 return args.func(package_deps, args) |
| 604 | 587 |
| 605 if args.command == 'test': | 588 if args.command == 'test': |
| 606 return test(config_file, package_deps, args) | 589 return test(config_file, package_deps, args) |
| 607 elif args.command == 'run': | 590 elif args.command == 'run': |
| 608 return run(config_file, package_deps, args) | 591 return run(config_file, package_deps, args) |
| 609 elif args.command == 'refs': | |
| 610 return refs(config_file, package_deps, args) | |
| 611 elif args.command == 'doc': | 592 elif args.command == 'doc': |
| 612 return doc(config_file, package_deps, args) | 593 return doc(config_file, package_deps, args) |
| 613 else: | 594 else: |
| 614 print """Dear sir or madam, | 595 print """Dear sir or madam, |
| 615 It has come to my attention that a quite impossible condition has come | 596 It has come to my attention that a quite impossible condition has come |
| 616 to pass in the specification you have issued a request for us to fulfill. | 597 to pass in the specification you have issued a request for us to fulfill. |
| 617 It is with a heavy heart that I inform you that, at the present juncture, | 598 It is with a heavy heart that I inform you that, at the present juncture, |
| 618 there is no conceivable next action to be taken upon your request, and as | 599 there is no conceivable next action to be taken upon your request, and as |
| 619 such, we have decided to abort the request with a nonzero status code. We | 600 such, we have decided to abort the request with a nonzero status code. We |
| 620 hope that your larger goals have not been put at risk due to this | 601 hope that your larger goals have not been put at risk due to this |
| (...skipping 21 matching lines...) Expand all Loading... |
| 642 | 623 |
| 643 if not isinstance(ret, int): | 624 if not isinstance(ret, int): |
| 644 if ret is None: | 625 if ret is None: |
| 645 ret = 0 | 626 ret = 0 |
| 646 else: | 627 else: |
| 647 print >> sys.stderr, ret | 628 print >> sys.stderr, ret |
| 648 ret = 1 | 629 ret = 1 |
| 649 sys.stdout.flush() | 630 sys.stdout.flush() |
| 650 sys.stderr.flush() | 631 sys.stderr.flush() |
| 651 os._exit(ret) | 632 os._exit(ret) |
| OLD | NEW |