Skip to content
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: 26 additions & 7 deletions crates/uv-pep508/src/unnamed.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ use uv_normalize::ExtraName;

use crate::marker::parse;
use crate::verbatim_url::strip_host;
use crate::verbatim_url::were_vars_expanded;
use crate::{
Cursor, MarkerEnvironment, MarkerTree, Pep508Error, Pep508ErrorSource, Pep508Url, Reporter,
RequirementOrigin, Scheme, TracingReporter, VerbatimUrl, VerbatimUrlError, expand_env_vars,
Expand All @@ -32,6 +33,12 @@ pub trait UnnamedRequirementUrl: Pep508Url {
#[must_use]
fn with_given(self, given: impl AsRef<str>) -> Self;

/// Set the "given value contained variables which were expanded" flag.
#[must_use]
fn with_expanded(self, _expanded: bool) -> Self {
self
}

/// Return the original string as given by the user, if available.
fn given(&self) -> Option<&str>;
}
Expand All @@ -56,6 +63,10 @@ impl UnnamedRequirementUrl for VerbatimUrl {
self.with_given(given)
}

fn with_expanded(self, expanded: bool) -> Self {
self.with_expanded(expanded)
}

fn given(&self) -> Option<&str> {
self.given()
}
Expand Down Expand Up @@ -234,6 +245,7 @@ fn preprocess_unnamed_url<Url: UnnamedRequirementUrl>(

// Expand environment variables in the URL.
let expanded = expand_env_vars(url);
let vars_expanded = were_vars_expanded(url, expanded.as_ref());

if let Some((scheme, path)) = split_scheme(&expanded) {
match Scheme::parse(scheme) {
Expand All @@ -254,7 +266,8 @@ fn preprocess_unnamed_url<Url: UnnamedRequirementUrl>(
len,
input: cursor.to_string(),
})?
.with_given(url);
.with_given(url)
.with_expanded(vars_expanded);
return Ok((url, extras));
}

Expand All @@ -265,7 +278,8 @@ fn preprocess_unnamed_url<Url: UnnamedRequirementUrl>(
len,
input: cursor.to_string(),
})?
.with_given(url);
.with_given(url)
.with_expanded(vars_expanded);
Ok((url, extras))
}
// Ex) `https://download.pytorch.org/whl/torch_stable.html`
Expand All @@ -278,7 +292,8 @@ fn preprocess_unnamed_url<Url: UnnamedRequirementUrl>(
len,
input: cursor.to_string(),
})?
.with_given(url);
.with_given(url)
.with_expanded(vars_expanded);
Ok((url, extras))
}

Expand All @@ -292,7 +307,8 @@ fn preprocess_unnamed_url<Url: UnnamedRequirementUrl>(
len,
input: cursor.to_string(),
})?
.with_given(url);
.with_given(url)
.with_expanded(vars_expanded);
return Ok((url, extras));
}

Expand All @@ -303,7 +319,8 @@ fn preprocess_unnamed_url<Url: UnnamedRequirementUrl>(
len,
input: cursor.to_string(),
})?
.with_given(url);
.with_given(url)
.with_expanded(vars_expanded);
Ok((url, extras))
}
}
Expand All @@ -317,7 +334,8 @@ fn preprocess_unnamed_url<Url: UnnamedRequirementUrl>(
len,
input: cursor.to_string(),
})?
.with_given(url);
.with_given(url)
.with_expanded(vars_expanded);
return Ok((url, extras));
}

Expand All @@ -328,7 +346,8 @@ fn preprocess_unnamed_url<Url: UnnamedRequirementUrl>(
len,
input: cursor.to_string(),
})?
.with_given(url);
.with_given(url)
.with_expanded(vars_expanded);
Ok((url, extras))
}
}
Expand Down
22 changes: 11 additions & 11 deletions crates/uv-pep508/src/verbatim_url.rs
Original file line number Diff line number Diff line change
Expand Up @@ -260,9 +260,9 @@ impl VerbatimUrl {

/// Set the "given value contained variables which were expanded" flag.
///
/// Intended to only be used by the [`Pep508Url`] impl.
/// Intended to only be used by the URL parser implementations.
#[must_use]
fn with_expanded(self, expanded: bool) -> Self {
pub(crate) fn with_expanded(self, expanded: bool) -> Self {
Self { expanded, ..self }
}

Expand Down Expand Up @@ -369,15 +369,7 @@ impl Pep508Url for VerbatimUrl {
// Expand environment variables in the URL.
let expanded = expand_env_vars(url);

// Since `expand_env_vars` can return `Cow::Owned` even when variables were not expanded,
// the check needs to fall back to comparison for that case.
//
// Note: If a variable named `FOO` expands to `${FOO}` then this will produce a false
// negative. This seems like too much of a corner case to justify trying to fix it.
let vars_expanded = match &expanded {
Cow::Owned(owned) => owned != url,
Cow::Borrowed(_) => false,
};
let vars_expanded = were_vars_expanded(url, expanded.as_ref());

if let Some((scheme, path)) = split_scheme(&expanded) {
match Scheme::parse(scheme) {
Expand Down Expand Up @@ -521,6 +513,14 @@ pub fn expand_env_vars(s: &str) -> Cow<'_, str> {
})
}

/// Returns `true` if [`expand_env_vars`] changed the given value.
///
/// Note: If a variable named `FOO` expands to `${FOO}` then this will produce a false negative.
/// This seems like too much of a corner case to justify trying to fix it.
pub(crate) fn were_vars_expanded(given: &str, expanded: &str) -> bool {
expanded != given
}

/// Like [`Url::parse`], but only splits the scheme. Derived from the `url` crate.
pub fn split_scheme(s: &str) -> Option<(&str, &str)> {
/// <https://url.spec.whatwg.org/#c0-controls-and-space>
Expand Down
10 changes: 10 additions & 0 deletions crates/uv-pypi-types/src/parsed_url.rs
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,16 @@ impl UnnamedRequirementUrl for VerbatimParsedUrl {
}
}

fn with_expanded(self, expanded: bool) -> Self {
Self {
verbatim: <VerbatimUrl as UnnamedRequirementUrl>::with_expanded(
self.verbatim,
expanded,
),
..self
}
}

fn given(&self) -> Option<&str> {
self.verbatim.given()
}
Expand Down
13 changes: 7 additions & 6 deletions crates/uv-workspace/src/pyproject.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ use tracing::instrument;
use uv_build_backend::BuildBackendSettings;
use uv_configuration::{ExcludeDependency, GitLfsSetting, Override};
use uv_distribution_types::{Index, IndexName, RequirementSource};
use uv_fs::{PortablePathBuf, relative_to};
use uv_fs::{PortablePathBuf, try_relative_to_if};
use uv_git_types::GitReference;
use uv_macros::OptionsMetadata;
use uv_normalize::{DefaultGroups, ExtraName, GroupName, PackageName};
Expand Down Expand Up @@ -1777,12 +1777,13 @@ impl Source {
return Ok(None);
}
}
RequirementSource::Path { install_path, .. } => Self::Path {
RequirementSource::Path {
install_path, url, ..
} => Self::Path {
editable: None,
package: None,
path: PortablePathBuf::from(
relative_to(&install_path, root)
.or_else(|_| std::path::absolute(&install_path))
try_relative_to_if(&install_path, root, !url.was_given_absolute())
.map_err(SourceError::Absolute)?
.into_boxed_path(),
),
Expand All @@ -1793,13 +1794,13 @@ impl Source {
RequirementSource::Directory {
install_path,
editable: is_editable,
url,
..
} => Self::Path {
editable: editable.or(is_editable),
package: None,
path: PortablePathBuf::from(
relative_to(&install_path, root)
.or_else(|_| std::path::absolute(&install_path))
try_relative_to_if(&install_path, root, !url.was_given_absolute())
.map_err(SourceError::Absolute)?
.into_boxed_path(),
),
Expand Down
Loading
Loading