Skip to content

Commit

Permalink
feat(cli): add --no-activation option to prevent env activation durin…
Browse files Browse the repository at this point in the history
…g global install/upgrade (#1980)

Introduce the `--no-activation` flag in `install.rs`, `upgrade.rs`, and
`upgrade_all.rs` to allow users to globally install executable scripts
without activating the underlying conda environment. Fixes #1382

docs: update usage instructions with `--no-activation` flag in global
cli documentation

test: add integration tests for `--no-activation` option in global
install/upgrade paths

---------

Co-authored-by: Hofer-Julian <[email protected]>
  • Loading branch information
183amir and Hofer-Julian authored Sep 23, 2024
1 parent 3e58dc3 commit e545af3
Show file tree
Hide file tree
Showing 5 changed files with 53 additions and 2 deletions.
13 changes: 13 additions & 0 deletions docs/basic_usage.md
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,19 @@ pixi global install rattler-build
pixi global install ruff
```

### Using the --no-activation option

When installing packages globally, you can use the `--no-activation` option to prevent the insertion of environment activation code into the installed executable scripts. This means that when you run the installed executable, it won't modify the `PATH` or `CONDA_PREFIX` environment variables beforehand.

Example:

```shell
# Install a package without inserting activation code
pixi global install ruff --no-activation
```

This option can be useful in scenarios where you want more control over the environment activation or if you're using the installed executables in contexts where automatic activation might interfere with other processes.

## Use pixi in GitHub Actions

You can use pixi in GitHub Actions to install dependencies and run commands.
Expand Down
4 changes: 4 additions & 0 deletions docs/reference/cli.md
Original file line number Diff line number Diff line change
Expand Up @@ -934,6 +934,7 @@ This command installs package(s) into its own environment and adds the binary to

- `--channel <CHANNEL> (-c)`: specify a channel that the project uses. Defaults to `conda-forge`. (Allowed to be used more than once)
- `--platform <PLATFORM> (-p)`: specify a platform that you want to install the package for. (default: current platform)
- `--no-activation`: Do not insert conda_prefix, path modifications, and activation script into the installed executable script.

```shell
pixi global install ruff
Expand All @@ -952,6 +953,9 @@ pixi global install python=3.11.0=h10a6764_1_cpython

# Install for a specific platform, only useful on osx-arm64
pixi global install --platform osx-64 ruff

# Install without inserting activation code into the executable script
pixi global install ruff --no-activation
```

!!! tip
Expand Down
27 changes: 25 additions & 2 deletions src/cli/global/install.rs
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,10 @@ pub struct Args {

#[clap(flatten)]
config: ConfigCli,

/// Do not insert `CONDA_PREFIX`, `PATH` modifications into the installed executable script.
#[clap(long)]
no_activation: bool,
}

impl HasSpecs for Args {
Expand Down Expand Up @@ -212,13 +216,23 @@ pub(super) async fn create_executable_scripts(
prefix: &Prefix,
shell: &ShellEnum,
activation_script: String,
no_activation: bool,
) -> miette::Result<()> {
for BinScriptMapping {
original_executable: exec,
global_binary_path: executable_script_path,
} in mapped_executables
{
let mut script = activation_script.clone();
let mut script = if no_activation {
if cfg!(unix) {
"#!/bin/sh\n".to_string()
} else {
String::new()
}
} else {
activation_script.clone()
};

shell
.run_command(
&mut script,
Expand Down Expand Up @@ -342,6 +356,7 @@ pub async fn execute(args: Args) -> miette::Result<()> {
solved_records.clone(),
auth_client.clone(),
args.platform,
args.no_activation,
)
.await?;
let channel_name =
Expand Down Expand Up @@ -410,6 +425,7 @@ pub(super) async fn globally_install_package(
records: Vec<RepoDataRecord>,
authenticated_client: ClientWithMiddleware,
platform: Platform,
no_activation: bool,
) -> miette::Result<(PrefixRecord, Vec<PathBuf>, bool)> {
try_increase_rlimit_to_sensible();

Expand Down Expand Up @@ -460,7 +476,14 @@ pub(super) async fn globally_install_package(
let bin_dir = BinDir::create().await?;
let script_mapping =
find_and_map_executable_scripts(&prefix, &prefix_package, &bin_dir).await?;
create_executable_scripts(&script_mapping, &prefix, &shell, activation_script).await?;
create_executable_scripts(
&script_mapping,
&prefix,
&shell,
activation_script,
no_activation,
)
.await?;

let scripts: Vec<_> = script_mapping
.into_iter()
Expand Down
1 change: 1 addition & 0 deletions src/cli/global/upgrade.rs
Original file line number Diff line number Diff line change
Expand Up @@ -200,6 +200,7 @@ pub(super) async fn upgrade_packages(
records,
authenticated_client.clone(),
platform,
false,
)
.await?;
pb.finish_with_message(format!("{} {}", console::style("Updated").green(), message));
Expand Down
10 changes: 10 additions & 0 deletions tests/integration/test_main_cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -185,9 +185,19 @@ def test_global_install(pixi: Path) -> None:
stdout_excludes="rattler-build",
)

# Install with --no-activation
verify_cli_command(
[pixi, "global", "install", "rattler-build", "--no-activation"],
ExitCode.SUCCESS,
stdout_excludes="rattler-build",
)

# Upgrade
verify_cli_command([pixi, "global", "upgrade", "rattler-build"], ExitCode.SUCCESS)

# Upgrade all
verify_cli_command([pixi, "global", "upgrade-all"], ExitCode.SUCCESS)

# List
verify_cli_command([pixi, "global", "list"], ExitCode.SUCCESS, stderr_contains="rattler-build")

Expand Down

0 comments on commit e545af3

Please sign in to comment.