Skip to content

Commit e63b45b

Browse files
committed
env: moved all spack env install functionality into spack install
- moved get_env from cmd/env.py to environment.py - spack install will now install into the active environment when no arguments are provided. It looks: 1. at the command line 2. for a local spack.yaml file 3. for any currently activated environment
1 parent 08e4720 commit e63b45b

File tree

4 files changed

+110
-124
lines changed

4 files changed

+110
-124
lines changed

lib/spack/spack/cmd/env.py

Lines changed: 8 additions & 75 deletions
Original file line numberDiff line numberDiff line change
@@ -39,46 +39,10 @@
3939
['status', 'st'],
4040
'loads',
4141
'stage',
42-
'install',
4342
'uninstall',
4443
]
4544

4645

47-
def get_env(args, cmd_name, fail_on_error=True):
48-
"""Get target environment from args, or from environment variables.
49-
50-
This is used by a number of commands for handling the environment
51-
argument.
52-
53-
Check whether an environment was passed via arguments, then whether
54-
it was passed via SPACK_ENV. If an environment is found, read it in.
55-
If not, print an error message referencing the calling command.
56-
57-
Arguments:
58-
args (Namespace): argparse namespace wtih command arguments
59-
cmd_name (str): name of calling command
60-
61-
"""
62-
env = args.env
63-
if not env:
64-
if ev.active:
65-
return ev.active
66-
elif not fail_on_error:
67-
return None
68-
tty.die(
69-
'`spack env %s` requires an environment' % cmd_name,
70-
'activate an environment first:',
71-
' spack env activate ENV',
72-
'or use:',
73-
' spack -e ENV %s ...' % cmd_name)
74-
75-
environment = ev.disambiguate(env)
76-
77-
if not environment:
78-
tty.die('no such environment: %s' % env)
79-
return environment
80-
81-
8246
#
8347
# env activate
8448
#
@@ -316,7 +280,7 @@ def env_add_setup_parser(subparser):
316280

317281

318282
def env_add(args):
319-
env = get_env(args, 'add')
283+
env = ev.get_env(args, 'env add')
320284

321285
for spec in spack.cmd.parse_specs(args.specs):
322286
if not env.add(spec):
@@ -340,7 +304,7 @@ def env_remove_setup_parser(subparser):
340304

341305

342306
def env_remove(args):
343-
env = get_env(args, 'remove <spec>')
307+
env = ev.get_env(args, 'env remove <spec>')
344308

345309
if args.all:
346310
env.clear()
@@ -364,41 +328,10 @@ def env_concretize_setup_parser(subparser):
364328

365329

366330
def env_concretize(args):
367-
env = get_env(args, 'status')
368-
_env_concretize(env, use_repo=args.use_env_repo, force=args.force)
369-
370-
371-
def _env_concretize(env, use_repo=False, force=False):
372-
"""Function body separated out to aid in testing."""
373-
env.concretize(force=force)
331+
env = ev.get_env(args, 'env concretize')
332+
env.concretize(force=args.force)
374333
env.write()
375334

376-
377-
# REMOVE
378-
# env install
379-
#
380-
def env_install_setup_parser(subparser):
381-
"""concretize and install all specs in an environment"""
382-
subparser.add_argument(
383-
'env', nargs='?', help='install all packages in this environment')
384-
subparser.add_argument(
385-
'--only-concrete', action='store_true', default=False,
386-
help='only install already concretized specs')
387-
spack.cmd.install.add_common_arguments(subparser)
388-
389-
390-
def env_install(args):
391-
env = get_env(args, 'status')
392-
393-
# concretize unless otherwise specified
394-
if not args.only_concrete:
395-
env.concretize()
396-
env.write()
397-
398-
# install all specs in the environment
399-
env.install_all(args)
400-
401-
402335
# REMOVE
403336
# env uninstall
404337
#
@@ -410,7 +343,7 @@ def env_uninstall_setup_parser(subparser):
410343

411344

412345
def env_uninstall(args):
413-
env = get_env(args, 'uninstall')
346+
env = ev.get_env(args, 'env uninstall')
414347
env.uninstall(args)
415348

416349

@@ -427,7 +360,7 @@ def env_status_setup_parser(subparser):
427360

428361

429362
def env_status(args):
430-
env = get_env(args, 'status', fail_on_error=False)
363+
env = ev.get_env(args, 'env status', required=False)
431364
if not env:
432365
tty.msg('No active environment')
433366
return
@@ -450,7 +383,7 @@ def env_stage_setup_parser(subparser):
450383

451384

452385
def env_stage(args):
453-
env = get_env(args, 'stage')
386+
env = ev.get_env(args, 'env stage')
454387
for spec in env.specs_by_hash.values():
455388
for dep in spec.traverse():
456389
dep.package.do_stage()
@@ -470,7 +403,7 @@ def env_loads_setup_parser(subparser):
470403

471404

472405
def env_loads(args):
473-
env = get_env(args, 'loads')
406+
env = ev.get_env(args, 'env loads')
474407

475408
# Set the module types that have been selected
476409
module_type = args.module_type

lib/spack/spack/cmd/install.py

Lines changed: 45 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -26,41 +26,6 @@
2626
level = "short"
2727

2828

29-
def add_common_arguments(subparser):
30-
arguments.add_common_arguments(subparser, ['jobs', 'install_status'])
31-
subparser.add_argument(
32-
'--overwrite', action='store_true',
33-
help="reinstall an existing spec, even if it has dependents")
34-
subparser.add_argument(
35-
'--keep-prefix', action='store_true',
36-
help="don't remove the install prefix if installation fails")
37-
subparser.add_argument(
38-
'--keep-stage', action='store_true',
39-
help="don't remove the build stage if installation succeeds")
40-
subparser.add_argument(
41-
'--dont-restage', action='store_true',
42-
help="if a partial install is detected, don't delete prior state")
43-
subparser.add_argument(
44-
'--use-cache', action='store_true', dest='use_cache',
45-
help="check for pre-built Spack packages in mirrors")
46-
subparser.add_argument(
47-
'--show-log-on-error', action='store_true',
48-
help="print full build log to stderr if build fails")
49-
subparser.add_argument(
50-
'--source', action='store_true', dest='install_source',
51-
help="install source files in prefix")
52-
arguments.add_common_arguments(subparser, ['no_checksum'])
53-
subparser.add_argument(
54-
'-v', '--verbose', action='store_true',
55-
help="display verbose build output while installing")
56-
subparser.add_argument(
57-
'--fake', action='store_true',
58-
help="fake install for debug purposes.")
59-
60-
cd_group = subparser.add_mutually_exclusive_group()
61-
arguments.add_common_arguments(cd_group, ['clean', 'dirty'])
62-
63-
6429
def update_kwargs_from_args(args, kwargs):
6530
"""Parse cli arguments and construct a dictionary
6631
that will be passed to Package.do_install API"""
@@ -86,7 +51,6 @@ def update_kwargs_from_args(args, kwargs):
8651

8752

8853
def setup_parser(subparser):
89-
add_common_arguments(subparser)
9054
subparser.add_argument(
9155
'--only',
9256
default='package,dependencies',
@@ -97,11 +61,46 @@ def setup_parser(subparser):
9761
alternatively one can decide to install only the package or only
9862
the dependencies"""
9963
)
64+
arguments.add_common_arguments(subparser, ['jobs', 'install_status'])
65+
subparser.add_argument(
66+
'--overwrite', action='store_true',
67+
help="reinstall an existing spec, even if it has dependents")
68+
subparser.add_argument(
69+
'--keep-prefix', action='store_true',
70+
help="don't remove the install prefix if installation fails")
71+
subparser.add_argument(
72+
'--keep-stage', action='store_true',
73+
help="don't remove the build stage if installation succeeds")
74+
subparser.add_argument(
75+
'--dont-restage', action='store_true',
76+
help="if a partial install is detected, don't delete prior state")
77+
subparser.add_argument(
78+
'--use-cache', action='store_true', dest='use_cache',
79+
help="check for pre-built Spack packages in mirrors")
80+
subparser.add_argument(
81+
'--show-log-on-error', action='store_true',
82+
help="print full build log to stderr if build fails")
83+
subparser.add_argument(
84+
'--source', action='store_true', dest='install_source',
85+
help="install source files in prefix")
86+
arguments.add_common_arguments(subparser, ['no_checksum'])
87+
subparser.add_argument(
88+
'-v', '--verbose', action='store_true',
89+
help="display verbose build output while installing")
90+
subparser.add_argument(
91+
'--fake', action='store_true',
92+
help="fake install for debug purposes.")
93+
subparser.add_argument(
94+
'--only-concrete', action='store_true', default=False,
95+
help='(with environment) only install already concretized specs')
10096
subparser.add_argument(
10197
'-f', '--file', action='append', default=[],
10298
dest='specfiles', metavar='SPEC_YAML_FILE',
10399
help="install from file. Read specs to install from .yaml files")
104100

101+
cd_group = subparser.add_mutually_exclusive_group()
102+
arguments.add_common_arguments(cd_group, ['clean', 'dirty'])
103+
105104
subparser.add_argument(
106105
'package',
107106
nargs=argparse.REMAINDER,
@@ -155,7 +154,7 @@ def install_spec(cli_args, kwargs, spec):
155154

156155
# handle active environment, if any
157156
def install(spec, kwargs):
158-
env = spack.environment.active
157+
env = ev.get_env(cli_args, 'install', required=False)
159158
if env:
160159
env.install(spec, kwargs)
161160
env.write()
@@ -187,12 +186,15 @@ def install(spec, kwargs):
187186

188187
def install(parser, args, **kwargs):
189188
if not args.package and not args.specfiles:
190-
# if there is a spack.yaml file, then install the packages in it.
191-
if os.path.exists(ev.manifest_name):
192-
env = ev.Environment(os.getcwd())
193-
env.concretize()
194-
env.write()
195-
env.install_all()
189+
# if there are no args but an active environment or spack.yaml file
190+
# then install the packages from it.
191+
env = ev.get_env(args, 'install', required=False)
192+
if env:
193+
if not args.only_concrete:
194+
env.concretize()
195+
env.write()
196+
tty.msg("Installing environment %s" % env.name)
197+
env.install_all(args)
196198
return
197199
else:
198200
tty.die("install requires a package argument or a spack.yaml file")

lib/spack/spack/environment.py

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,53 @@ def deactivate():
132132
active = None
133133

134134

135+
def get_env(args, cmd_name, required=True):
136+
"""Get target environment from args, environment variables, or spack.yaml.
137+
138+
This is used by a number of commands for determining whether there is
139+
an active environment.
140+
141+
Check for an environment:
142+
1. via spack -e ENV
143+
2. as a spack.yaml file in the current directory, or
144+
3. via the SPACK_ENV environment variable.
145+
146+
If an environment is found, read it in. If not, print an error
147+
message referencing the calling command.
148+
149+
Arguments:
150+
args (Namespace): argparse namespace wtih command arguments
151+
cmd_name (str): name of calling command
152+
153+
"""
154+
# try arguments
155+
env = args.env
156+
157+
# try a manifest file in the current directory
158+
if not env:
159+
if os.path.exists(manifest_name):
160+
env = os.getcwd()
161+
162+
# try the active environment via SPACK_ENV environment variable
163+
if not env:
164+
if active:
165+
return active
166+
elif not required:
167+
return None
168+
tty.die(
169+
'`spack %s` requires an environment' % cmd_name,
170+
'activate an environment first:',
171+
' spack env activate ENV',
172+
'or use:',
173+
' spack -e ENV %s ...' % cmd_name)
174+
175+
environment = disambiguate(env)
176+
177+
if not environment:
178+
tty.die('no such environment: %s' % env)
179+
return environment
180+
181+
135182
def disambiguate(env, env_dir=None):
136183
"""Used to determine whether an environment is named or a directory."""
137184
if env:

lib/spack/spack/test/cmd/env.py

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212

1313
import spack.modules
1414
import spack.environment as ev
15-
from spack.cmd.env import _env_concretize, _env_create
15+
from spack.cmd.env import _env_create
1616
from spack.spec import Spec
1717
from spack.main import SpackCommand
1818

@@ -23,6 +23,7 @@
2323

2424

2525
env = SpackCommand('env')
26+
install = SpackCommand('install')
2627

2728

2829
def test_add():
@@ -117,7 +118,6 @@ def test_env_install_single_spec(install_mockery, mock_fetch):
117118

118119
def test_env_install_same_spec_twice(install_mockery, mock_fetch, capfd):
119120
env('create', 'test')
120-
install = SpackCommand('install')
121121

122122
e = ev.read('test')
123123
with capfd.disabled():
@@ -193,7 +193,9 @@ def test_to_lockfile_dict():
193193
def test_env_repo():
194194
e = ev.create('test')
195195
e.add('mpileaks')
196-
_env_concretize(e)
196+
e.write()
197+
198+
env('concretize', 'test')
197199

198200
package = e.repo.get('mpileaks')
199201
assert package.name == 'mpileaks'
@@ -486,8 +488,12 @@ def test_env_loads(install_mockery, mock_fetch):
486488

487489
with ev.read('test'):
488490
env('add', 'mpileaks')
491+
489492
env('concretize', 'test')
490-
env('install', '--fake', 'test')
493+
494+
with ev.read('test'):
495+
install('--fake')
496+
491497
env('loads', 'test')
492498

493499
e = ev.read('test')
@@ -535,8 +541,6 @@ def test_env_commands_die_with_no_env_arg():
535541
env('loads')
536542
with pytest.raises(spack.main.SpackCommandError):
537543
env('stage')
538-
with pytest.raises(spack.main.SpackCommandError):
539-
env('install')
540544
with pytest.raises(spack.main.SpackCommandError):
541545
env('uninstall')
542546
with pytest.raises(spack.main.SpackCommandError):

0 commit comments

Comments
 (0)