Skip to content

Commit

Permalink
Add '--hook' option (#2)
Browse files Browse the repository at this point in the history
  • Loading branch information
jaimergp authored Jan 15, 2025
1 parent 66a5145 commit d8d54c3
Show file tree
Hide file tree
Showing 12 changed files with 256 additions and 117 deletions.
1 change: 0 additions & 1 deletion .devcontainer/post_create.sh
Original file line number Diff line number Diff line change
Expand Up @@ -28,4 +28,3 @@ if [ ! -f "$SRC_CONDA_SPAWN/pyproject.toml" ]; then
echo "https://github.com/conda-incubator/conda-spawn not found! Please clone or mount to $SRC_CONDA_SPAWN"
exit 1
fi

3 changes: 1 addition & 2 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ jobs:
pixi run --environment ${{ env.PIXI_ENV_NAME }} conda info
- name: Run tests
run: pixi run --environment ${{ env.PIXI_ENV_NAME }} test --basetemp=${{ runner.os == 'Windows' && 'D:\\temp' || runner.temp }}

build-conda:
name: Build conda package (${{ matrix.os }})
runs-on: ${{ matrix.os }}
Expand All @@ -73,4 +73,3 @@ jobs:
pixi run --environment build dev
- name: Build recipe
run: pixi run --environment build build

6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -52,13 +52,13 @@ For in-script usage, please consider these replacements for `conda activate`:
For Unix shell scripts:

```bash
eval "$(conda shell.posix activate <ENV-NAME>)"
eval "$(conda spawn --hook --shell posix -n <ENV-NAME>)"
```

For Windows CMD scripts:

```cmd
FOR /F "tokens=*" %%g IN ('conda shell.cmd.exe activate <ENV-NAME>') do @CALL %%g
FOR /F "tokens=*" %%g IN ('conda spawn --hook --shell cmd -n <ENV-NAME>') do @CALL %%g
```

For Windows Powershell scripts:
Expand All @@ -72,7 +72,7 @@ For example, if you want to create a new environment and activate it, it would l
```bash
# Assumes `conda` is in PATH
conda create -n new-env python numpy
eval "$(conda shell.posix activate new-env)"
eval "$(conda spawn --hook --shell powershell -n new-env)"
python -c "import numpy"
```

Expand Down
3 changes: 2 additions & 1 deletion conda_spawn/__init__.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
"""
conda go: activate conda environments in new shell processes.
"""
from .main import spawn

from .main import spawn, hook # noqa
45 changes: 40 additions & 5 deletions conda_spawn/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,34 +5,69 @@
from __future__ import annotations

import argparse
from textwrap import dedent

from conda.exceptions import ArgumentError
from conda.cli.conda_argparse import (
add_parser_help,
add_parser_prefix,
)


def configure_parser(parser: argparse.ArgumentParser):
from .shell import SHELLS

add_parser_help(parser)
add_parser_prefix(parser, prefix_required=True)

parser.add_argument(
"command",
metavar="COMMAND [args]",
nargs="*",
help="Optional program and arguments to run after starting the shell.",
help="Optional program to run after starting the shell. "
"Use -- before the program if providing arguments.",
)
shell_group = parser.add_argument_group("Shell options")
shell_group.add_argument(
"-s",
"--hook",
action="store_true",
help=(
"Print the shell activation logic so it can be sourced in-process. "
"This is meant to be used in scripts only."
),
)
shell_group.add_argument(
"--shell",
help="Shell to use for the new session. "
"If not specified, autodetect shell in use.",
choices=SHELLS,
help="Shell to use for the new session. If not specified, autodetect shell in use.",
)

parser.prog = "conda spawn"
parser.epilog = dedent(
"""
Examples for --hook usage in different shells:
POSIX:
source "$(conda spawn --hook -n ENV-NAME)"
CMD:
FOR /F "tokens=*" %%g IN ('conda spawn --hook -n ENV-NAME') do @CALL %%g
Powershell:
conda spawn --hook -n ENV-NAME | Out-String | Invoke-Expression
"""
).lstrip()


def execute(args: argparse.Namespace) -> int:
from .main import spawn, environment_speficier_to_path, shell_specifier_to_shell
from .main import (
hook,
spawn,
environment_speficier_to_path,
shell_specifier_to_shell,
)

prefix = environment_speficier_to_path(args.name, args.prefix)
shell = shell_specifier_to_shell(args.shell)
if args.hook:
if args.command:
raise ArgumentError("COMMAND cannot be provided with --hook.")
return hook(prefix, shell)
return spawn(prefix, shell, command=args.command)
4 changes: 1 addition & 3 deletions conda_spawn/exceptions.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
"""
"""
""" """

from conda.base.constants import COMPATIBLE_SHELLS
from conda.common.io import dashlist
Expand All @@ -14,4 +13,3 @@ def __init__(self, name: str):
f"{dashlist(COMPATIBLE_SHELLS)}"
)
super().__init__(message)

12 changes: 11 additions & 1 deletion conda_spawn/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,17 @@ def spawn(
) -> int:
if shell_cls is None:
shell_cls = detect_shell_class()
return shell_cls().spawn(prefix, command=command)
return shell_cls(prefix).spawn(command=command)


def hook(prefix: Path, shell_cls: Shell | None = None) -> int:
if shell_cls is None:
shell_cls = detect_shell_class()
script = shell_cls(prefix).script()
prompt = shell_cls(prefix).prompt()
print(script)
print(prompt)
return 0


def environment_speficier_to_path(
Expand Down
2 changes: 1 addition & 1 deletion conda_spawn/plugin.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
def conda_subcommands():
yield plugins.CondaSubcommand(
name="spawn",
summary="activate conda environments in new shell processes",
summary="Activate conda environments in new shell processes.",
action=cli.execute,
configure_parser=cli.configure_parser,
)
Loading

0 comments on commit d8d54c3

Please sign in to comment.