Skip to content
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
2 changes: 2 additions & 0 deletions docs/reference/cli/pixi/run.md
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,8 @@ pixi run [OPTIONS] [TASK]...
- <a id="arg---locked" href="#arg---locked">`--locked`</a>
: Check if lockfile is up-to-date before installing the environment, aborts when lockfile isn't up-to-date with the manifest file
<br>**env**: `PIXI_LOCKED`
- <a id="arg---as-is" href="#arg---as-is">`--as-is`</a>
: Shorthand for the combination of --no-install and --frozen

## Global Options
- <a id="arg---manifest-path" href="#arg---manifest-path">`--manifest-path <MANIFEST_PATH>`</a>
Expand Down
2 changes: 2 additions & 0 deletions docs/reference/cli/pixi/shell-hook.md
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,8 @@ pixi shell-hook [OPTIONS]
- <a id="arg---locked" href="#arg---locked">`--locked`</a>
: Check if lockfile is up-to-date before installing the environment, aborts when lockfile isn't up-to-date with the manifest file
<br>**env**: `PIXI_LOCKED`
- <a id="arg---as-is" href="#arg---as-is">`--as-is`</a>
: Shorthand for the combination of --no-install and --frozen

## Global Options
- <a id="arg---manifest-path" href="#arg---manifest-path">`--manifest-path <MANIFEST_PATH>`</a>
Expand Down
2 changes: 2 additions & 0 deletions docs/reference/cli/pixi/shell.md
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,8 @@ pixi shell [OPTIONS]
- <a id="arg---locked" href="#arg---locked">`--locked`</a>
: Check if lockfile is up-to-date before installing the environment, aborts when lockfile isn't up-to-date with the manifest file
<br>**env**: `PIXI_LOCKED`
- <a id="arg---as-is" href="#arg---as-is">`--as-is`</a>
: Shorthand for the combination of --no-install and --frozen

## Global Options
- <a id="arg---manifest-path" href="#arg---manifest-path">`--manifest-path <MANIFEST_PATH>`</a>
Expand Down
91 changes: 90 additions & 1 deletion src/cli/cli_config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,44 @@ impl NoInstallConfig {
}
}

/// Lock file and installation configuration with --as-is support
/// Used by shell, shell-hook, and run commands
#[derive(Parser, Debug, Default, Clone)]
pub struct LockAndInstallConfig {
#[clap(flatten)]
pub no_install_config: NoInstallConfig,

#[clap(flatten)]
pub lock_file_update_config: LockFileUpdateConfig,

/// Shorthand for the combination of --no-install and --frozen.
#[arg(long, help_heading = consts::CLAP_UPDATE_OPTIONS, conflicts_with_all = ["locked"])]
pub as_is: bool,
}

impl LockAndInstallConfig {
/// Returns true if the --as-is flag is set or if the no_install flag is set
pub fn no_install(&self) -> bool {
self.as_is || self.no_install_config.no_install
}

/// Get the effective lock file usage based on the configuration
pub fn lock_file_usage(&self) -> miette::Result<pixi_core::environment::LockFileUsage> {
// If --as-is is set this is equivalent to --frozen and --no-install
if self.as_is {
return Ok(LockFileUsage::Frozen);
}

// Otherwise use the normal lock file update config
self.lock_file_update_config.lock_file_usage()
}

/// Check if installs are allowed (considering --as-is)
pub fn allow_installs(&self) -> bool {
!self.as_is && self.no_install_config.allow_installs()
}
}

#[derive(Parser, Debug, Default, Clone)]
pub struct GitRev {
/// The git branch
Expand Down Expand Up @@ -410,7 +448,10 @@ fn build_vcs_requirement(
mod tests {
use url::Url;

use crate::cli::cli_config::{GitRev, build_vcs_requirement};
use crate::cli::cli_config::{
GitRev, LockAndInstallConfig, LockFileUpdateConfig, NoInstallConfig, build_vcs_requirement,
};
use pixi_core::environment::LockFileUsage;

#[test]
fn test_build_vcs_requirement_with_all_fields() {
Expand Down Expand Up @@ -475,4 +516,52 @@ mod tests {
);
assert_eq!(result, "mypackage @ git+file:///home/user/GitHub/mypackage");
}

#[test]
fn test_lock_and_install_config_as_is_flag() {
// Test --as-is sets both frozen and no_install
let config = LockAndInstallConfig {
as_is: true,
no_install_config: NoInstallConfig::default(),
lock_file_update_config: LockFileUpdateConfig::default(),
};

assert!(config.no_install(), "as_is should enable no_install");
assert!(!config.allow_installs(), "as_is should disable installs");

let lock_usage = config.lock_file_usage().unwrap();
assert!(
matches!(lock_usage, LockFileUsage::Frozen),
"as_is should set lock file usage to Frozen"
);
}

#[test]
fn test_lock_and_install_config_respects_individual_flags() {
// Test that individual flags still work when --as-is is not set
let config = LockAndInstallConfig {
as_is: false,
no_install_config: NoInstallConfig::new(true),
lock_file_update_config: {
let mut lock_config = LockFileUpdateConfig::default();
lock_config.lock_file_usage.frozen = true;
lock_config
},
};

assert!(
config.no_install(),
"should respect individual no_install flag"
);
assert!(
!config.allow_installs(),
"should respect individual no_install flag"
);

let lock_usage = config.lock_file_usage().unwrap();
assert!(
matches!(lock_usage, LockFileUsage::Frozen),
"should respect individual frozen flag"
);
}
}
12 changes: 5 additions & 7 deletions src/cli/run.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ use pixi_core::{
workspace::{Environment, errors::UnsupportedPlatformError},
};

use crate::cli::cli_config::{LockFileUpdateConfig, NoInstallConfig, WorkspaceConfig};
use crate::cli::cli_config::{LockAndInstallConfig, WorkspaceConfig};

/// Runs task in the pixi environment.
///
Expand All @@ -50,9 +50,7 @@ pub struct Args {
pub workspace_config: WorkspaceConfig,

#[clap(flatten)]
pub no_install_config: NoInstallConfig,
#[clap(flatten)]
pub lock_file_update_config: LockFileUpdateConfig,
pub lock_and_install_config: LockAndInstallConfig,

#[clap(flatten)]
pub config: ConfigCli,
Expand Down Expand Up @@ -125,8 +123,8 @@ pub async fn execute(args: Args) -> miette::Result<()> {
// Ensure that the lock-file is up-to-date.
let lock_file = workspace
.update_lock_file(UpdateLockFileOptions {
no_install: args.no_install_config.no_install,
lock_file_usage: args.lock_file_update_config.lock_file_usage()?,
lock_file_usage: args.lock_and_install_config.lock_file_usage()?,
no_install: args.lock_and_install_config.no_install(),
max_concurrent_solves: workspace.config().max_concurrent_solves(),
})
.await?
Expand Down Expand Up @@ -254,7 +252,7 @@ pub async fn execute(args: Args) -> miette::Result<()> {
Entry::Occupied(env) => env.into_mut(),
Entry::Vacant(entry) => {
// Check if we allow installs
if args.no_install_config.allow_installs() {
if args.lock_and_install_config.allow_installs() {
// Ensure there is a valid prefix
lock_file
.prefix(
Expand Down
12 changes: 4 additions & 8 deletions src/cli/shell.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,25 +18,21 @@ use pixi_core::{
workspace::get_activated_environment_variables,
};

use crate::cli::cli_config::{NoInstallConfig, WorkspaceConfig};
use crate::cli::cli_config::{LockAndInstallConfig, WorkspaceConfig};
#[cfg(target_family = "unix")]
use pixi_pty::unix::PtySession;

#[cfg(target_family = "unix")]
use pixi_utils::prefix::Prefix;

use crate::cli::cli_config::LockFileUpdateConfig;

/// Start a shell in a pixi environment, run `exit` to leave the shell.
#[derive(Parser, Debug)]
pub struct Args {
#[clap(flatten)]
workspace_config: WorkspaceConfig,

#[clap(flatten)]
pub no_install_config: NoInstallConfig,
#[clap(flatten)]
pub lock_file_update_config: LockFileUpdateConfig,
pub lock_and_install_config: LockAndInstallConfig,

#[clap(flatten)]
config: ConfigCli,
Expand Down Expand Up @@ -281,8 +277,8 @@ pub async fn execute(args: Args) -> miette::Result<()> {
&environment,
UpdateMode::QuickValidate,
UpdateLockFileOptions {
lock_file_usage: args.lock_file_update_config.lock_file_usage()?,
no_install: args.no_install_config.no_install,
lock_file_usage: args.lock_and_install_config.lock_file_usage()?,
no_install: args.lock_and_install_config.no_install(),
max_concurrent_solves: workspace.config().max_concurrent_solves(),
},
ReinstallPackages::default(),
Expand Down
10 changes: 4 additions & 6 deletions src/cli/shell_hook.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ use pixi_core::{
workspace::{Environment, HasWorkspaceRef, get_activated_environment_variables},
};

use crate::cli::cli_config::{LockFileUpdateConfig, NoInstallConfig, WorkspaceConfig};
use crate::cli::cli_config::{LockAndInstallConfig, WorkspaceConfig};

/// Print the pixi environment activation script.
///
Expand All @@ -37,9 +37,7 @@ pub struct Args {
pub project_config: WorkspaceConfig,

#[clap(flatten)]
pub no_install_config: NoInstallConfig,
#[clap(flatten)]
pub lock_file_update_config: LockFileUpdateConfig,
pub lock_and_install_config: LockAndInstallConfig,

#[clap(flatten)]
config: ConfigCli,
Expand Down Expand Up @@ -160,8 +158,8 @@ pub async fn execute(args: Args) -> miette::Result<()> {
&environment,
UpdateMode::QuickValidate,
UpdateLockFileOptions {
lock_file_usage: args.lock_file_update_config.lock_file_usage()?,
no_install: args.no_install_config.no_install,
lock_file_usage: args.lock_and_install_config.lock_file_usage()?,
no_install: args.lock_and_install_config.no_install(),
max_concurrent_solves: workspace.config().max_concurrent_solves(),
},
ReinstallPackages::default(),
Expand Down
2 changes: 1 addition & 1 deletion tests/integration_rust/common/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -491,7 +491,7 @@ impl PixiControl {
// Ensure the lock-file is up-to-date
let lock_file = project
.update_lock_file(UpdateLockFileOptions {
lock_file_usage: args.lock_file_update_config.lock_file_usage().unwrap(),
lock_file_usage: args.lock_and_install_config.lock_file_usage().unwrap(),
..UpdateLockFileOptions::default()
})
.await?
Expand Down
11 changes: 7 additions & 4 deletions tests/integration_rust/install_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ use fs_err::tokio as tokio_fs;
use pixi::cli::run::{self, Args};
use pixi::cli::{
LockFileUsageConfig,
cli_config::{LockFileUpdateConfig, WorkspaceConfig},
cli_config::{LockAndInstallConfig, LockFileUpdateConfig, WorkspaceConfig},
};
use pixi_config::{Config, DetachedEnvironments};
use pixi_consts::consts;
Expand Down Expand Up @@ -297,9 +297,12 @@ async fn install_frozen() {
// Check if running with frozen doesn't suddenly install the latest update.
let result = pixi
.run(run::Args {
lock_file_update_config: LockFileUpdateConfig {
lock_file_usage: LockFileUsageConfig {
frozen: true,
lock_and_install_config: LockAndInstallConfig {
lock_file_update_config: LockFileUpdateConfig {
lock_file_usage: LockFileUsageConfig {
frozen: true,
..Default::default()
},
..Default::default()
},
..Default::default()
Expand Down
Loading