From 6e002565f52ea998cbc117bc63c8ba6f8b633280 Mon Sep 17 00:00:00 2001 From: Olivier Lacroix Date: Sun, 19 May 2024 22:06:45 +1000 Subject: [PATCH] refactor: Remove project level method that are per environment (#1412) --- src/cli/add.rs | 19 ++++--- src/cli/list.rs | 2 +- src/cli/search.rs | 8 ++- src/project/mod.rs | 121 +++++++++++------------------------------ tests/add_tests.rs | 14 +++-- tests/init_tests.rs | 6 +- tests/project_tests.rs | 8 ++- 7 files changed, 70 insertions(+), 108 deletions(-) diff --git a/src/cli/add.rs b/src/cli/add.rs index e9c73691f..946e0886c 100644 --- a/src/cli/add.rs +++ b/src/cli/add.rs @@ -125,14 +125,9 @@ pub async fn execute(args: Args) -> miette::Result<()> { verify_prefix_location_unchanged(project.default_environment().dir().as_path()).await?; // Add the platform if it is not already present - let platforms_to_add = spec_platforms - .iter() - .filter(|p| !project.platforms().contains(p)) - .cloned() - .collect::>(); project .manifest - .add_platforms(platforms_to_add.iter(), &FeatureName::Default)?; + .add_platforms(spec_platforms.iter(), &FeatureName::Default)?; let feature_name = args .feature @@ -376,7 +371,11 @@ async fn determine_latest_versions( ) -> miette::Result> { // Get platforms to search for including NoArch let platforms = if platforms.is_empty() { - let mut temp = project.platforms().into_iter().collect_vec(); + let mut temp = project + .default_environment() + .platforms() + .into_iter() + .collect_vec(); temp.push(Platform::NoArch); temp } else { @@ -389,7 +388,11 @@ async fn determine_latest_versions( let records = project .repodata_gateway() .query( - project.channels().into_iter().cloned(), + project + .default_environment() + .channels() + .into_iter() + .cloned(), platforms, [name.clone()], ) diff --git a/src/cli/list.rs b/src/cli/list.rs index 74a3846e8..015e1c4cf 100644 --- a/src/cli/list.rs +++ b/src/cli/list.rs @@ -141,7 +141,7 @@ pub async fn execute(args: Args) -> miette::Result<()> { index_locations = environment.pypi_options().to_index_locations(); tags = get_pypi_tags( platform, - &project.system_requirements(), + &environment.system_requirements(), python_record.package_record(), )?; Some(RegistryWheelIndex::new( diff --git a/src/cli/search.rs b/src/cli/search.rs index b1d103527..46ff7776b 100644 --- a/src/cli/search.rs +++ b/src/cli/search.rs @@ -16,6 +16,7 @@ use tokio::task::spawn_blocking; use crate::config::Config; use crate::util::default_channel_config; use crate::utils::reqwest::build_reqwest_clients; +use crate::HasFeatures; use crate::{progress::await_in_progress, repodata::fetch_sparse_repodata, Project}; /// Search a package, output will list the latest version of package @@ -115,7 +116,12 @@ pub async fn execute(args: Args) -> miette::Result<()> { } // if user doesn't pass channels and we are in a project (None, Some(p)) => { - let channels: Vec<_> = p.channels().into_iter().cloned().collect(); + let channels: Vec<_> = p + .default_environment() + .channels() + .into_iter() + .cloned() + .collect(); eprintln!( "Using channels from project ({}): {}", p.name(), diff --git a/src/project/mod.rs b/src/project/mod.rs index f29e4565c..f8b291c68 100644 --- a/src/project/mod.rs +++ b/src/project/mod.rs @@ -9,15 +9,14 @@ mod solve_group; pub mod virtual_packages; use async_once_cell::OnceCell as AsyncCell; -use indexmap::{Equivalent, IndexSet}; +use indexmap::Equivalent; use miette::{IntoDiagnostic, NamedSource}; -use rattler_conda_types::{Channel, Platform, Version}; +use rattler_conda_types::Version; use reqwest_middleware::ClientWithMiddleware; use std::hash::Hash; use rattler_repodata_gateway::Gateway; -use rattler_virtual_packages::VirtualPackage; use std::sync::OnceLock; use std::{ collections::{HashMap, HashSet}, @@ -29,20 +28,13 @@ use std::{ use crate::activation::{get_environment_variables, run_activation}; use crate::config::Config; +use crate::consts::{self, PROJECT_MANIFEST, PYPROJECT_MANIFEST}; use crate::project::grouped_environment::GroupedEnvironment; use crate::pypi_mapping::MappingSource; -use crate::task::TaskName; use crate::utils::reqwest::build_reqwest_clients; -use crate::{ - consts::{self, PROJECT_MANIFEST, PYPROJECT_MANIFEST}, - task::Task, -}; -use manifest::{EnvironmentName, Manifest, SystemRequirements}; +use manifest::{EnvironmentName, Manifest}; -use self::{ - has_features::HasFeatures, - manifest::{pyproject::PyProjectToml, Environments}, -}; +use self::manifest::{pyproject::PyProjectToml, Environments}; pub use dependencies::{CondaDependencies, PyPiDependencies}; pub use environment::Environment; pub use solve_group::SolveGroup; @@ -394,76 +386,6 @@ impl Project { environments.into_iter().collect() } - /// Returns the channels used by this project. - /// - /// TODO: Remove this function and use the channels from the default environment instead. - pub fn channels(&self) -> IndexSet<&Channel> { - self.default_environment().channels() - } - - /// Returns the platforms this project targets - /// - /// TODO: Remove this function and use the platforms from the default environment instead. - pub fn platforms(&self) -> HashSet { - self.default_environment().platforms() - } - - /// Get the tasks of this project - /// - /// TODO: Remove this function and use the tasks from the default environment instead. - pub fn tasks(&self, platform: Option) -> HashMap<&TaskName, &Task> { - self.default_environment() - .tasks(platform) - .unwrap_or_default() - } - - /// Get the task with the specified `name` or `None` if no such task exists. If `platform` is - /// specified then the task will first be looked up in the target specific tasks for the given - /// platform. - /// - /// TODO: Remove this function and use the `task` function from the default environment instead. - pub fn task_opt(&self, name: &TaskName, platform: Option) -> Option<&Task> { - self.default_environment().task(name, platform).ok() - } - - /// TODO: Remove this method and use the one from Environment instead. - pub fn virtual_packages(&self, platform: Platform) -> Vec { - self.default_environment().virtual_packages(platform) - } - - /// Get the system requirements defined under the `system-requirements` section of the project manifest. - /// They will act as the description of a reference machine which is minimally needed for this package to be run. - /// - /// TODO: Remove this function and use the `system_requirements` function from the default environment instead. - pub fn system_requirements(&self) -> SystemRequirements { - self.default_environment().system_requirements() - } - - /// Returns the dependencies of the project. - /// - /// TODO: Remove this function and use the `dependencies` function from the default environment instead. - pub fn dependencies( - &self, - kind: Option, - platform: Option, - ) -> CondaDependencies { - self.default_environment().dependencies(kind, platform) - } - - /// Returns the PyPi dependencies of the project - /// - /// TODO: Remove this function and use the `dependencies` function from the default environment instead. - pub fn pypi_dependencies(&self, platform: Option) -> PyPiDependencies { - self.default_environment().pypi_dependencies(platform) - } - - /// Returns the all specified activation scripts that are used in the current platform. - /// - /// TODO: Remove this function and use the `activation_scripts function from the default environment instead. - pub fn activation_scripts(&self, platform: Option) -> Vec { - self.default_environment().activation_scripts(platform) - } - /// Returns true if the project contains any reference pypi dependencies. Even if just /// `[pypi-dependencies]` is specified without any requirements this will return true. pub fn has_pypi_dependencies(&self) -> bool { @@ -550,10 +472,12 @@ pub fn find_project_manifest() -> Option { #[cfg(test)] mod tests { + use self::has_features::HasFeatures; use super::*; use crate::project::manifest::FeatureName; use insta::{assert_debug_snapshot, assert_snapshot}; use itertools::Itertools; + use rattler_conda_types::Platform; use rattler_virtual_packages::{LibC, VirtualPackage}; use std::str::FromStr; @@ -597,7 +521,10 @@ mod tests { version: Version::from_str("2.12").unwrap(), })]; - let virtual_packages = project.system_requirements().virtual_packages(); + let virtual_packages = project + .default_environment() + .system_requirements() + .virtual_packages(); assert_eq!(virtual_packages, expected_result); } @@ -630,7 +557,9 @@ mod tests { let project = Project::from_manifest(manifest); assert_snapshot!(format_dependencies( - project.dependencies(None, Some(Platform::Linux64)) + project + .default_environment() + .dependencies(None, Some(Platform::Linux64)) )); } @@ -663,7 +592,9 @@ mod tests { let project = Project::from_manifest(manifest); assert_snapshot!(format_dependencies( - project.dependencies(None, Some(Platform::Linux64)) + project + .default_environment() + .dependencies(None, Some(Platform::Linux64)) )); } @@ -693,9 +624,21 @@ mod tests { assert_snapshot!(format!( "= Linux64\n{}\n\n= Win64\n{}\n\n= OsxArm64\n{}", - fmt_activation_scripts(project.activation_scripts(Some(Platform::Linux64))), - fmt_activation_scripts(project.activation_scripts(Some(Platform::Win64))), - fmt_activation_scripts(project.activation_scripts(Some(Platform::OsxArm64))) + fmt_activation_scripts( + project + .default_environment() + .activation_scripts(Some(Platform::Linux64)) + ), + fmt_activation_scripts( + project + .default_environment() + .activation_scripts(Some(Platform::Win64)) + ), + fmt_activation_scripts( + project + .default_environment() + .activation_scripts(Some(Platform::OsxArm64)) + ) )); } diff --git a/tests/add_tests.rs b/tests/add_tests.rs index 090945e24..fe6018615 100644 --- a/tests/add_tests.rs +++ b/tests/add_tests.rs @@ -4,7 +4,7 @@ use crate::common::package_database::{Package, PackageDatabase}; use crate::common::LockFileExt; use crate::common::PixiControl; use pixi::consts::DEFAULT_ENVIRONMENT_NAME; -use pixi::{DependencyType, SpecType}; +use pixi::{DependencyType, HasFeatures, SpecType}; use rattler_conda_types::{PackageName, Platform}; use serial_test::serial; use std::str::FromStr; @@ -100,13 +100,19 @@ async fn add_functionality_union() { let project = pixi.project().unwrap(); // Should contain all added dependencies - let dependencies = project.dependencies(Some(SpecType::Run), Some(Platform::current())); + let dependencies = project + .default_environment() + .dependencies(Some(SpecType::Run), Some(Platform::current())); let (name, _) = dependencies.into_specs().next().unwrap(); assert_eq!(name, PackageName::try_from("rattler").unwrap()); - let host_deps = project.dependencies(Some(SpecType::Host), Some(Platform::current())); + let host_deps = project + .default_environment() + .dependencies(Some(SpecType::Host), Some(Platform::current())); let (name, _) = host_deps.into_specs().next().unwrap(); assert_eq!(name, PackageName::try_from("libcomputer").unwrap()); - let build_deps = project.dependencies(Some(SpecType::Build), Some(Platform::current())); + let build_deps = project + .default_environment() + .dependencies(Some(SpecType::Build), Some(Platform::current())); let (name, _) = build_deps.into_specs().next().unwrap(); assert_eq!(name, PackageName::try_from("libidk").unwrap()); diff --git a/tests/init_tests.rs b/tests/init_tests.rs index 8d88c992e..dc1007197 100644 --- a/tests/init_tests.rs +++ b/tests/init_tests.rs @@ -1,7 +1,7 @@ mod common; use crate::common::PixiControl; -use pixi::util::default_channel_config; +use pixi::{util::default_channel_config, HasFeatures}; use rattler_conda_types::{Channel, Version}; use std::str::FromStr; @@ -43,7 +43,7 @@ async fn specific_channel() { let project = pixi.project().unwrap(); // The only channel should be the "random" channel - let channels = Vec::from_iter(project.channels()); + let channels = Vec::from_iter(project.default_environment().channels()); assert_eq!( channels, [ @@ -65,7 +65,7 @@ async fn default_channel() { let project = pixi.project().unwrap(); // The only channel should be the "conda-forge" channel - let channels = Vec::from_iter(project.channels()); + let channels = Vec::from_iter(project.default_environment().channels()); assert_eq!( channels, [&Channel::from_str("conda-forge", &default_channel_config()).unwrap()] diff --git a/tests/project_tests.rs b/tests/project_tests.rs index 7d9cedc92..0bf580be8 100644 --- a/tests/project_tests.rs +++ b/tests/project_tests.rs @@ -4,7 +4,7 @@ use std::path::PathBuf; use crate::{common::package_database::PackageDatabase, common::PixiControl}; use insta::assert_debug_snapshot; -use pixi::{util::default_channel_config, Project}; +use pixi::{util::default_channel_config, HasFeatures, Project}; use rattler_conda_types::{Channel, Platform}; use tempfile::TempDir; use url::Url; @@ -47,13 +47,17 @@ async fn add_channel() { &default_channel_config(), ) .unwrap(); - assert!(project.channels().contains(&local_channel)); + assert!(project + .default_environment() + .channels() + .contains(&local_channel)); } #[tokio::test] async fn parse_project() { fn dependency_names(project: &Project, platform: Platform) -> Vec { project + .default_environment() .dependencies(None, Some(platform)) .iter() .map(|dep| dep.0.as_normalized().to_string())