From d531eb3806397b5c57ef5574bc480cbd945806b1 Mon Sep 17 00:00:00 2001 From: Min RK Date: Sat, 21 Sep 2024 00:16:19 +0200 Subject: [PATCH] test: exercise project channel add/remove with priority --- crates/pixi_manifest/src/channel.rs | 2 +- .../pixi_manifest/src/manifests/manifest.rs | 7 ++-- tests/common/builders.rs | 38 +++++++++++++++++++ tests/common/mod.rs | 15 +++++++- tests/project_tests.rs | 35 ++++++++++++++++- 5 files changed, 90 insertions(+), 7 deletions(-) diff --git a/crates/pixi_manifest/src/channel.rs b/crates/pixi_manifest/src/channel.rs index 32ebf7b28..b777433a3 100644 --- a/crates/pixi_manifest/src/channel.rs +++ b/crates/pixi_manifest/src/channel.rs @@ -41,7 +41,7 @@ impl From for Value { table.insert("channel", channel.channel.to_string().into()); table.insert("priority", i64::from(priority).into()); Value::InlineTable(table) - }, + } None => Value::String(toml_edit::Formatted::new(channel.channel.to_string())), } } diff --git a/crates/pixi_manifest/src/manifests/manifest.rs b/crates/pixi_manifest/src/manifests/manifest.rs index 67d348012..98736dc95 100644 --- a/crates/pixi_manifest/src/manifests/manifest.rs +++ b/crates/pixi_manifest/src/manifests/manifest.rs @@ -566,22 +566,21 @@ impl Manifest { FeatureName::Default => &mut self.parsed.project.channels, FeatureName::Named(_) => self.feature_mut(feature_name)?.channels_mut(), }; - // Get the channels to remove, while checking if they exist let to_remove: IndexSet<_> = channels .into_iter() .map(|c| { current .iter() - .position(|x| x.channel == c.channel) + .position(|x| x.channel.to_string() == c.channel.to_string()) .ok_or_else(|| miette::miette!("channel {} does not exist", c.channel.as_str())) - .map(|_| c.channel) + .map(|_| c.channel.to_string()) }) .collect::>()?; let retained: IndexSet<_> = current .iter() - .filter(|channel| !to_remove.contains(&channel.channel)) + .filter(|channel| !to_remove.contains(&channel.channel.to_string())) .cloned() .collect(); diff --git a/tests/common/builders.rs b/tests/common/builders.rs index b53b67b3f..2e551c10a 100644 --- a/tests/common/builders.rs +++ b/tests/common/builders.rs @@ -323,6 +323,11 @@ impl ProjectChannelAddBuilder { self } + pub fn with_priority(mut self, priority: Option) -> Self { + self.args.priority = priority; + self + } + /// Alias to add a local channel. pub fn with_local_channel(self, channel: impl AsRef) -> Self { self.with_channel(Url::from_directory_path(channel).unwrap()) @@ -342,6 +347,39 @@ impl IntoFuture for ProjectChannelAddBuilder { } } +pub struct ProjectChannelRemoveBuilder { + pub manifest_path: Option, + pub args: project::channel::AddRemoveArgs, +} + +impl ProjectChannelRemoveBuilder { + /// Removes the specified channel + pub fn with_channel(mut self, name: impl Into) -> Self { + self.args + .channel + .push(NamedChannelOrUrl::from_str(&name.into()).unwrap()); + self + } + + /// Alias to Remove a local channel. + pub fn with_local_channel(self, channel: impl AsRef) -> Self { + self.with_channel(Url::from_directory_path(channel).unwrap()) + } +} + +impl IntoFuture for ProjectChannelRemoveBuilder { + type Output = miette::Result<()>; + type IntoFuture = Pin + 'static>>; + + fn into_future(self) -> Self::IntoFuture { + project::channel::execute(project::channel::Args { + manifest_path: self.manifest_path, + command: project::channel::Command::Remove(self.args), + }) + .boxed_local() + } +} + /// Contains the arguments to pass to [`install::execute()`]. Call `.await` to /// call the CLI execute method and await the result at the same time. pub struct InstallBuilder { diff --git a/tests/common/mod.rs b/tests/common/mod.rs index fe353b4c6..08d310936 100644 --- a/tests/common/mod.rs +++ b/tests/common/mod.rs @@ -38,7 +38,7 @@ use thiserror::Error; use self::builders::{HasDependencyConfig, RemoveBuilder}; use crate::common::builders::{ - AddBuilder, InitBuilder, InstallBuilder, ProjectChannelAddBuilder, + AddBuilder, InitBuilder, InstallBuilder, ProjectChannelAddBuilder, ProjectChannelRemoveBuilder, ProjectEnvironmentAddBuilder, TaskAddBuilder, TaskAliasBuilder, UpdateBuilder, }; @@ -339,6 +339,19 @@ impl PixiControl { } } + /// Add a new channel to the project. + pub fn project_channel_remove(&self) -> ProjectChannelRemoveBuilder { + ProjectChannelRemoveBuilder { + manifest_path: Some(self.manifest_path()), + args: project::channel::AddRemoveArgs { + channel: vec![], + no_install: true, + feature: None, + priority: None, + }, + } + } + pub fn project_environment_add(&self, name: &str) -> ProjectEnvironmentAddBuilder { ProjectEnvironmentAddBuilder { manifest_path: Some(self.manifest_path()), diff --git a/tests/project_tests.rs b/tests/project_tests.rs index e160b9021..933046914 100644 --- a/tests/project_tests.rs +++ b/tests/project_tests.rs @@ -12,7 +12,7 @@ use url::Url; use crate::common::{package_database::PackageDatabase, PixiControl}; #[tokio::test] -async fn add_channel() { +async fn add_remove_channel() { // Create a local package database with no entries and write it to disk. This // ensures that we have a valid channel. let package_database = PackageDatabase::default(); @@ -47,7 +47,40 @@ async fn add_channel() { let local_channel = NamedChannelOrUrl::Url(Url::from_file_path(additional_channel_dir.as_ref()).unwrap()); let channels = project.default_environment().channels(); + assert!(channels.len() == 2); + assert!(channels.last().unwrap() == &&local_channel); assert!(channels.contains(&local_channel)); + + // now add the same channel, with priority 2 + pixi.project_channel_add() + .with_local_channel(additional_channel_dir.path()) + .with_priority(Some(2i32)) + .await + .unwrap(); + + // Load again + let project = Project::from_path(&pixi.manifest_path()).unwrap(); + let channels = project.default_environment().channels(); + // still present + assert!(channels.contains(&local_channel)); + // didn't duplicate + assert!(channels.len() == 2); + // priority applied + assert!(channels.first().unwrap() == &&local_channel); + + // now remove it + pixi.project_channel_remove() + .with_local_channel(additional_channel_dir.path()) + .await + .unwrap(); + + // Load again + let project = Project::from_path(&pixi.manifest_path()).unwrap(); + let channels = project.default_environment().channels(); + + // Channel has been removed + assert!(channels.len() == 1); + assert!(!channels.contains(&local_channel)); } #[tokio::test]