Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Remove dependency from feature through cli #680

Merged
merged 11 commits into from
Jan 18, 2024
22 changes: 16 additions & 6 deletions src/cli/remove.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ use miette::miette;
use rattler_conda_types::Platform;

use crate::environment::LockFileUsage;
use crate::project::manifest::FeatureName;
use crate::{consts, environment::get_up_to_date_prefix, project::SpecType, Project};

/// Remove the dependency from the project
Expand Down Expand Up @@ -34,6 +35,10 @@ pub struct Args {
/// The platform for which the dependency should be removed
#[arg(long, short)]
pub platform: Option<Platform>,

/// The feature for which the dependency should be removed
#[arg(long)]
pub feature: Option<FeatureName>,
baszalmstra marked this conversation as resolved.
Show resolved Hide resolved
}

fn convert_pkg_name<T>(deps: &[String]) -> miette::Result<Vec<T>>
Expand Down Expand Up @@ -81,9 +86,11 @@ pub async fn execute(args: Args) -> miette::Result<()> {
if args.pypi {
let all_pkg_name = convert_pkg_name::<rip::types::PackageName>(&deps)?;
for dep in all_pkg_name.iter() {
let (name, req) = project
.manifest
.remove_pypi_dependency(dep, args.platform)?;
let (name, req) = project.manifest.remove_pypi_dependency(
dep,
args.platform,
args.feature.as_ref(),
)?;
sucessful_output.push(format_ok_message(
name.as_str(),
&req.to_string(),
Expand All @@ -93,9 +100,12 @@ pub async fn execute(args: Args) -> miette::Result<()> {
} else {
let all_pkg_name = convert_pkg_name::<rattler_conda_types::PackageName>(&deps)?;
for dep in all_pkg_name.iter() {
let (name, req) = project
.manifest
.remove_dependency(dep, spec_type, args.platform)?;
let (name, req) = project.manifest.remove_dependency(
dep,
spec_type,
args.platform,
args.feature.as_ref(),
)?;
sucessful_output.push(format_ok_message(
name.as_source(),
&req.to_string(),
Expand Down
1 change: 1 addition & 0 deletions src/environment.rs
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ fn create_prefix_location_file(prefix_file: &Path) -> miette::Result<()> {
/// Runs the following checks to make sure the project is in a sane state:
/// 1. It verifies that the prefix location is unchanged.
/// 2. It verifies that the system requirements are met.
/// 3. It verifies the absence of the `env` folder.
pub fn sanity_check_project(project: &Project) -> miette::Result<()> {
// Sanity check of prefix location
verify_prefix_location_unchanged(
Expand Down
23 changes: 21 additions & 2 deletions src/project/manifest/feature.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
use super::{Activation, PyPiRequirement, SystemRequirements, Target, TargetSelector};
use crate::consts;
use crate::project::manifest::channel::{PrioritizedChannel, TomlPrioritizedChannelStrOrMap};
use crate::project::manifest::target::Targets;
use crate::project::SpecType;
Expand All @@ -10,7 +11,7 @@ use rattler_conda_types::{NamelessMatchSpec, PackageName, Platform};
use serde::de::Error;
use serde::{Deserialize, Deserializer};
use serde_with::{serde_as, DisplayFromStr, PickFirst};
use std::borrow::Cow;
use std::borrow::{Borrow, Cow};
use std::collections::HashMap;

/// The name of a feature. This is either a string or default for the default feature.
Expand All @@ -26,14 +27,22 @@ impl<'de> Deserialize<'de> for FeatureName {
D: serde::Deserializer<'de>,
{
match String::deserialize(deserializer)?.as_str() {
"default" => Err(D::Error::custom(
consts::DEFAULT_ENVIRONMENT_NAME => Err(D::Error::custom(
"The name 'default' is reserved for the default feature",
)),
name => Ok(FeatureName::Named(name.to_string())),
}
}
}

impl<'s> From<&'s str> for FeatureName {
fn from(value: &'s str) -> Self {
match value {
consts::DEFAULT_ENVIRONMENT_NAME => FeatureName::Default,
name => FeatureName::Named(name.to_string()),
}
}
}
impl FeatureName {
/// Returns the name of the feature or `None` if this is the default feature.
pub fn name(&self) -> Option<&str> {
Expand All @@ -42,6 +51,16 @@ impl FeatureName {
FeatureName::Named(name) => Some(name),
}
}

pub fn as_str(&self) -> &str {
self.name().unwrap_or(consts::DEFAULT_ENVIRONMENT_NAME)
}
}

impl Borrow<str> for FeatureName {
fn borrow(&self) -> &str {
self.as_str()
}
}

/// A feature describes a set of functionalities. It allows us to group functionality and its
Expand Down
Loading
Loading