| 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 204 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 215 | 215 |
| 216 if args.recipes_dir: | 216 if args.recipes_dir: |
| 217 print package_spec.recipes_path | 217 print package_spec.recipes_path |
| 218 | 218 |
| 219 | 219 |
| 220 def main(): | 220 def main(): |
| 221 from recipe_engine import package | 221 from recipe_engine import package |
| 222 | 222 |
| 223 # Super-annoyingly, we need to manually parse for simulation_test since | 223 # Super-annoyingly, we need to manually parse for simulation_test since |
| 224 # argparse is bonkers and doesn't allow us to forward --help to subcommands. | 224 # argparse is bonkers and doesn't allow us to forward --help to subcommands. |
| 225 # Save old_args for if we're using bootstrap |
| 226 original_sys_argv = sys.argv[:] |
| 225 if 'simulation_test' in sys.argv: | 227 if 'simulation_test' in sys.argv: |
| 226 index = sys.argv.index('simulation_test') | 228 index = sys.argv.index('simulation_test') |
| 227 sys.argv = sys.argv[:index+1] + [json.dumps(sys.argv[index+1:])] | 229 sys.argv = sys.argv[:index+1] + [json.dumps(sys.argv[index+1:])] |
| 228 | 230 |
| 229 parser = argparse.ArgumentParser( | 231 parser = argparse.ArgumentParser( |
| 230 description='Interact with the recipe system.') | 232 description='Interact with the recipe system.') |
| 231 | 233 |
| 232 parser.add_argument( | 234 parser.add_argument( |
| 233 '--package', | 235 '--package', |
| 234 help='Path to recipes.cfg of the recipe package to operate on' | 236 help='Path to recipes.cfg of the recipe package to operate on' |
| 235 ', usually in infra/config/recipes.cfg') | 237 ', usually in infra/config/recipes.cfg') |
| 236 parser.add_argument( | 238 parser.add_argument( |
| 237 '--deps-path', | 239 '--deps-path', |
| 238 help='Path where recipe engine dependencies will be extracted.') | 240 help='Path where recipe engine dependencies will be extracted.') |
| 239 parser.add_argument( | 241 parser.add_argument( |
| 240 '--verbose', '-v', action='store_true', | 242 '--verbose', '-v', action='store_true', |
| 241 help='Increase logging verboisty') | 243 help='Increase logging verboisty') |
| 242 # TODO(phajdan.jr): Figure out if we need --no-fetch; remove if not. | 244 # TODO(phajdan.jr): Figure out if we need --no-fetch; remove if not. |
| 243 parser.add_argument( | 245 parser.add_argument( |
| 244 '--no-fetch', action='store_true', | 246 '--no-fetch', action='store_true', |
| 245 help='Disable automatic fetching') | 247 help='Disable automatic fetching') |
| 246 parser.add_argument( | 248 parser.add_argument( |
| 247 '--bootstrap-script', | 249 '--bootstrap-script', |
| 248 help='Path to the script used to bootstrap this tool (internal use only)') | 250 help='Path to the script used to bootstrap this tool (internal use only)') |
| 249 parser.add_argument('-O', '--project-override', metavar='ID=PATH', | 251 parser.add_argument('-O', '--project-override', metavar='ID=PATH', |
| 250 action=ProjectOverrideAction, | 252 action=ProjectOverrideAction, |
| 251 help='Override a project repository path with a local one.') | 253 help='Override a project repository path with a local one.') |
| 254 parser.add_argument( |
| 255 '--use-bootstrap', action='store_true', |
| 256 help='Use bootstrap/bootstrap.py to create a isolated python virtualenv' |
| 257 ' with required python dependencies.') |
| 252 | 258 |
| 253 subp = parser.add_subparsers() | 259 subp = parser.add_subparsers() |
| 254 | 260 |
| 255 fetch_p = subp.add_parser( | 261 fetch_p = subp.add_parser( |
| 256 'fetch', | 262 'fetch', |
| 257 description='Fetch and update dependencies.') | 263 description='Fetch and update dependencies.') |
| 258 fetch_p.set_defaults(command='fetch') | 264 fetch_p.set_defaults(command='fetch') |
| 259 | 265 |
| 260 simulation_test_p = subp.add_parser( | 266 simulation_test_p = subp.add_parser( |
| 261 'simulation_test', | 267 'simulation_test', |
| (...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 369 info_p = subp.add_parser( | 375 info_p = subp.add_parser( |
| 370 'info', | 376 'info', |
| 371 description='Query information about the current recipe package') | 377 description='Query information about the current recipe package') |
| 372 info_p.set_defaults(command='info') | 378 info_p.set_defaults(command='info') |
| 373 info_p.add_argument( | 379 info_p.add_argument( |
| 374 '--recipes-dir', action='store_true', | 380 '--recipes-dir', action='store_true', |
| 375 help='Get the subpath where the recipes live relative to repository root') | 381 help='Get the subpath where the recipes live relative to repository root') |
| 376 | 382 |
| 377 args = parser.parse_args() | 383 args = parser.parse_args() |
| 378 | 384 |
| 385 if args.use_bootstrap and not os.environ.pop('RECIPES_RUN_BOOTSTRAP', None): |
| 386 subprocess.check_call( |
| 387 [sys.executable, 'bootstrap/bootstrap.py', '--deps-file', |
| 388 'bootstrap/deps.pyl', 'ENV'], |
| 389 cwd=os.path.dirname(os.path.realpath(__file__))) |
| 390 |
| 391 os.environ['RECIPES_RUN_BOOTSTRAP'] = '1' |
| 392 args = sys.argv |
| 393 return subprocess.call( |
| 394 ['ENV/bin/python'] + original_sys_argv, |
| 395 cwd=os.path.dirname(os.path.realpath(__file__))) |
| 396 |
| 379 if args.verbose: | 397 if args.verbose: |
| 380 logging.getLogger().setLevel(logging.INFO) | 398 logging.getLogger().setLevel(logging.INFO) |
| 381 | 399 |
| 382 # Commands which do not require config_file, package_deps, and other objects | 400 # Commands which do not require config_file, package_deps, and other objects |
| 383 # initialized later. | 401 # initialized later. |
| 384 if args.command == 'remote_run': | 402 if args.command == 'remote_run': |
| 385 return remote_run(args) | 403 return remote_run(args) |
| 386 | 404 |
| 387 repo_root, config_file = get_package_config(args) | 405 repo_root, config_file = get_package_config(args) |
| 388 | 406 |
| (...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 443 ret = main() | 461 ret = main() |
| 444 if not isinstance(ret, int): | 462 if not isinstance(ret, int): |
| 445 if ret is None: | 463 if ret is None: |
| 446 ret = 0 | 464 ret = 0 |
| 447 else: | 465 else: |
| 448 print >> sys.stderr, ret | 466 print >> sys.stderr, ret |
| 449 ret = 1 | 467 ret = 1 |
| 450 sys.stdout.flush() | 468 sys.stdout.flush() |
| 451 sys.stderr.flush() | 469 sys.stderr.flush() |
| 452 os._exit(ret) | 470 os._exit(ret) |
| OLD | NEW |