Compare commits

...

23 Commits

Author SHA1 Message Date
psakievich
2cae2d0f27
Update lib/spack/spack/test/cmd/build_env.py 2024-12-17 15:47:28 -07:00
psakievich
b68b5811b8
Update build_env.py
Co-authored-by: John W. Parent <45471568+johnwparent@users.noreply.github.com>
2024-12-16 20:27:52 -07:00
psakiev
3f88278d48 Update imports 2024-12-10 22:54:56 -07:00
psakiev
1d536ce143 Revert prompt changes for environment activation
I tried consolidating but I am not convinced it will work
correctly
2024-12-10 22:40:34 -07:00
psakiev
20d148e464 Style 2024-12-10 16:24:24 -07:00
Aaron Young
88b5a12e16
Add prompt support for fish. (#47609)
To avoid changing the fish_prompt function, create a SPACK_PROMPT
environment variable, which users can then manually incorporate into
their fish_prompt.fish function.
2024-11-14 16:14:44 -07:00
psakievich
f5fef81779 [@spackbot] updating style on behalf of psakievich 2024-11-14 04:53:17 +00:00
psakiev
8c6773f33e Add a cd test 2024-11-13 16:13:01 -07:00
psakiev
7a79fe88e2 Re-write test and update docs some more 2024-11-12 20:57:32 -07:00
psakiev
5cbbed42b4 Add docs 2024-11-12 18:12:21 -07:00
psakiev
d6b937d94b Style 2024-11-12 17:44:11 -07:00
psakiev
8eb4354b4b Add navigation to dive feature 2024-11-12 17:32:28 -07:00
psakiev
707a8daaea Compatibility 2024-11-12 16:20:39 -07:00
psakiev
ab5c2d5f7c Fixes 2024-11-12 16:09:16 -07:00
psakiev
4d49a658c8 Add completion 2024-11-12 15:28:34 -07:00
psakiev
973f59abbc Merge remote-tracking branch 'origin' into psakiev/dev-build 2024-11-12 13:18:16 -07:00
psakiev
4216a06cd8 Add build-env --dive 2024-11-12 13:16:59 -07:00
psakiev
2acf90f7b7 WIP unify 2024-11-11 17:06:04 -07:00
psakiev
8d5e71f66b Merge remote-tracking branch 'origin' into psakiev/dev-build 2024-11-11 16:46:55 -07:00
psakiev
9b3c200a07 Add prompt capability to dev_build drop-in 2024-11-11 16:44:48 -07:00
Philip Sakievich
43604f639e Update help 2024-11-08 10:01:17 -07:00
Philip Sakievich
33ae096a8b Fix some things from review 2024-11-08 06:32:55 -07:00
Philip Sakievich
259a1d9268 Make dev-build compatible with spack develop 2024-11-07 21:59:21 -07:00
14 changed files with 409 additions and 69 deletions

View File

@ -220,3 +220,4 @@ config:
concretise: concretize concretise: concretize
containerise: containerize containerise: containerize
rm: remove rm: remove
dev-dive: build-env --cd build-dir --dive

View File

@ -470,6 +470,48 @@ The supplied location will become the build-directory for that package in all fu
developers to only redirect the build directory if they understand their package's developers to only redirect the build directory if they understand their package's
build-system. build-system.
When doing active development it can often be nice to work inside the build environment
to run tests, and compile the code natively (i.e. run ``make`` or ``ninja``) without the
overhead of calling ``spack install``.
The spack command ``build-env`` allows users to run processes inside the build environment
or to dive directly into it. An additional convenience alias is ``spack dev-dive [spec]``.
This will navigate to the package's build directory and then launch a subshell with the
build environment active. Users can query if they are currently in a build environment
subshell by running ``spack build-env --status``. When users are finished exploring or
working in the subshell they can call ``exit`` to leave the build subshell.
.. code-block:: console
# create and setup a spack environment for development
# ====
$ spack env activate --temp
$ spack add zlib-ng
$ spack stage -p $SPACK_ENV zlib-ng
$ spack develop zlib-ng
# build and make changes
# =====
$ spack install -u autoreconf zlib-ng
# [ fails ]
$ spack dev-dive zlib-ng
# prompt changed, confirm the location is the build directory
zlib-ng-build-env $ pwd
/private/var/folders/ln/1_3kxbwd35s_ylsjlm3zmqmc00307v/T/spack-ne8_m488/zlib-ng
# confirm build-env in case we forget where we are in subshell hierarchy
zlib-ng-build-env $ spack build-env --status
==> In build env zlib-ng-wrsaadvkbg7rjj7kfjw5rhdrrfdswcmm
# [ fix code ]
zlib-ng-build-env $ make -j6
# [ builds now ]
zlib-ng-build-env $ exit
# exit subshell and rebuild environment
# ====
$ spack build-env --status
==> build environment not detected
$ spack install
^^^^^^^ ^^^^^^^
Loading Loading
^^^^^^^ ^^^^^^^

View File

@ -7081,7 +7081,34 @@ provide them after the spec argument to ``spack build-env``:
$ spack build-env mpileaks@1.1%intel ./configure $ spack build-env mpileaks@1.1%intel ./configure
This will cd to the build directory and then run ``configure`` in the This will cd to the build directory and then run ``configure`` in the
package's build environment. package's build environment. This could also be done in one command as follows.
.. code-block:: console
$ spack build-env --cd build-dir mpileaks@1.1%intel ./configure
Furthermore, ``spack build-env`` has the ability to dive into the build environment
in a subshell to allow you to work natively without polluting your current shell.
.. code-block:: console
$ spack build-env --cd build-dir --dive mpileaks@1.1%intel
mpileaks-build-env $ ./configure
Note that the command prompt changed for this case. This will happen automatically
if a Bourne or C-Shell to indicate that the user is in the build environment subshell.
While automatic prompt changes only occur for a selection of shells, any shell can
query if they are in the build environment with the ``spack build-env --status``
flag.
.. code-block:: console
$ spack build-env --dive mpileaks@1.1%intel
$ spack build-env --status
==> In build env mpileaks-wrsaadvkbg7rjj7kfjw5rhdrrfdswcmm
$ exit
$ spack build-env --status
==> build environment not detected
.. _cmd-spack-location: .. _cmd-spack-location:

View File

@ -857,6 +857,8 @@ def setup_package(pkg, dirty, context: Context = Context.BUILD):
load_external_modules(pkg) load_external_modules(pkg)
env_mods.set("SPACK_BUILD_ENV", f"{pkg.spec.name}-{pkg.spec.dag_hash()}")
# Make sure nothing's strange about the Spack environment. # Make sure nothing's strange about the Spack environment.
validate(env_mods, tty.warn) validate(env_mods, tty.warn)
env_mods.apply_modifications() env_mods.apply_modifications()

View File

@ -6,7 +6,7 @@
from spack.context import Context from spack.context import Context
description = ( description = (
"run a command in a spec's install environment, or dump its environment to screen or file" "use a spec's build environment to run a command, dump to screen or file, or dive into it"
) )
section = "build" section = "build"
level = "long" level = "long"

View File

@ -10,12 +10,15 @@
import spack.cmd import spack.cmd
import spack.deptypes as dt import spack.deptypes as dt
import spack.error import spack.error
import spack.prompt
import spack.spec import spack.spec
import spack.store import spack.store
from spack import build_environment, traverse from spack import build_environment, traverse
from spack.cmd.common import arguments from spack.cmd.common import arguments
from spack.cmd.location import location_emulator
from spack.context import Context from spack.context import Context
from spack.util.environment import dump_environment, pickle_environment from spack.util.environment import dump_environment, pickle_environment
from spack.util.shell_detection import active_shell_type
def setup_parser(subparser): def setup_parser(subparser):
@ -26,6 +29,17 @@ def setup_parser(subparser):
subparser.add_argument( subparser.add_argument(
"--pickle", metavar="FILE", help="dump a pickled source-able environment to FILE" "--pickle", metavar="FILE", help="dump a pickled source-able environment to FILE"
) )
subparser.add_argument(
"-d", "--dive", action="store_true", help="dive into the build-env in a subshell"
)
subparser.add_argument(
"-c",
"--cd",
help="location to dive to or run command from (takes arguments from 'spack cd')",
)
subparser.add_argument(
"--status", action="store_true", help="check shell for an active build environment"
)
subparser.add_argument( subparser.add_argument(
"spec", "spec",
nargs=argparse.REMAINDER, nargs=argparse.REMAINDER,
@ -75,7 +89,38 @@ def neighbors(self, item):
return item.edge.spec.edges_to_dependencies(depflag=depflag) return item.edge.spec.edges_to_dependencies(depflag=depflag)
def run_command_in_subshell(
spec, context, cmd, prompt=False, dirty=False, cd_arg=None, shell=active_shell_type()
):
mods = build_environment.setup_package(spec.package, dirty, context)
if prompt:
mods.extend(spack.prompt.prompt_modifications(f"{spec.name}-{str(context)}-env", shell))
mods.apply_modifications()
if cd_arg:
prefix = "-" if len(cd_arg) == 1 else "--"
loc_args = [f"{prefix}{cd_arg}"]
# don't add spec for cd if using env since spec hash is not the env
if not (cd_arg == "e" or cd_arg == "env"):
loc_args.append(f"/{spec.dag_hash()}")
location = location_emulator(*loc_args)
os.chdir(location)
os.execvp(cmd[0], cmd)
def emulate_env_utility(cmd_name, context: Context, args): def emulate_env_utility(cmd_name, context: Context, args):
if args.status:
context_var = os.environ.get(f"SPACK_{str(context).upper()}_ENV", None)
if context_var:
tty.msg(f"In {str(context)} env {context_var}")
else:
tty.msg(f"{str(context)} environment not detected")
exit(0)
if not args.spec: if not args.spec:
tty.die("spack %s requires a spec." % cmd_name) tty.die("spack %s requires a spec." % cmd_name)
@ -92,6 +137,12 @@ def emulate_env_utility(cmd_name, context: Context, args):
spec = args.spec[0] spec = args.spec[0]
cmd = args.spec[1:] cmd = args.spec[1:]
if args.dive:
if cmd:
tty.die("--dive and additional commands can't be run together")
else:
cmd = [active_shell_type()]
if not spec: if not spec:
tty.die("spack %s requires a spec." % cmd_name) tty.die("spack %s requires a spec." % cmd_name)
@ -106,6 +157,7 @@ def emulate_env_utility(cmd_name, context: Context, args):
visitor = AreDepsInstalledVisitor(context=context) visitor = AreDepsInstalledVisitor(context=context)
# Mass install check needs read transaction. # Mass install check needs read transaction.
# FIXME: this command is slow
with spack.store.STORE.db.read_transaction(): with spack.store.STORE.db.read_transaction():
traverse.traverse_breadth_first_with_visitor([spec], traverse.CoverNodesVisitor(visitor)) traverse.traverse_breadth_first_with_visitor([spec], traverse.CoverNodesVisitor(visitor))
@ -123,6 +175,10 @@ def emulate_env_utility(cmd_name, context: Context, args):
), ),
) )
if cmd:
run_command_in_subshell(spec, context, cmd, prompt=args.dive, cd_arg=args.cd)
else:
# setup build env if no command to run
build_environment.setup_package(spec.package, args.dirty, context) build_environment.setup_package(spec.package, args.dirty, context)
if args.dump: if args.dump:
@ -135,10 +191,6 @@ def emulate_env_utility(cmd_name, context: Context, args):
tty.msg("Pickling a source-able environment to {0}".format(args.pickle)) tty.msg("Pickling a source-able environment to {0}".format(args.pickle))
pickle_environment(args.pickle) pickle_environment(args.pickle)
if cmd:
# Execute the command with the new environment
os.execvp(cmd[0], cmd)
elif not bool(args.pickle or args.dump): elif not bool(args.pickle or args.dump):
# If no command or dump/pickle option then act like the "env" command # If no command or dump/pickle option then act like the "env" command
# and print out env vars. # and print out env vars.

View File

@ -8,15 +8,18 @@
import llnl.util.tty as tty import llnl.util.tty as tty
import spack.build_environment
import spack.cmd import spack.cmd
import spack.cmd.common.arguments import spack.cmd.common.arguments
import spack.config import spack.config
import spack.environment as ev
import spack.repo import spack.repo
import spack.version
from spack.cmd.common import arguments from spack.cmd.common import arguments
from spack.cmd.common.env_utility import run_command_in_subshell
from spack.context import Context
from spack.installer import PackageInstaller from spack.installer import PackageInstaller
description = "developer build: build from code in current working directory" description = "developer build: build from user managed code"
section = "build" section = "build"
level = "long" level = "long"
@ -28,7 +31,11 @@ def setup_parser(subparser):
"--source-path", "--source-path",
dest="source_path", dest="source_path",
default=None, default=None,
help="path to source directory (defaults to the current directory)", help=(
"path to source directory (defaults to the current directory)."
" ignored when using an active environment since the path is determined"
" by the develop section of the environment manifest."
),
) )
subparser.add_argument( subparser.add_argument(
"-i", "-i",
@ -53,12 +60,19 @@ def setup_parser(subparser):
help="do not display verbose build output while installing", help="do not display verbose build output while installing",
) )
subparser.add_argument( subparser.add_argument(
"-D",
"--drop-in", "--drop-in",
type=str, type=str,
dest="shell", dest="shell",
default=None, default=None,
help="drop into a build environment in a new shell, e.g., bash", help="drop into a build environment in a new shell, e.g., bash",
) )
subparser.add_argument(
"-p",
"--prompt",
action="store_true",
help="change the prompt when droping into the build-env",
)
subparser.add_argument( subparser.add_argument(
"--test", "--test",
default=None, default=None,
@ -102,11 +116,21 @@ def dev_build(self, args):
if not spack.repo.PATH.exists(spec.name): if not spack.repo.PATH.exists(spec.name):
raise spack.repo.UnknownPackageError(spec.name) raise spack.repo.UnknownPackageError(spec.name)
env = ev.active_environment()
if env:
matches = env.all_matching_specs(spec)
dev_matches = [m for m in matches if m.is_develop]
if len(dev_matches) > 1:
tty.die("Too many matching develop specs in the active environment")
elif len(dev_matches) < 1:
tty.die("No matching develop specs found in the active environment")
else:
spec = dev_matches[0]
else:
if not spec.versions.concrete_range_as_version: if not spec.versions.concrete_range_as_version:
tty.die( version = max(spec.package_class.versions.keys())
"spack dev-build spec must have a single, concrete version. " spec.versions = spack.version.VersionList([version])
"Did you forget a package version number?" tty.msg(f"Defaulting to highest version: {spec.name}@{version}")
)
source_path = args.source_path source_path = args.source_path
if source_path is None: if source_path is None:
@ -146,5 +170,6 @@ def dev_build(self, args):
# drop into the build environment of the package? # drop into the build environment of the package?
if args.shell is not None: if args.shell is not None:
spack.build_environment.setup_package(spec.package, dirty=False) run_command_in_subshell(
os.execvp(args.shell, [args.shell]) spec, Context.BUILD, [args.shell], prompt=args.prompt, shell=args.shell
)

View File

@ -3,6 +3,7 @@
# #
# SPDX-License-Identifier: (Apache-2.0 OR MIT) # SPDX-License-Identifier: (Apache-2.0 OR MIT)
import argparse
import os import os
import llnl.util.tty as tty import llnl.util.tty as tty
@ -15,7 +16,7 @@
import spack.stage import spack.stage
from spack.cmd.common import arguments from spack.cmd.common import arguments
description = "print out locations of packages and spack directories" description = "location = str out locations of packages and spack directories"
section = "basic" section = "basic"
level = "long" level = "long"
@ -86,15 +87,11 @@ def setup_parser(subparser):
arguments.add_common_arguments(subparser, ["spec"]) arguments.add_common_arguments(subparser, ["spec"])
def location(parser, args): def _location(parser, args):
if args.module_dir: if args.module_dir:
print(spack.paths.module_path) return spack.paths.module_path
return
if args.spack_root: if args.spack_root:
print(spack.paths.prefix) return spack.paths.prefix
return
# no -e corresponds to False, -e without arg to None, -e name to the string name. # no -e corresponds to False, -e without arg to None, -e name to the string name.
if args.location_env is not False: if args.location_env is not False:
if args.location_env is None: if args.location_env is None:
@ -106,16 +103,13 @@ def location(parser, args):
if not ev.exists(args.location_env): if not ev.exists(args.location_env):
tty.die("no such environment: '%s'" % args.location_env) tty.die("no such environment: '%s'" % args.location_env)
path = ev.root(args.location_env) path = ev.root(args.location_env)
print(path) return path
return
if args.packages: if args.packages:
print(spack.repo.PATH.first_repo().root) return spack.repo.PATH.first_repo().root
return
if args.stages: if args.stages:
print(spack.stage.get_stage_root()) return spack.stage.get_stage_root()
return
specs = spack.cmd.parse_specs(args.spec) specs = spack.cmd.parse_specs(args.spec)
@ -129,15 +123,13 @@ def location(parser, args):
if args.install_dir: if args.install_dir:
env = ev.active_environment() env = ev.active_environment()
spec = spack.cmd.disambiguate_spec(specs[0], env, first=args.find_first) spec = spack.cmd.disambiguate_spec(specs[0], env, first=args.find_first)
print(spec.prefix) return spec.prefix
return
spec = specs[0] spec = specs[0]
# Package dir just needs the spec name # Package dir just needs the spec name
if args.package_dir: if args.package_dir:
print(spack.repo.PATH.dirname_for_package_name(spec.name)) return spack.repo.PATH.dirname_for_package_name(spec.name)
return
# Either concretize or filter from already concretized environment # Either concretize or filter from already concretized environment
spec = spack.cmd.matching_spec_from_env(spec) spec = spack.cmd.matching_spec_from_env(spec)
@ -145,20 +137,17 @@ def location(parser, args):
builder = spack.builder.create(pkg) builder = spack.builder.create(pkg)
if args.stage_dir: if args.stage_dir:
print(pkg.stage.path) return pkg.stage.path
return
if args.build_dir: if args.build_dir:
# Out of source builds have build_directory defined # Out of source builds have build_directory defined
if hasattr(builder, "build_directory"): if hasattr(builder, "build_directory"):
# build_directory can be either absolute or relative to the stage path # build_directory can be either absolute or relative to the stage path
# in either case os.path.join makes it absolute # in either case os.path.join makes it absolute
print(os.path.normpath(os.path.join(pkg.stage.path, builder.build_directory))) return os.path.normpath(os.path.join(pkg.stage.path, builder.build_directory))
return
# Otherwise assume in-source builds # Otherwise assume in-source builds
print(pkg.stage.source_path) return pkg.stage.source_path
return
# source dir remains, which requires the spec to be staged # source dir remains, which requires the spec to be staged
if not pkg.stage.expanded: if not pkg.stage.expanded:
@ -168,4 +157,15 @@ def location(parser, args):
) )
# Default to source dir. # Default to source dir.
print(pkg.stage.source_path) return pkg.stage.source_path
# Is this too hacky? I don't want to reproduce the parser for an internal function
def location_emulator(*args):
parser = argparse.ArgumentParser()
setup_parser(parser)
return _location(parser, parser.parse_args(args))
def location(parser, args):
print(_location(parser, args))

74
lib/spack/spack/prompt.py Normal file
View File

@ -0,0 +1,74 @@
# Copyright 2013-2024 Lawrence Livermore National Security, LLC and other
# Spack Project Developers. See the top-level COPYRIGHT file for details.
#
# SPDX-License-Identifier: (Apache-2.0 OR MIT)
import os
import textwrap
from llnl.util.tty.color import colorize
from spack.util.environment import EnvironmentModifications
def prompt_modifications(prompt, shell, env=os.environ):
mods = EnvironmentModifications()
if shell == "fish" or shell == "pwsh" or shell == "bat":
# requires a function and can't be set with os.environ
pass
elif shell == "csh":
mods.set("SPACK_OLD_PROMPT", env.get("prompt", None))
mods.set("prompt", prompt)
else:
mods.set("SPACK_OLD_PS1", env.get("PS1", "$$$$"))
if "TERM" in env and "color" in env["TERM"]:
if "BASH" in env:
bash_color_prompt = colorize(f"@G{{{prompt}}}", color=True, enclose=True)
mods.set("PS1", f"{bash_color_prompt} {env.get('PS1','$ ')}")
else:
zsh_color_prompt = colorize(f"@G{{{prompt}}}", color=True, enclose=False, zsh=True)
mods.set("PS1", f"{zsh_color_prompt} {env.get('PS1', '$ ')}")
else:
mods.set("PS1", f"{prompt} {env.get('PS1', '$ ')}")
return mods
def custom_prompt(prompt, shell):
cmds = ""
if shell == "csh":
cmds += "if (! $?SPACK_OLD_PROMPT ) "
cmds += 'setenv SPACK_OLD_PROMPT "${prompt}";\n'
cmds += 'set prompt="%s ${prompt}";\n' % prompt
elif shell == "fish":
if "color" in os.getenv("TERM", ""):
prompt = colorize(f"@G{prompt}", color=True)
cmds += "set -gx SPACK_PROMPT '%s';\n" % prompt
elif shell == "bat" or shell == "pwsh":
# TODO
pass
else:
bash_color_prompt = colorize(f"@G{{{prompt}}}", color=True, enclose=True)
zsh_color_prompt = colorize(f"@G{{{prompt}}}", color=True, enclose=False, zsh=True)
cmds += textwrap.dedent(
rf"""
if [ -z ${{SPACK_OLD_PS1+x}} ]; then
if [ -z ${{PS1+x}} ]; then
PS1='$$$$';
fi;
export SPACK_OLD_PS1="${{PS1}}";
fi;
if [ -n "${{TERM:-}}" ] && [ "${{TERM#*color}}" != "${{TERM}}" ] && \
[ -n "${{BASH:-}}" ];
then
export PS1="{bash_color_prompt} ${{PS1}}";
elif [ -n "${{TERM:-}}" ] && [ "${{TERM#*color}}" != "${{TERM}}" ] && \
[ -n "${{ZSH_NAME:-}}" ];
then
export PS1="{zsh_color_prompt} ${{PS1}}";
else
export PS1="{prompt} ${{PS1}}";
fi
"""
).lstrip("\n")
return cmds

View File

@ -2,13 +2,18 @@
# Spack Project Developers. See the top-level COPYRIGHT file for details. # Spack Project Developers. See the top-level COPYRIGHT file for details.
# #
# SPDX-License-Identifier: (Apache-2.0 OR MIT) # SPDX-License-Identifier: (Apache-2.0 OR MIT)
import os
import pickle import pickle
import subprocess
import sys import sys
import pytest import pytest
import spack.error import spack.error
from spack.cmd.common.env_utility import run_command_in_subshell
from spack.context import Context
from spack.main import SpackCommand from spack.main import SpackCommand
from spack.spec import Spec
build_env = SpackCommand("build-env") build_env = SpackCommand("build-env")
@ -58,6 +63,31 @@ def test_pickle(tmpdir):
assert "PATH" in environment assert "PATH" in environment
# TODO params [i, b, c] require a spec that has proceeded with a directory
# TODO praram [e] requires an active env
@pytest.mark.parametrize("cd_key", ["r", "spack-root"])
@pytest.mark.usefixtures("config", "mock_packages", "working_env")
def test_cd(cd_key, tmpdir, monkeypatch, capfd):
"""test that a subshell will navigate using spack cd before running commands"""
cmd = "pwd" if sys.platform != "win32" else 'powershell.exe -Command "& {(Get-Location).Path}"'
def mock_execvp(_, args):
"""os.execvp will kill take over the pytest process when it is successful"""
result = subprocess.check_output(args, universal_newlines=True)
print(result)
with tmpdir.as_cwd():
monkeypatch.setattr(os, "execvp", mock_execvp)
pwd = os.getcwd()
spec = Spec("zlib").concretized()
run_command_in_subshell(spec, Context.BUILD, [cmd], cd_arg=cd_key)
output = capfd.readouterr()
assert pwd not in output.out
assert output.err == ""
def test_failure_when_uninstalled_deps(config, mock_packages): def test_failure_when_uninstalled_deps(config, mock_packages):
with pytest.raises( with pytest.raises(
spack.error.SpackError, match="Not all dependencies of dttop are installed" spack.error.SpackError, match="Not all dependencies of dttop are installed"

View File

@ -164,9 +164,9 @@ def test_dev_build_fails_nonexistent_package_name(mock_packages):
assert "Package 'no_such_package' not found" in output assert "Package 'no_such_package' not found" in output
def test_dev_build_fails_no_version(mock_packages): def test_dev_build_msg_no_version(mock_packages):
output = dev_build("dev-build-test-install", fail_on_error=False) output = dev_build("dev-build-test-install", fail_on_error=False)
assert "dev-build spec must have a single, concrete version" in output assert "Defaulting to highest version" in output
def test_dev_build_env(tmpdir, install_mockery, mutable_mock_env_path): def test_dev_build_env(tmpdir, install_mockery, mutable_mock_env_path):

View File

@ -0,0 +1,35 @@
# Copyright 2013-2024 Lawrence Livermore National Security, LLC and other
# Spack Project Developers. See the top-level COPYRIGHT file for details.
#
# SPDX-License-Identifier: (Apache-2.0 OR MIT)
import os
import platform
import subprocess
from spack.error import SpackError
def active_shell_type(env=os.environ):
if platform.system() == "Windows":
if "POWERSHELL" in env:
return "ps1"
else:
try:
output = subprocess.check_output(
'powershell -Command "echo $PSVersionTable"', universal_newlines=True
)
if "PSVersion" in output:
return "ps1"
else:
pass
except subprocess.CalledProcessError:
pass
raise SpackError("Unknown shell type being used on Windows")
else:
shell = env.get("SHELL", None)
if shell:
return shell
else:
# assume it is a bourne shell
return "sh"

View File

@ -393,7 +393,7 @@ _spack_compress_aliases() {
# Spack commands # Spack commands
# #
# Everything below here is auto-generated. # Everything below here is auto-generated.
SPACK_ALIASES="concretise:concretize;containerise:containerize;rm:remove" SPACK_ALIASES="concretise:concretize;containerise:containerize;rm:remove;dev-dive:build-env --cd build-dir --dive"
_spack() { _spack() {
@ -401,7 +401,7 @@ _spack() {
then then
SPACK_COMPREPLY="-h --help -H --all-help --color -c --config -C --config-scope -d --debug --timestamp --pdb -e --env -D --env-dir -E --no-env --use-env-repo -k --insecure -l --enable-locks -L --disable-locks -m --mock -b --bootstrap -p --profile --sorted-profile --lines -v --verbose --stacktrace -t --backtrace -V --version --print-shell-vars" SPACK_COMPREPLY="-h --help -H --all-help --color -c --config -C --config-scope -d --debug --timestamp --pdb -e --env -D --env-dir -E --no-env --use-env-repo -k --insecure -l --enable-locks -L --disable-locks -m --mock -b --bootstrap -p --profile --sorted-profile --lines -v --verbose --stacktrace -t --backtrace -V --version --print-shell-vars"
else else
SPACK_COMPREPLY="add arch audit blame bootstrap build-env buildcache cd change checksum ci clean clone commands compiler compilers concretize concretise config containerize containerise create debug deconcretize dependencies dependents deprecate dev-build develop diff docs edit env extensions external fetch find gc gpg graph help info install license list load location log-parse logs maintainers make-installer mark mirror module patch pkg providers pydoc python reindex remove rm repo resource restage solve spec stage style tags test test-env tutorial undevelop uninstall unit-test unload url verify versions view" SPACK_COMPREPLY="add arch audit blame bootstrap build-env dev-dive buildcache cd change checksum ci clean clone commands compiler compilers concretize concretise config containerize containerise create debug deconcretize dependencies dependents deprecate dev-build develop diff docs edit env extensions external fetch find gc gpg graph help info install license list load location log-parse logs maintainers make-installer mark mirror module patch pkg providers pydoc python reindex remove rm repo resource restage solve spec stage style tags test test-env tutorial undevelop uninstall unit-test unload url verify versions view"
fi fi
} }
@ -553,7 +553,16 @@ _spack_bootstrap_mirror() {
_spack_build_env() { _spack_build_env() {
if $list_options if $list_options
then then
SPACK_COMPREPLY="-h --help --clean --dirty -U --fresh --reuse --fresh-roots --reuse-deps --deprecated --dump --pickle" SPACK_COMPREPLY="-h --help --clean --dirty -U --fresh --reuse --fresh-roots --reuse-deps --deprecated --dump --pickle -d --dive -c --cd --status"
else
_all_packages
fi
}
_spack_dev_dive() {
if $list_options
then
SPACK_COMPREPLY="-h --help --clean --dirty -U --fresh --reuse --fresh-roots --reuse-deps --deprecated --dump --pickle -d --dive -c --cd --status"
else else
_all_packages _all_packages
fi fi
@ -981,7 +990,7 @@ _spack_deprecate() {
_spack_dev_build() { _spack_dev_build() {
if $list_options if $list_options
then then
SPACK_COMPREPLY="-h --help -j --jobs -n --no-checksum -d --source-path -i --ignore-dependencies --keep-prefix --skip-patch -q --quiet --drop-in --test -b --before -u --until --clean --dirty -U --fresh --reuse --fresh-roots --reuse-deps --deprecated" SPACK_COMPREPLY="-h --help -j --jobs -n --no-checksum -d --source-path -i --ignore-dependencies --keep-prefix --skip-patch -q --quiet -D --drop-in -p --prompt --test -b --before -u --until --clean --dirty -U --fresh --reuse --fresh-roots --reuse-deps --deprecated"
else else
_all_packages _all_packages
fi fi
@ -1957,7 +1966,7 @@ _spack_test_remove() {
_spack_test_env() { _spack_test_env() {
if $list_options if $list_options
then then
SPACK_COMPREPLY="-h --help --clean --dirty -U --fresh --reuse --fresh-roots --reuse-deps --deprecated --dump --pickle" SPACK_COMPREPLY="-h --help --clean --dirty -U --fresh --reuse --fresh-roots --reuse-deps --deprecated --dump --pickle -d --dive -c --cd --status"
else else
_all_packages _all_packages
fi fi

View File

@ -353,7 +353,8 @@ complete -c spack -n '__fish_spack_using_command_pos 0 ' -f -a arch -d 'print ar
complete -c spack -n '__fish_spack_using_command_pos 0 ' -f -a audit -d 'audit configuration files, packages, etc.' complete -c spack -n '__fish_spack_using_command_pos 0 ' -f -a audit -d 'audit configuration files, packages, etc.'
complete -c spack -n '__fish_spack_using_command_pos 0 ' -f -a blame -d 'show contributors to packages' complete -c spack -n '__fish_spack_using_command_pos 0 ' -f -a blame -d 'show contributors to packages'
complete -c spack -n '__fish_spack_using_command_pos 0 ' -f -a bootstrap -d 'manage bootstrap configuration' complete -c spack -n '__fish_spack_using_command_pos 0 ' -f -a bootstrap -d 'manage bootstrap configuration'
complete -c spack -n '__fish_spack_using_command_pos 0 ' -f -a build-env -d 'run a command in a spec'"'"'s install environment, or dump its environment to screen or file' complete -c spack -n '__fish_spack_using_command_pos 0 ' -f -a build-env -d 'use a spec'"'"'s build environment to run a command, dump to screen or file, or dive into it'
complete -c spack -n '__fish_spack_using_command_pos 0 ' -f -a dev-dive -d 'use a spec'"'"'s build environment to run a command, dump to screen or file, or dive into it'
complete -c spack -n '__fish_spack_using_command_pos 0 ' -f -a buildcache -d 'create, download and install binary packages' complete -c spack -n '__fish_spack_using_command_pos 0 ' -f -a buildcache -d 'create, download and install binary packages'
complete -c spack -n '__fish_spack_using_command_pos 0 ' -f -a cd -d 'cd to spack directories in the shell' complete -c spack -n '__fish_spack_using_command_pos 0 ' -f -a cd -d 'cd to spack directories in the shell'
complete -c spack -n '__fish_spack_using_command_pos 0 ' -f -a change -d 'change an existing spec in an environment' complete -c spack -n '__fish_spack_using_command_pos 0 ' -f -a change -d 'change an existing spec in an environment'
@ -375,7 +376,7 @@ complete -c spack -n '__fish_spack_using_command_pos 0 ' -f -a deconcretize -d '
complete -c spack -n '__fish_spack_using_command_pos 0 ' -f -a dependencies -d 'show dependencies of a package' complete -c spack -n '__fish_spack_using_command_pos 0 ' -f -a dependencies -d 'show dependencies of a package'
complete -c spack -n '__fish_spack_using_command_pos 0 ' -f -a dependents -d 'show packages that depend on another' complete -c spack -n '__fish_spack_using_command_pos 0 ' -f -a dependents -d 'show packages that depend on another'
complete -c spack -n '__fish_spack_using_command_pos 0 ' -f -a deprecate -d 'replace one package with another via symlinks' complete -c spack -n '__fish_spack_using_command_pos 0 ' -f -a deprecate -d 'replace one package with another via symlinks'
complete -c spack -n '__fish_spack_using_command_pos 0 ' -f -a dev-build -d 'developer build: build from code in current working directory' complete -c spack -n '__fish_spack_using_command_pos 0 ' -f -a dev-build -d 'developer build: build from user managed code'
complete -c spack -n '__fish_spack_using_command_pos 0 ' -f -a develop -d 'add a spec to an environment'"'"'s dev-build information' complete -c spack -n '__fish_spack_using_command_pos 0 ' -f -a develop -d 'add a spec to an environment'"'"'s dev-build information'
complete -c spack -n '__fish_spack_using_command_pos 0 ' -f -a diff -d 'compare two specs' complete -c spack -n '__fish_spack_using_command_pos 0 ' -f -a diff -d 'compare two specs'
complete -c spack -n '__fish_spack_using_command_pos 0 ' -f -a docs -d 'open spack documentation in a web browser' complete -c spack -n '__fish_spack_using_command_pos 0 ' -f -a docs -d 'open spack documentation in a web browser'
@ -394,7 +395,7 @@ complete -c spack -n '__fish_spack_using_command_pos 0 ' -f -a install -d 'build
complete -c spack -n '__fish_spack_using_command_pos 0 ' -f -a license -d 'list and check license headers on files in spack' complete -c spack -n '__fish_spack_using_command_pos 0 ' -f -a license -d 'list and check license headers on files in spack'
complete -c spack -n '__fish_spack_using_command_pos 0 ' -f -a list -d 'list and search available packages' complete -c spack -n '__fish_spack_using_command_pos 0 ' -f -a list -d 'list and search available packages'
complete -c spack -n '__fish_spack_using_command_pos 0 ' -f -a load -d 'add package to the user environment' complete -c spack -n '__fish_spack_using_command_pos 0 ' -f -a load -d 'add package to the user environment'
complete -c spack -n '__fish_spack_using_command_pos 0 ' -f -a location -d 'print out locations of packages and spack directories' complete -c spack -n '__fish_spack_using_command_pos 0 ' -f -a location -d 'location = str out locations of packages and spack directories'
complete -c spack -n '__fish_spack_using_command_pos 0 ' -f -a log-parse -d 'filter errors and warnings from build logs' complete -c spack -n '__fish_spack_using_command_pos 0 ' -f -a log-parse -d 'filter errors and warnings from build logs'
complete -c spack -n '__fish_spack_using_command_pos 0 ' -f -a logs -d 'print out logs for packages' complete -c spack -n '__fish_spack_using_command_pos 0 ' -f -a logs -d 'print out logs for packages'
complete -c spack -n '__fish_spack_using_command_pos 0 ' -f -a maintainers -d 'get information about package maintainers' complete -c spack -n '__fish_spack_using_command_pos 0 ' -f -a maintainers -d 'get information about package maintainers'
@ -664,7 +665,7 @@ complete -c spack -n '__fish_spack_using_command bootstrap mirror' -l dev -f -a
complete -c spack -n '__fish_spack_using_command bootstrap mirror' -l dev -d 'download dev dependencies too' complete -c spack -n '__fish_spack_using_command bootstrap mirror' -l dev -d 'download dev dependencies too'
# spack build-env # spack build-env
set -g __fish_spack_optspecs_spack_build_env h/help clean dirty U/fresh reuse fresh-roots deprecated dump= pickle= set -g __fish_spack_optspecs_spack_build_env h/help clean dirty U/fresh reuse fresh-roots deprecated dump= pickle= d/dive c/cd= status
complete -c spack -n '__fish_spack_using_command_pos_remainder 0 build-env' -f -a '(__fish_spack_build_env_spec)' complete -c spack -n '__fish_spack_using_command_pos_remainder 0 build-env' -f -a '(__fish_spack_build_env_spec)'
complete -c spack -n '__fish_spack_using_command build-env' -s h -l help -f -a help complete -c spack -n '__fish_spack_using_command build-env' -s h -l help -f -a help
complete -c spack -n '__fish_spack_using_command build-env' -s h -l help -d 'show this help message and exit' complete -c spack -n '__fish_spack_using_command build-env' -s h -l help -d 'show this help message and exit'
@ -684,6 +685,40 @@ complete -c spack -n '__fish_spack_using_command build-env' -l dump -r -f -a dum
complete -c spack -n '__fish_spack_using_command build-env' -l dump -r -d 'dump a source-able environment to FILE' complete -c spack -n '__fish_spack_using_command build-env' -l dump -r -d 'dump a source-able environment to FILE'
complete -c spack -n '__fish_spack_using_command build-env' -l pickle -r -f -a pickle complete -c spack -n '__fish_spack_using_command build-env' -l pickle -r -f -a pickle
complete -c spack -n '__fish_spack_using_command build-env' -l pickle -r -d 'dump a pickled source-able environment to FILE' complete -c spack -n '__fish_spack_using_command build-env' -l pickle -r -d 'dump a pickled source-able environment to FILE'
complete -c spack -n '__fish_spack_using_command build-env' -s d -l dive -f -a dive
complete -c spack -n '__fish_spack_using_command build-env' -s d -l dive -d 'dive into the build-env in a subshell'
complete -c spack -n '__fish_spack_using_command build-env' -s c -l cd -r -f -a cd
complete -c spack -n '__fish_spack_using_command build-env' -s c -l cd -r -d 'location to dive to or run command from (takes arguments from '"'"'spack cd'"'"')'
complete -c spack -n '__fish_spack_using_command build-env' -l status -f -a status
complete -c spack -n '__fish_spack_using_command build-env' -l status -d 'check shell for an active build environment'
# spack dev-dive
set -g __fish_spack_optspecs_spack_dev_dive h/help clean dirty U/fresh reuse fresh-roots deprecated dump= pickle= d/dive c/cd= status
complete -c spack -n '__fish_spack_using_command dev-dive' -s h -l help -f -a help
complete -c spack -n '__fish_spack_using_command dev-dive' -s h -l help -d 'show this help message and exit'
complete -c spack -n '__fish_spack_using_command dev-dive' -l clean -f -a dirty
complete -c spack -n '__fish_spack_using_command dev-dive' -l clean -d 'unset harmful variables in the build environment (default)'
complete -c spack -n '__fish_spack_using_command dev-dive' -l dirty -f -a dirty
complete -c spack -n '__fish_spack_using_command dev-dive' -l dirty -d 'preserve user environment in spack'"'"'s build environment (danger!)'
complete -c spack -n '__fish_spack_using_command dev-dive' -s U -l fresh -f -a concretizer_reuse
complete -c spack -n '__fish_spack_using_command dev-dive' -s U -l fresh -d 'do not reuse installed deps; build newest configuration'
complete -c spack -n '__fish_spack_using_command dev-dive' -l reuse -f -a concretizer_reuse
complete -c spack -n '__fish_spack_using_command dev-dive' -l reuse -d 'reuse installed packages/buildcaches when possible'
complete -c spack -n '__fish_spack_using_command dev-dive' -l fresh-roots -l reuse-deps -f -a concretizer_reuse
complete -c spack -n '__fish_spack_using_command dev-dive' -l fresh-roots -l reuse-deps -d 'concretize with fresh roots and reused dependencies'
complete -c spack -n '__fish_spack_using_command dev-dive' -l deprecated -f -a config_deprecated
complete -c spack -n '__fish_spack_using_command dev-dive' -l deprecated -d 'allow concretizer to select deprecated versions'
complete -c spack -n '__fish_spack_using_command dev-dive' -l dump -r -f -a dump
complete -c spack -n '__fish_spack_using_command dev-dive' -l dump -r -d 'dump a source-able environment to FILE'
complete -c spack -n '__fish_spack_using_command dev-dive' -l pickle -r -f -a pickle
complete -c spack -n '__fish_spack_using_command dev-dive' -l pickle -r -d 'dump a pickled source-able environment to FILE'
complete -c spack -n '__fish_spack_using_command dev-dive' -s d -l dive -f -a dive
complete -c spack -n '__fish_spack_using_command dev-dive' -s d -l dive -d 'dive into the build-env in a subshell'
complete -c spack -n '__fish_spack_using_command dev-dive' -s c -l cd -r -f -a cd
complete -c spack -n '__fish_spack_using_command dev-dive' -s c -l cd -r -d 'location to dive to or run command from (takes arguments from '"'"'spack cd'"'"')'
complete -c spack -n '__fish_spack_using_command dev-dive' -l status -f -a status
complete -c spack -n '__fish_spack_using_command dev-dive' -l status -d 'check shell for an active build environment'
# spack buildcache # spack buildcache
set -g __fish_spack_optspecs_spack_buildcache h/help set -g __fish_spack_optspecs_spack_buildcache h/help
@ -1376,7 +1411,7 @@ complete -c spack -n '__fish_spack_using_command deprecate' -s l -l link-type -r
complete -c spack -n '__fish_spack_using_command deprecate' -s l -l link-type -r -d '(deprecated)' complete -c spack -n '__fish_spack_using_command deprecate' -s l -l link-type -r -d '(deprecated)'
# spack dev-build # spack dev-build
set -g __fish_spack_optspecs_spack_dev_build h/help j/jobs= n/no-checksum d/source-path= i/ignore-dependencies keep-prefix skip-patch q/quiet drop-in= test= b/before= u/until= clean dirty U/fresh reuse fresh-roots deprecated set -g __fish_spack_optspecs_spack_dev_build h/help j/jobs= n/no-checksum d/source-path= i/ignore-dependencies keep-prefix skip-patch q/quiet D/drop-in= p/prompt test= b/before= u/until= clean dirty U/fresh reuse fresh-roots deprecated
complete -c spack -n '__fish_spack_using_command_pos_remainder 0 dev-build' -f -k -a '(__fish_spack_specs)' complete -c spack -n '__fish_spack_using_command_pos_remainder 0 dev-build' -f -k -a '(__fish_spack_specs)'
complete -c spack -n '__fish_spack_using_command dev-build' -s h -l help -f -a help complete -c spack -n '__fish_spack_using_command dev-build' -s h -l help -f -a help
complete -c spack -n '__fish_spack_using_command dev-build' -s h -l help -d 'show this help message and exit' complete -c spack -n '__fish_spack_using_command dev-build' -s h -l help -d 'show this help message and exit'
@ -1385,7 +1420,7 @@ complete -c spack -n '__fish_spack_using_command dev-build' -s j -l jobs -r -d '
complete -c spack -n '__fish_spack_using_command dev-build' -s n -l no-checksum -f -a no_checksum complete -c spack -n '__fish_spack_using_command dev-build' -s n -l no-checksum -f -a no_checksum
complete -c spack -n '__fish_spack_using_command dev-build' -s n -l no-checksum -d 'do not use checksums to verify downloaded files (unsafe)' complete -c spack -n '__fish_spack_using_command dev-build' -s n -l no-checksum -d 'do not use checksums to verify downloaded files (unsafe)'
complete -c spack -n '__fish_spack_using_command dev-build' -s d -l source-path -r -f -a source_path complete -c spack -n '__fish_spack_using_command dev-build' -s d -l source-path -r -f -a source_path
complete -c spack -n '__fish_spack_using_command dev-build' -s d -l source-path -r -d 'path to source directory (defaults to the current directory)' complete -c spack -n '__fish_spack_using_command dev-build' -s d -l source-path -r -d 'path to source directory (defaults to the current directory). ignored when using an active environment since the path is determined by the develop section of the environment manifest.'
complete -c spack -n '__fish_spack_using_command dev-build' -s i -l ignore-dependencies -f -a ignore_deps complete -c spack -n '__fish_spack_using_command dev-build' -s i -l ignore-dependencies -f -a ignore_deps
complete -c spack -n '__fish_spack_using_command dev-build' -s i -l ignore-dependencies -d 'do not try to install dependencies of requested packages' complete -c spack -n '__fish_spack_using_command dev-build' -s i -l ignore-dependencies -d 'do not try to install dependencies of requested packages'
complete -c spack -n '__fish_spack_using_command dev-build' -l keep-prefix -f -a keep_prefix complete -c spack -n '__fish_spack_using_command dev-build' -l keep-prefix -f -a keep_prefix
@ -1394,8 +1429,10 @@ complete -c spack -n '__fish_spack_using_command dev-build' -l skip-patch -f -a
complete -c spack -n '__fish_spack_using_command dev-build' -l skip-patch -d 'skip patching for the developer build' complete -c spack -n '__fish_spack_using_command dev-build' -l skip-patch -d 'skip patching for the developer build'
complete -c spack -n '__fish_spack_using_command dev-build' -s q -l quiet -f -a quiet complete -c spack -n '__fish_spack_using_command dev-build' -s q -l quiet -f -a quiet
complete -c spack -n '__fish_spack_using_command dev-build' -s q -l quiet -d 'do not display verbose build output while installing' complete -c spack -n '__fish_spack_using_command dev-build' -s q -l quiet -d 'do not display verbose build output while installing'
complete -c spack -n '__fish_spack_using_command dev-build' -l drop-in -r -f -a shell complete -c spack -n '__fish_spack_using_command dev-build' -s D -l drop-in -r -f -a shell
complete -c spack -n '__fish_spack_using_command dev-build' -l drop-in -r -d 'drop into a build environment in a new shell, e.g., bash' complete -c spack -n '__fish_spack_using_command dev-build' -s D -l drop-in -r -d 'drop into a build environment in a new shell, e.g., bash'
complete -c spack -n '__fish_spack_using_command dev-build' -s p -l prompt -f -a prompt
complete -c spack -n '__fish_spack_using_command dev-build' -s p -l prompt -d 'change the prompt when droping into the build-env'
complete -c spack -n '__fish_spack_using_command dev-build' -l test -r -f -a 'root all' complete -c spack -n '__fish_spack_using_command dev-build' -l test -r -f -a 'root all'
complete -c spack -n '__fish_spack_using_command dev-build' -l test -r -d 'run tests on only root packages or all packages' complete -c spack -n '__fish_spack_using_command dev-build' -l test -r -d 'run tests on only root packages or all packages'
complete -c spack -n '__fish_spack_using_command dev-build' -s b -l before -r -f -a before complete -c spack -n '__fish_spack_using_command dev-build' -s b -l before -r -f -a before
@ -3005,7 +3042,7 @@ complete -c spack -n '__fish_spack_using_command test remove' -s y -l yes-to-all
complete -c spack -n '__fish_spack_using_command test remove' -s y -l yes-to-all -d 'assume "yes" is the answer to every confirmation request' complete -c spack -n '__fish_spack_using_command test remove' -s y -l yes-to-all -d 'assume "yes" is the answer to every confirmation request'
# spack test-env # spack test-env
set -g __fish_spack_optspecs_spack_test_env h/help clean dirty U/fresh reuse fresh-roots deprecated dump= pickle= set -g __fish_spack_optspecs_spack_test_env h/help clean dirty U/fresh reuse fresh-roots deprecated dump= pickle= d/dive c/cd= status
complete -c spack -n '__fish_spack_using_command_pos_remainder 0 test-env' -f -a '(__fish_spack_build_env_spec)' complete -c spack -n '__fish_spack_using_command_pos_remainder 0 test-env' -f -a '(__fish_spack_build_env_spec)'
complete -c spack -n '__fish_spack_using_command test-env' -s h -l help -f -a help complete -c spack -n '__fish_spack_using_command test-env' -s h -l help -f -a help
complete -c spack -n '__fish_spack_using_command test-env' -s h -l help -d 'show this help message and exit' complete -c spack -n '__fish_spack_using_command test-env' -s h -l help -d 'show this help message and exit'
@ -3025,6 +3062,12 @@ complete -c spack -n '__fish_spack_using_command test-env' -l dump -r -f -a dump
complete -c spack -n '__fish_spack_using_command test-env' -l dump -r -d 'dump a source-able environment to FILE' complete -c spack -n '__fish_spack_using_command test-env' -l dump -r -d 'dump a source-able environment to FILE'
complete -c spack -n '__fish_spack_using_command test-env' -l pickle -r -f -a pickle complete -c spack -n '__fish_spack_using_command test-env' -l pickle -r -f -a pickle
complete -c spack -n '__fish_spack_using_command test-env' -l pickle -r -d 'dump a pickled source-able environment to FILE' complete -c spack -n '__fish_spack_using_command test-env' -l pickle -r -d 'dump a pickled source-able environment to FILE'
complete -c spack -n '__fish_spack_using_command test-env' -s d -l dive -f -a dive
complete -c spack -n '__fish_spack_using_command test-env' -s d -l dive -d 'dive into the build-env in a subshell'
complete -c spack -n '__fish_spack_using_command test-env' -s c -l cd -r -f -a cd
complete -c spack -n '__fish_spack_using_command test-env' -s c -l cd -r -d 'location to dive to or run command from (takes arguments from '"'"'spack cd'"'"')'
complete -c spack -n '__fish_spack_using_command test-env' -l status -f -a status
complete -c spack -n '__fish_spack_using_command test-env' -l status -d 'check shell for an active build environment'
# spack tutorial # spack tutorial
set -g __fish_spack_optspecs_spack_tutorial h/help y/yes-to-all set -g __fish_spack_optspecs_spack_tutorial h/help y/yes-to-all