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

refactor: parse matchspec url into NamedChannelOrUrl [skip ci] #964

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
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
33 changes: 4 additions & 29 deletions crates/rattler_conda_types/src/match_spec/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ use std::hash::Hash;
use std::sync::Arc;
use url::Url;

use crate::Channel;
use crate::{Channel, NamedChannelOrUrl};
use crate::ChannelConfig;

pub mod matcher;
Expand Down Expand Up @@ -133,7 +133,7 @@ pub struct MatchSpec {
/// Match the specific filename of the package
pub file_name: Option<String>,
/// The channel of the package
pub channel: Option<Arc<Channel>>,
pub channel: Option<NamedChannelOrUrl>,
/// The subdir of the channel
pub subdir: Option<String>,
/// The namespace of the package (currently not used)
Expand All @@ -151,8 +151,7 @@ pub struct MatchSpec {
impl Display for MatchSpec {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
if let Some(channel) = &self.channel {
let name = channel.name();
write!(f, "{name}")?;
write!(f, "{channel}")?;

if let Some(subdir) = &self.subdir {
write!(f, "/{subdir}")?;
Expand Down Expand Up @@ -256,8 +255,7 @@ pub struct NamelessMatchSpec {
/// Match the specific filename of the package
pub file_name: Option<String>,
/// The channel of the package
#[serde(deserialize_with = "deserialize_channel", default)]
pub channel: Option<Arc<Channel>>,
pub channel: Option<NamedChannelOrUrl>,
/// The subdir of the channel
pub subdir: Option<String>,
/// The namespace of the package (currently not used)
Expand Down Expand Up @@ -337,29 +335,6 @@ impl MatchSpec {
}
}

/// Deserialize channel from string
/// TODO: This should be refactored so that the front ends are the one setting the channel config,
/// and rattler only takes care of the url.
fn deserialize_channel<'de, D>(deserializer: D) -> Result<Option<Arc<Channel>>, D::Error>
where
D: Deserializer<'de>,
{
let s: Option<String> = Option::deserialize(deserializer)?;

match s {
Some(str_val) => {
let config = ChannelConfig::default_with_root_dir(
std::env::current_dir().expect("Could not determine current directory"),
);

Channel::from_str(str_val, &config)
.map(|channel| Some(Arc::new(channel)))
.map_err(serde::de::Error::custom)
}
None => Ok(None),
}
}

/// A trait that defines the behavior of matching a spec against a record.
pub trait Matches<T> {
/// Match a [`MatchSpec`] against a record.
Expand Down
29 changes: 9 additions & 20 deletions crates/rattler_conda_types/src/match_spec/parse.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use std::{borrow::Cow, collections::HashSet, ops::Not, str::FromStr, sync::Arc};
use std::{borrow::Cow, collections::HashSet, ops::Not, str::FromStr};

use nom::{
branch::alt,
Expand All @@ -21,18 +21,11 @@ use super::{
MatchSpec,
};
use crate::{
build_spec::{BuildNumberSpec, ParseBuildNumberSpecError},
package::ArchiveIdentifier,
utils::{path::is_absolute_path, url::parse_scheme},
version_spec::{
build_spec::{BuildNumberSpec, ParseBuildNumberSpecError}, package::ArchiveIdentifier, utils::{path::is_absolute_path, url::parse_scheme}, version_spec::{
is_start_of_version_constraint,
version_tree::{recognize_constraint, recognize_version},
ParseVersionSpecError,
},
Channel, ChannelConfig, InvalidPackageNameError, NamelessMatchSpec, PackageName,
ParseChannelError, ParseStrictness,
ParseStrictness::{Lenient, Strict},
ParseVersionError, Platform, VersionSpec,
}, InvalidPackageNameError, NamedChannelOrUrl, NamelessMatchSpec, PackageName, ParseChannelError, ParseStrictness::{self, Lenient, Strict}, ParseVersionError, Platform, VersionSpec
};

/// The type of parse error that occurred when parsing match spec.
Expand Down Expand Up @@ -280,7 +273,7 @@ fn parse_bracket_vec_into_components(
"subdir" => match_spec.subdir = Some(value.to_string()),
"channel" => {
let (channel, subdir) = parse_channel_and_subdir(value)?;
match_spec.channel = match_spec.channel.or(channel.map(Arc::new));
match_spec.channel = match_spec.channel.or(channel);
match_spec.subdir = match_spec.subdir.or(subdir);
}
// TODO: Still need to add `track_features`, `features`, `license` and `license_family`
Expand Down Expand Up @@ -490,7 +483,7 @@ impl NamelessMatchSpec {

if let Some(channel_str) = channel_str {
let (channel, subdir) = parse_channel_and_subdir(channel_str)?;
match_spec.channel = match_spec.channel.or(channel.map(Arc::new));
match_spec.channel = match_spec.channel.or(channel);
match_spec.subdir = match_spec.subdir.or(subdir);
}

Expand Down Expand Up @@ -519,21 +512,17 @@ impl NamelessMatchSpec {
/// Parse channel and subdir from a string.
fn parse_channel_and_subdir(
input: &str,
) -> Result<(Option<Channel>, Option<String>), ParseMatchSpecError> {
let channel_config = ChannelConfig::default_with_root_dir(
std::env::current_dir().expect("Could not get current directory"),
);

) -> Result<(Option<NamedChannelOrUrl>, Option<String>), ParseMatchSpecError> {
if let Some((channel, subdir)) = input.rsplit_once('/') {
// If the subdir is a platform, we assume the channel has a subdir
if Platform::from_str(subdir).is_ok() {
return Ok((
Some(Channel::from_str(channel, &channel_config)?),
Some(NamedChannelOrUrl::from_str(channel)?),
Some(subdir.to_string()),
));
}
}
Ok((Some(Channel::from_str(input, &channel_config)?), None))
Ok((Some(NamedChannelOrUrl::from_str(input)?), None))
}

/// Parses a conda match spec.
Expand Down Expand Up @@ -592,7 +581,7 @@ fn matchspec_parser(

if let Some(channel_str) = channel_str {
let (channel, subdir) = parse_channel_and_subdir(channel_str)?;
nameless_match_spec.channel = nameless_match_spec.channel.or(channel.map(Arc::new));
nameless_match_spec.channel = nameless_match_spec.channel.or(channel);
nameless_match_spec.subdir = nameless_match_spec.subdir.or(subdir);
}

Expand Down