Add navigation to dive feature

This commit is contained in:
psakiev
2024-11-12 17:32:28 -07:00
parent 707a8daaea
commit 8eb4354b4b
7 changed files with 112 additions and 96 deletions

View File

@@ -6,7 +6,7 @@
from spack.context import Context
description = (
"run a command in a spec's build 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"
level = "long"
@@ -14,7 +14,5 @@
setup_parser = env_utility.setup_parser
# TODO create a dropin/dive funciton that dev_build and build_env cmd's can use
# create a default shell utility for picking the current shell to start with
def build_env(parser, args):
env_utility.emulate_env_utility("build-env", Context.BUILD, args)

View File

@@ -15,6 +15,7 @@
import spack.store
from spack import build_environment, traverse
from spack.cmd.common import arguments
from spack.cmd.location import location_emulator
from spack.context import Context
from spack.util.environment import dump_environment, pickle_environment
from spack.util.shell_detection import active_shell_type
@@ -31,6 +32,11 @@ def setup_parser(subparser):
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"
)
@@ -84,12 +90,19 @@ def neighbors(self, item):
def run_command_in_subshell(
spec, context, cmd, prompt=False, dirty=False, shell=active_shell_type()
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 "--"
location = location_emulator(f"{prefix}{cd_arg}", f"/{spec.dag_hash()}")
os.chdir(location)
os.execvp(cmd[0], cmd)
@@ -157,7 +170,7 @@ def emulate_env_utility(cmd_name, context: Context, args):
)
if cmd:
run_command_in_subshell(spec, context, cmd, prompt=args.dive)
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)

View File

@@ -3,6 +3,7 @@
#
# SPDX-License-Identifier: (Apache-2.0 OR MIT)
import argparse
import os
import llnl.util.tty as tty
@@ -15,7 +16,7 @@
import spack.stage
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"
level = "long"
@@ -86,15 +87,11 @@ def setup_parser(subparser):
arguments.add_common_arguments(subparser, ["spec"])
def location(parser, args):
def _location(parser, args):
if args.module_dir:
print(spack.paths.module_path)
return
return spack.paths.module_path
if args.spack_root:
print(spack.paths.prefix)
return
return spack.paths.prefix
# 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 None:
@@ -106,16 +103,13 @@ def location(parser, args):
if not ev.exists(args.location_env):
tty.die("no such environment: '%s'" % args.location_env)
path = ev.root(args.location_env)
print(path)
return
return path
if args.packages:
print(spack.repo.PATH.first_repo().root)
return
return spack.repo.PATH.first_repo().root
if args.stages:
print(spack.stage.get_stage_root())
return
return spack.stage.get_stage_root()
specs = spack.cmd.parse_specs(args.spec)
@@ -129,15 +123,13 @@ def location(parser, args):
if args.install_dir:
env = ev.active_environment()
spec = spack.cmd.disambiguate_spec(specs[0], env, first=args.find_first)
print(spec.prefix)
return
return spec.prefix
spec = specs[0]
# Package dir just needs the spec name
if args.package_dir:
print(spack.repo.PATH.dirname_for_package_name(spec.name))
return
return spack.repo.PATH.dirname_for_package_name(spec.name)
# Either concretize or filter from already concretized environment
spec = spack.cmd.matching_spec_from_env(spec)
@@ -145,20 +137,17 @@ def location(parser, args):
builder = spack.builder.create(pkg)
if args.stage_dir:
print(pkg.stage.path)
return
return pkg.stage.path
if args.build_dir:
# Out of source builds have build_directory defined
if hasattr(builder, "build_directory"):
# build_directory can be either absolute or relative to the stage path
# in either case os.path.join makes it absolute
print(os.path.normpath(os.path.join(pkg.stage.path, builder.build_directory)))
return
return os.path.normpath(os.path.join(pkg.stage.path, builder.build_directory))
# Otherwise assume in-source builds
print(pkg.stage.source_path)
return
return pkg.stage.source_path
# source dir remains, which requires the spec to be staged
if not pkg.stage.expanded:
@@ -168,4 +157,15 @@ def location(parser, args):
)
# 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))

View File

@@ -16,10 +16,8 @@ def active_shell_type(env=os.environ):
return "ps1"
else:
try:
output = subprocess.run(
output = subprocess.check_output(
'powershell -Command "echo $PSVersionTable"',
shell=True,
check=True,
universal_newlines=True,
)
if "PSVersion" in output:
@@ -34,4 +32,5 @@ def active_shell_type(env=os.environ):
if shell:
return shell
else:
raise SpackError("No shell type detected for the Unix process")
# assume it is a bourne shell
return "sh"