Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: use autoguessing of the shell in the shell hook #811

Merged
merged 3 commits into from
Feb 15, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions docs/cli.md
Original file line number Diff line number Diff line change
Expand Up @@ -376,8 +376,8 @@ exit
This command prints the activation script of an environment.

##### Options
- `--shell`: The shell for which the activation script should be printed. Defaults to the current shell.
Currently supported variants: [`Bash`, `Zsh`, `Xonsh`, `CmdExe`, `PowerShell`, `Fish`, `NuShell`]
- `--shell <SHELL> (-s)`: The shell for which the activation script should be printed. Defaults to the current shell.
Currently supported variants: [`bash`, `zsh`, `xonsh`, `cmd`, `powershell`, `fish`, `nushell`]
- `--manifest-path`: the path to `pixi.toml`, by default it searches for one in the parent directories.
- `--frozen`: install the environment as defined in the lockfile. Without checking the status of the lockfile. It can also be controlled by the `PIXI_FROZEN` environment variable (example: `PIXI_FROZEN=true`).
- `--locked`: only install if the `pixi.lock` is up-to-date with the `pixi.toml`[^1]. It can also be controlled by the `PIXI_LOCKED` environment variable (example: `PIXI_LOCKED=true`). Conflicts with `--frozen`.
Expand All @@ -387,6 +387,7 @@ This command prints the activation script of an environment.
pixi shell-hook
pixi shell-hook --shell bash
pixi shell-hook --shell zsh
pixi shell-hook -s powershell
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

wdyt about using long option here also?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it's fine to show that different flags work :)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah normally I would use the full version but the repetition made me change it.

pixi shell-hook --manifest-path ~/myproject/pixi.toml
pixi shell-hook --frozen
pixi shell-hook --locked
Expand Down
60 changes: 50 additions & 10 deletions src/cli/shell_hook.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ use crate::{
/// Print the activation script so users can source it in their shell, without needing the pixi executable.
#[derive(Parser, Debug)]
pub struct Args {
/// Sets the shell
/// Sets the shell, options: [`bash`, `zsh`, `xonsh`, `cmd`, `powershell`, `fish`, `nushell`]
#[arg(short, long)]
shell: Option<ShellEnum>,

Expand All @@ -39,7 +39,12 @@ async fn generate_activation_script(
shell: Option<ShellEnum>,
environment: &Environment<'_>,
) -> miette::Result<String> {
let shell = shell.unwrap_or_default();
// Get shell from the arguments or from the current process or use default if all fails
let shell = shell.unwrap_or_else(|| {
ShellEnum::from_parent_process()
.unwrap_or_else(|| ShellEnum::from_env().unwrap_or_default())
});

let activator = get_activator(environment, shell).into_diagnostic()?;

let path = std::env::var("PATH")
Expand Down Expand Up @@ -88,20 +93,55 @@ pub async fn execute(args: Args) -> miette::Result<()> {
#[cfg(test)]
mod tests {
use super::*;
use rattler_shell::shell::{Bash, CmdExe, Fish, NuShell, PowerShell, Xonsh, Zsh};

#[tokio::test]
async fn test_shell_hook() {
let project = Project::discover().unwrap();
let environment = project.default_environment();
let script = generate_activation_script(None, &environment)
let script = generate_activation_script(Some(ShellEnum::Bash(Bash)), &environment)
.await
.unwrap();
assert!(script.contains("export PATH="));
assert!(script.contains("export CONDA_PREFIX="));

let script = generate_activation_script(
Some(ShellEnum::PowerShell(PowerShell::default())),
&environment,
)
.await
.unwrap();
assert!(script.contains("${Env:PATH}"));
assert!(script.contains("${Env:CONDA_PREFIX}"));

let script = generate_activation_script(Some(ShellEnum::Zsh(Zsh)), &environment)
.await
.unwrap();
assert!(script.contains("export PATH="));
assert!(script.contains("export CONDA_PREFIX="));

let script = generate_activation_script(Some(ShellEnum::Fish(Fish)), &environment)
.await
.unwrap();
assert!(script.contains("set -gx PATH "));
assert!(script.contains("set -gx CONDA_PREFIX "));

let script = generate_activation_script(Some(ShellEnum::Xonsh(Xonsh)), &environment)
.await
.unwrap();
assert!(script.contains("$PATH = "));
assert!(script.contains("$CONDA_PREFIX = "));

let script = generate_activation_script(Some(ShellEnum::CmdExe(CmdExe)), &environment)
.await
.unwrap();
assert!(script.contains("@SET \"PATH="));
assert!(script.contains("@SET \"CONDA_PREFIX="));

let script = generate_activation_script(Some(ShellEnum::NuShell(NuShell)), &environment)
.await
.unwrap();
if cfg!(unix) {
assert!(script.contains("export PATH="));
assert!(script.contains("export CONDA_PREFIX="));
} else {
assert!(script.contains("@SET \"PATH="));
assert!(script.contains("@SET \"CONDA_PREFIX="));
}
assert!(script.contains("$env.PATH = "));
assert!(script.contains("$env.CONDA_PREFIX = "));
}
}
Loading