Skip to content

Commit

Permalink
Merge pull request #213 from baszalmstra/feat/install_during_add
Browse files Browse the repository at this point in the history
feat: also install environment when using add
  • Loading branch information
tdejager committed Jul 14, 2023
2 parents 9f4d913 + 3674d45 commit 08444f0
Show file tree
Hide file tree
Showing 5 changed files with 55 additions and 7 deletions.
26 changes: 24 additions & 2 deletions src/cli/add.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
use crate::environment::update_prefix;
use crate::prefix::Prefix;
use crate::{
environment::{load_lock_file, update_lock_file},
project::Project,
virtual_packages::get_minimal_virtual_packages,
};
use clap::Parser;
use console::style;
use indexmap::IndexMap;
use itertools::Itertools;
use miette::{IntoDiagnostic, WrapErr};
Expand Down Expand Up @@ -48,6 +51,10 @@ pub struct Args {
/// This is a build dependency
#[arg(long, conflicts_with = "host")]
pub build: bool,

/// Don't install the package to the environment, only add the package to the lock-file.
#[arg(long)]
pub no_install: bool,
}

#[derive(Debug, Copy, Clone)]
Expand All @@ -72,13 +79,14 @@ impl SpecType {
pub async fn execute(args: Args) -> miette::Result<()> {
let mut project = Project::load_or_else_discover(args.manifest_path.as_deref())?;
let spec_type = SpecType::from_args(&args);
add_specs_to_project(&mut project, args.specs, spec_type).await
add_specs_to_project(&mut project, args.specs, spec_type, args.no_install).await
}

pub async fn add_specs_to_project(
project: &mut Project,
specs: Vec<MatchSpec>,
spec_type: SpecType,
no_install: bool,
) -> miette::Result<()> {
// Split the specs into package name and version specifier
let new_specs = specs
Expand Down Expand Up @@ -160,14 +168,28 @@ pub async fn add_specs_to_project(
}

// Update the lock file and write to disk
update_lock_file(
let lock_file = update_lock_file(
project,
load_lock_file(project).await?,
Some(sparse_repo_data),
)
.await?;
project.save()?;

if !no_install {
let platform = Platform::current();
if project.platforms().contains(&platform) {
// Get the currently installed packages
let prefix = Prefix::new(project.root().join(".pixi/env"))?;
let installed_packages = prefix.find_installed_packages(None).await?;

// Update the prefix
update_prefix(&prefix, installed_packages, &lock_file, platform).await?;
} else {
eprintln!("{} skipping installation of environment because your platform ({platform}) is not supported by this project.", style("!").yellow().bold())
}
}

for spec in added_specs {
eprintln!(
"{}Added {}",
Expand Down
26 changes: 22 additions & 4 deletions src/environment.rs
Original file line number Diff line number Diff line change
Expand Up @@ -68,10 +68,29 @@ pub async fn get_up_to_date_prefix(project: &Project) -> miette::Result<Prefix>
lock_file
};

// Update the environment
update_prefix(
&prefix,
installed_packages_future.await.into_diagnostic()??,
&lock_file,
platform,
)
.await?;

Ok(prefix)
}

/// Updates the environment to contain the packages from the specified lock-file
pub async fn update_prefix(
prefix: &Prefix,
installed_packages: Vec<PrefixRecord>,
lock_file: &CondaLock,
platform: Platform,
) -> miette::Result<()> {
// Construct a transaction to bring the environment up to date with the lock-file content
let transaction = Transaction::from_current_and_desired(
installed_packages_future.await.into_diagnostic()??,
get_required_packages(&lock_file, platform)?,
installed_packages,
get_required_packages(lock_file, platform)?,
platform,
)
.into_diagnostic()?;
Expand All @@ -91,8 +110,7 @@ pub async fn get_up_to_date_prefix(project: &Project) -> miette::Result<Prefix>
)
.await?;
}

Ok(prefix)
Ok(())
}

/// Loads the lockfile for the specified project or returns a dummy one if none could be found.
Expand Down
7 changes: 7 additions & 0 deletions tests/common/builders.rs
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,13 @@ impl AddBuilder {
}
self
}

/// Set whether or not to also install the environment. By default the environment is NOT
/// installed to reduce test times.
pub fn with_install(mut self, install: bool) -> Self {
self.args.no_install = !install;
self
}
}

impl IntoFuture for AddBuilder {
Expand Down
1 change: 1 addition & 0 deletions tests/common/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,7 @@ impl PixiControl {
host: false,
specs: vec![spec.into()],
build: false,
no_install: true,
},
}
}
Expand Down
2 changes: 1 addition & 1 deletion tests/install_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ use tempfile::TempDir;
async fn install_run_python() {
let pixi = PixiControl::new().unwrap();
pixi.init().await.unwrap();
pixi.add("python==3.11.0").await.unwrap();
pixi.add("python==3.11.0").with_install(true).await.unwrap();

// Check if lock has python version
let lock = pixi.lock_file().await.unwrap();
Expand Down

0 comments on commit 08444f0

Please sign in to comment.