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

Side by Side Diff: recipes.py

Issue 2511213002: Move ENV into custom deps, allow it to be random. (Closed)
Patch Set: Created 4 years, 1 month 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 """
11 11
12 import argparse 12 import argparse
13 import collections 13 import collections
14 import json 14 import json
15 import logging 15 import logging
16 import os 16 import os
17 import shutil
17 import subprocess 18 import subprocess
18 import sys 19 import sys
20 import tempfile
19 21
20 ROOT_DIR = os.path.dirname(os.path.abspath(__file__)) 22 ROOT_DIR = os.path.dirname(os.path.abspath(__file__))
21 sys.path.insert(0, ROOT_DIR) 23 sys.path.insert(0, ROOT_DIR)
22 24
23 from recipe_engine import env 25 from recipe_engine import env
24 from recipe_engine import arguments_pb2 26 from recipe_engine import arguments_pb2
25 from google.protobuf import json_format as jsonpb 27 from google.protobuf import json_format as jsonpb
26 from google.protobuf import text_format as textpb 28 from google.protobuf import text_format as textpb
27 29
28 def get_package_config(args): 30 def get_package_config(args):
(...skipping 338 matching lines...) Expand 10 before | Expand all | Expand 10 after
367 """Creates a properties dictionary from an arguments_pb2.PropertyMap entry. 369 """Creates a properties dictionary from an arguments_pb2.PropertyMap entry.
368 370
369 Args: 371 Args:
370 pmap (arguments_pb2.PropertyMap): Map to convert to dictionary form. 372 pmap (arguments_pb2.PropertyMap): Map to convert to dictionary form.
371 Returns (dict): A dictionary derived from the properties in "pmap". 373 Returns (dict): A dictionary derived from the properties in "pmap".
372 """ 374 """
373 return dict((k, _op_property_value(pmap[k])) for k in pmap) 375 return dict((k, _op_property_value(pmap[k])) for k in pmap)
374 376
375 377
376 def main(): 378 def main():
377 from recipe_engine import package
378
379 # Super-annoyingly, we need to manually parse for simulation_test since 379 # Super-annoyingly, we need to manually parse for simulation_test since
380 # argparse is bonkers and doesn't allow us to forward --help to subcommands. 380 # argparse is bonkers and doesn't allow us to forward --help to subcommands.
381 # Save old_args for if we're using bootstrap 381 # Save old_args for if we're using bootstrap
382 original_sys_argv = sys.argv[:] 382 original_sys_argv = sys.argv[:]
383 if 'simulation_test' in sys.argv: 383 if 'simulation_test' in sys.argv:
384 index = sys.argv.index('simulation_test') 384 index = sys.argv.index('simulation_test')
385 sys.argv = sys.argv[:index+1] + [json.dumps(sys.argv[index+1:])] 385 sys.argv = sys.argv[:index+1] + [json.dumps(sys.argv[index+1:])]
386 386
387 parser = argparse.ArgumentParser( 387 parser = argparse.ArgumentParser(
388 description='Interact with the recipe system.') 388 description='Interact with the recipe system.')
389 389
390 parser.add_argument( 390 parser.add_argument(
391 '--package', 391 '--package',
392 help='Path to recipes.cfg of the recipe package to operate on' 392 help='Path to recipes.cfg of the recipe package to operate on'
393 ', usually in infra/config/recipes.cfg') 393 ', usually in infra/config/recipes.cfg')
394 parser.add_argument( 394 parser.add_argument(
395 '--deps-path', 395 '--deps-path',
396 help='Path where recipe engine dependencies will be extracted.') 396 help='Path where recipe engine dependencies will be extracted. Specify '
397 '"-" to use a temporary directory for deps, which will be cleaned '
398 'up on exit.')
397 parser.add_argument( 399 parser.add_argument(
398 '--verbose', '-v', action='count', 400 '--verbose', '-v', action='count',
399 help='Increase logging verboisty') 401 help='Increase logging verboisty')
400 # TODO(phajdan.jr): Figure out if we need --no-fetch; remove if not. 402 # TODO(phajdan.jr): Figure out if we need --no-fetch; remove if not.
401 parser.add_argument( 403 parser.add_argument(
402 '--no-fetch', action='store_true', 404 '--no-fetch', action='store_true',
403 help='Disable automatic fetching') 405 help='Disable automatic fetching')
404 parser.add_argument('-O', '--project-override', metavar='ID=PATH', 406 parser.add_argument('-O', '--project-override', metavar='ID=PATH',
405 action=ProjectOverrideAction, 407 action=ProjectOverrideAction,
406 help='Override a project repository path with a local one.') 408 help='Override a project repository path with a local one.')
(...skipping 147 matching lines...) Expand 10 before | Expand all | Expand 10 after
554 556
555 args = parser.parse_args() 557 args = parser.parse_args()
556 558
557 # Load/parse operational arguments. 559 # Load/parse operational arguments.
558 op_args = arguments_pb2.Arguments() 560 op_args = arguments_pb2.Arguments()
559 if args.operational_args_path is not None: 561 if args.operational_args_path is not None:
560 with open(args.operational_args_path) as fd: 562 with open(args.operational_args_path) as fd:
561 data = fd.read() 563 data = fd.read()
562 jsonpb.Parse(data, op_args) 564 jsonpb.Parse(data, op_args)
563 565
564 if args.use_bootstrap and not os.environ.pop('RECIPES_RUN_BOOTSTRAP', None):
565 subprocess.check_call(
566 [sys.executable, 'bootstrap/bootstrap.py', '--deps-file',
567 'bootstrap/deps.pyl', 'ENV'],
568 cwd=os.path.dirname(os.path.realpath(__file__)))
569
570 os.environ['RECIPES_RUN_BOOTSTRAP'] = '1'
571 args = sys.argv
572 return subprocess.call(
573 [os.path.join(
574 os.path.dirname(os.path.realpath(__file__)), 'ENV/bin/python'),
575 os.path.join(ROOT_DIR, 'recipes.py')] + original_sys_argv[1:])
576
577 if args.verbose > 1: 566 if args.verbose > 1:
578 logging.getLogger().setLevel(logging.DEBUG) 567 logging.getLogger().setLevel(logging.DEBUG)
579 elif args.verbose > 0: 568 elif args.verbose > 0:
580 logging.getLogger().setLevel(logging.INFO) 569 logging.getLogger().setLevel(logging.INFO)
581 570
571 # If we're using a temporary deps directory, create it.
572 temp_deps_dir = None
573 try:
574 # When bootstrapping, re-use the calling wrapper's deps directory instead of
575 # creating a new one.
576 args.deps_path = os.environ.pop('RECIPES_RUN_BOOTSTRAP_DEPS_DIR',
577 args.deps_path)
578 if args.deps_path == '-':
579 # "-" means use a temporary deps path.
580 temp_deps_dir = tempfile.mkdtemp(dir=ROOT_DIR, suffix='_deps')
581 args.deps_path = temp_deps_dir
582
583 if args.deps_path:
584 logging.debug('Using custom deps path: %s', args.deps_path)
iannucci 2016/11/17 21:15:04 let's make this warning?
dnj 2016/11/17 21:27:56 Done.
Michael Moss 2016/12/02 17:08:57 Am I doing something wrong, or is expected that I
585
586 # If we're bootstrapping, construct our bootstrap environment. If we're
587 # using a custom deps path, install our enviornment there too.
588 if args.use_bootstrap and not os.environ.pop('RECIPES_RUN_BOOTSTRAP', None):
589 # Propagate our deps path, if specified, so we re-use our temporary
590 # directory.
591 if args.deps_path:
592 env_path = os.path.join(args.deps_path, 'ENV')
iannucci 2016/11/17 21:15:04 let's just make it .ENV
dnj 2016/11/17 21:27:56 Done.
593 os.environ['RECIPES_RUN_BOOTSTRAP_DEPS_DIR'] = args.deps_path
594 else:
595 env_path = os.path.join(ROOT_DIR, 'ENV')
596
597 logging.debug('Installing bootstrap environment into: %s', env_path)
598 subprocess.check_call(
599 [
600 sys.executable,
601 os.path.join(ROOT_DIR, 'bootstrap', 'bootstrap.py'),
602 '--deps-file', os.path.join(ROOT_DIR, 'bootstrap', 'deps.pyl'),
603 env_path,
604 ],
605 cwd=ROOT_DIR)
606
607 # Mark that we're bootstrapping, so the next invocation falls through to
608 # standard recipe operation.
609 os.environ['RECIPES_RUN_BOOTSTRAP'] = '1'
610 args = sys.argv
611 return subprocess.call(
612 [
613 os.path.join(env_path, 'bin', 'python'),
614 os.path.join(ROOT_DIR, 'recipes.py'),
615 ] + original_sys_argv[1:])
616
617 # Standard recipe engine operation.
618 return _real_main(args, op_args)
619
620 finally:
621 # If we're using a temporary deps directory, clean it up here.
622 if temp_deps_dir:
623 logging.info('Cleaning up temporary deps path: %s', temp_deps_dir)
624 shutil.rmtree(temp_deps_dir)
iannucci 2016/11/17 21:15:04 can we log the warning instead of throwing if this
dnj 2016/11/17 21:27:56 Done.
625
626
627 def _real_main(args, op_args):
628 from recipe_engine import package
629
582 # Commands which do not require config_file, package_deps, and other objects 630 # Commands which do not require config_file, package_deps, and other objects
583 # initialized later. 631 # initialized later.
584 if args.command == 'remote': 632 if args.command == 'remote':
585 return remote(args) 633 return remote(args)
586 634
587 repo_root, config_file = get_package_config(args) 635 repo_root, config_file = get_package_config(args)
588 636
589 try: 637 try:
590 # TODO(phajdan.jr): gracefully handle inconsistent deps when rolling. 638 # TODO(phajdan.jr): gracefully handle inconsistent deps when rolling.
591 # This fails if the starting point does not have consistent dependency 639 # This fails if the starting point does not have consistent dependency
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
652 700
653 if not isinstance(ret, int): 701 if not isinstance(ret, int):
654 if ret is None: 702 if ret is None:
655 ret = 0 703 ret = 0
656 else: 704 else:
657 print >> sys.stderr, ret 705 print >> sys.stderr, ret
658 ret = 1 706 ret = 1
659 sys.stdout.flush() 707 sys.stdout.flush()
660 sys.stderr.flush() 708 sys.stderr.flush()
661 os._exit(ret) 709 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