From 84140c6cd325b6a3130bd0e5df0afdf083ea7b1e Mon Sep 17 00:00:00 2001 From: Todd Gamblin Date: Sun, 19 Aug 2018 09:01:32 -0700 Subject: env: add -e as global spack argument, make `spack -e spec` work - add -E/--exact-env instead of --use-env-repo - simplify env handling in `spack find` --- lib/spack/spack/cmd/common/arguments.py | 18 +++---------- lib/spack/spack/cmd/env.py | 17 +----------- lib/spack/spack/cmd/find.py | 2 +- lib/spack/spack/cmd/spec.py | 6 +---- lib/spack/spack/environment.py | 46 ++++++++++++++++++++++++++++++--- lib/spack/spack/main.py | 15 +++++++++++ 6 files changed, 64 insertions(+), 40 deletions(-) (limited to 'lib') diff --git a/lib/spack/spack/cmd/common/arguments.py b/lib/spack/spack/cmd/common/arguments.py index 84f61a12cc..6b20fbc014 100644 --- a/lib/spack/spack/cmd/common/arguments.py +++ b/lib/spack/spack/cmd/common/arguments.py @@ -49,16 +49,14 @@ class ConstraintAction(argparse.Action): namespace.constraint = values namespace.specs = self._specs - # env comes from EnvAction if --env is provided - self.env = None if not hasattr(namespace, 'env') else namespace.env - def _specs(self, **kwargs): qspecs = spack.cmd.parse_specs(self.values) # If an environment is provided, we'll restrict the search to # only its installed packages. - if self.env: - kwargs['hashes'] = set(self.env.specs_by_hash.keys()) + env = spack.environment.active + if env: + kwargs['hashes'] = set(env.specs_by_hash.keys()) # return everything for an empty query. if not qspecs: @@ -74,16 +72,6 @@ class ConstraintAction(argparse.Action): return sorted(specs.values()) -class EnvAction(argparse.Action): - """Records the environment to which a command applies.""" - def __call__(self, parser, namespace, env_name, option_string=None): - namespace.env = spack.environment.read(env_name) - - -_arguments['env'] = Args( - '-e', '--env', action=EnvAction, default=None, - help="run this command on a specific environment") - _arguments['constraint'] = Args( 'constraint', nargs=argparse.REMAINDER, action=ConstraintAction, help='constraint to select a subset of installed packages') diff --git a/lib/spack/spack/cmd/env.py b/lib/spack/spack/cmd/env.py index da089c35c4..f96aa8efeb 100644 --- a/lib/spack/spack/cmd/env.py +++ b/lib/spack/spack/cmd/env.py @@ -12,7 +12,6 @@ import spack.environment as ev import spack.util.spack_yaml as syaml import spack.config -import spack.cmd.spec import spack.cmd.install import spack.cmd.uninstall import spack.cmd.module @@ -21,7 +20,7 @@ import spack.cmd.common.arguments as arguments import llnl.util.tty as tty import llnl.util.filesystem as fs -description = "group a subset of packages" +description = "manage virtual environments" section = "environment" level = "long" @@ -32,7 +31,6 @@ subcommands = [ 'add', 'remove', 'upgrade', - 'spec', 'concretize', 'list', 'loads', @@ -145,19 +143,6 @@ def environment_remove(args): ev.write(environment) -def setup_spec_parser(subparser): - """show results of concretizing a spec for an environment""" - spack.cmd.spec.add_common_arguments(subparser) - add_use_repo_argument(subparser) - - -def environment_spec(args): - environment = ev.read(args.environment) - ev.prepare_repository(environment, use_repo=args.use_repo) - ev.prepare_config_scope(environment) - spack.cmd.spec.spec(None, args) - - def setup_concretize_parser(subparser): """concretize user specs and write lockfile""" subparser.add_argument( diff --git a/lib/spack/spack/cmd/find.py b/lib/spack/spack/cmd/find.py index 5c7a508a46..680e44af28 100644 --- a/lib/spack/spack/cmd/find.py +++ b/lib/spack/spack/cmd/find.py @@ -38,7 +38,7 @@ def setup_parser(subparser): help='show full dependency DAG of installed packages') arguments.add_common_arguments( - subparser, ['env', 'long', 'very_long', 'tags']) + subparser, ['long', 'very_long', 'tags']) subparser.add_argument('-f', '--show-flags', action='store_true', diff --git a/lib/spack/spack/cmd/spec.py b/lib/spack/spack/cmd/spec.py index c0ce5b9bad..cc5172beb6 100644 --- a/lib/spack/spack/cmd/spec.py +++ b/lib/spack/spack/cmd/spec.py @@ -19,7 +19,7 @@ section = "build" level = "short" -def add_common_arguments(subparser): +def setup_parser(subparser): arguments.add_common_arguments( subparser, ['long', 'very_long', 'install_status']) subparser.add_argument( @@ -40,10 +40,6 @@ def add_common_arguments(subparser): 'specs', nargs=argparse.REMAINDER, help="specs of packages") -def setup_parser(subparser): - add_common_arguments(subparser) - - def spec(parser, args): name_fmt = '$.' if args.namespaces else '$_' kwargs = {'cover': args.cover, diff --git a/lib/spack/spack/environment.py b/lib/spack/spack/environment.py index 597fa14802..cc34f8a7ba 100644 --- a/lib/spack/spack/environment.py +++ b/lib/spack/spack/environment.py @@ -40,10 +40,52 @@ from spack.spec import Spec, CompilerSpec, FlagMap from spack.version import VersionList +#: currently activated environment +active = None + + #: path where environments are stored in the spack tree env_path = fs.join_path(spack.paths.var_path, 'environments') +def activate(name, exact=False): + """Activate an environment. + + To activate an environment, we add its configuration scope to the + existing Spack configuration, and we set active to the current + environment. + + Arguments: + name (str): name of the environment to activate + exact (bool): use the packages exactly as they appear in the + environment's repository + + TODO: Add support for views here. Activation should set up the shell + TODO: environment to use the activated spack environment. + """ + global active + + active = read(name) + prepare_config_scope(active) + prepare_repository(active, use_repo=exact) + + tty.msg("Using environmennt '%s'" % active.name) + + +def deactivate(): + """Undo any configuration or repo settings modified by ``activate()``. + + Returns: + (bool): True if an environment was deactivated, False if no + environment was active. + + """ + global active + if not active: + return + + + def root(name): """Get the root directory for an environment by name.""" return fs.join_path(env_path, name) @@ -180,7 +222,7 @@ class Environment(object): def install(self, install_args=None): """Do a `spack install` on all the (concretized) - specs in an Environment.""" + specs in an Environment.""" # Make sure log directory exists logs = fs.join_path(self.path, 'logs') @@ -462,8 +504,6 @@ def prepare_config_scope(environment): tty.die('Spack config %s (%s) not found' % (config_name, config_dir)) - tty.msg('Using Spack config %s scope at %s' % - (config_name, config_dir)) spack.config.config.push_scope(ConfigScope(config_name, config_dir)) diff --git a/lib/spack/spack/main.py b/lib/spack/spack/main.py index 9bcbd776a5..a1b83e8ac8 100644 --- a/lib/spack/spack/main.py +++ b/lib/spack/spack/main.py @@ -25,6 +25,7 @@ import spack import spack.architecture import spack.config import spack.cmd +import spack.environment import spack.hooks import spack.paths import spack.repo @@ -320,6 +321,15 @@ def make_argument_parser(**kwargs): parser.add_argument( '-D', '--pdb', action='store_true', help="run spack under the pdb debugger") + + env_group = parser.add_mutually_exclusive_group() + env_group.add_argument( + '-e', '--env', dest='env', metavar='ENV', action='store', + help="run spack with a specific environment (see spack env)") + env_group.add_argument( + '-E', '--exact-env', dest='exact_env', metavar='ENV', action='store', + help="run spack with a specific environment AND use its repo") + parser.add_argument( '-k', '--insecure', action='store_true', help="do not check ssl certificates when downloading") @@ -573,6 +583,11 @@ def main(argv=None): parser.add_argument('command', nargs=argparse.REMAINDER) args, unknown = parser.parse_known_args(argv) + # activate an environment if one was specified on the command line + env = args.env or args.exact_env + if env: + spack.environment.activate(env, args.exact_env is not None) + # make spack.config aware of any command line configuration scopes if args.config_scopes: spack.config.command_line_scopes = args.config_scopes -- cgit v1.2.3-60-g2f50