mirror of
https://github.com/astral-sh/uv.git
synced 2025-10-21 07:42:05 +00:00
Support environment variables in index URLs in requirements files (#2036)
## Summary This also preserves the environment variables in the output file, e.g.: ``` Resolved 1 package in 216ms # This file was autogenerated by uv via the following command: # uv pip compile requirements.in --emit-index-url --index-url https://test.pypi.org/${SUFFIX} requests==2.5.4.1 ``` I'm torn on whether that's correct or undesirable here. Closes #2035.
This commit is contained in:
parent
1df977f86b
commit
b873e3e991
14 changed files with 140 additions and 70 deletions
|
@ -755,11 +755,11 @@ fn preprocess_url(
|
|||
#[cfg(feature = "non-pep508-extensions")]
|
||||
if let Some(working_dir) = working_dir {
|
||||
return Ok(
|
||||
VerbatimUrl::from_path(path, working_dir).with_given(url.to_string())
|
||||
VerbatimUrl::parse_path(path, working_dir).with_given(url.to_string())
|
||||
);
|
||||
}
|
||||
|
||||
Ok(VerbatimUrl::from_absolute_path(path)
|
||||
Ok(VerbatimUrl::parse_absolute_path(path)
|
||||
.map_err(|err| Pep508Error {
|
||||
message: Pep508ErrorSource::UrlError(err),
|
||||
start,
|
||||
|
@ -783,10 +783,12 @@ fn preprocess_url(
|
|||
_ => {
|
||||
#[cfg(feature = "non-pep508-extensions")]
|
||||
if let Some(working_dir) = working_dir {
|
||||
return Ok(VerbatimUrl::from_path(url, working_dir).with_given(url.to_string()));
|
||||
return Ok(
|
||||
VerbatimUrl::parse_path(url, working_dir).with_given(url.to_string())
|
||||
);
|
||||
}
|
||||
|
||||
Ok(VerbatimUrl::from_absolute_path(url)
|
||||
Ok(VerbatimUrl::parse_absolute_path(url)
|
||||
.map_err(|err| Pep508Error {
|
||||
message: Pep508ErrorSource::UrlError(err),
|
||||
start,
|
||||
|
@ -800,10 +802,10 @@ fn preprocess_url(
|
|||
// Ex) `../editable/`
|
||||
#[cfg(feature = "non-pep508-extensions")]
|
||||
if let Some(working_dir) = working_dir {
|
||||
return Ok(VerbatimUrl::from_path(url, working_dir).with_given(url.to_string()));
|
||||
return Ok(VerbatimUrl::parse_path(url, working_dir).with_given(url.to_string()));
|
||||
}
|
||||
|
||||
Ok(VerbatimUrl::from_absolute_path(url)
|
||||
Ok(VerbatimUrl::parse_absolute_path(url)
|
||||
.map_err(|err| Pep508Error {
|
||||
message: Pep508ErrorSource::UrlError(err),
|
||||
start,
|
||||
|
|
|
@ -5,7 +5,7 @@ use std::path::{Component, Path, PathBuf};
|
|||
|
||||
use once_cell::sync::Lazy;
|
||||
use regex::Regex;
|
||||
use url::Url;
|
||||
use url::{ParseError, Url};
|
||||
|
||||
/// A wrapper around [`Url`] that preserves the original string.
|
||||
#[derive(Debug, Clone, Eq, derivative::Derivative)]
|
||||
|
@ -29,15 +29,26 @@ pub struct VerbatimUrl {
|
|||
|
||||
impl VerbatimUrl {
|
||||
/// Parse a URL from a string, expanding any environment variables.
|
||||
pub fn parse(given: impl AsRef<str>) -> Result<Self, VerbatimUrlError> {
|
||||
let url = Url::parse(&expand_env_vars(given.as_ref(), true))
|
||||
.map_err(|err| VerbatimUrlError::Url(given.as_ref().to_owned(), err))?;
|
||||
pub fn parse(given: impl AsRef<str>) -> Result<Self, ParseError> {
|
||||
let url = Url::parse(&expand_env_vars(given.as_ref(), true))?;
|
||||
Ok(Self { url, given: None })
|
||||
}
|
||||
|
||||
/// Create a [`VerbatimUrl`] from a [`Url`].
|
||||
pub fn from_url(url: Url) -> Self {
|
||||
Self { url, given: None }
|
||||
}
|
||||
|
||||
/// Create a [`VerbatimUrl`] from a file path.
|
||||
pub fn from_path(path: impl AsRef<Path>) -> Self {
|
||||
let path = normalize_path(path.as_ref());
|
||||
let url = Url::from_file_path(path).expect("path is absolute");
|
||||
Self { url, given: None }
|
||||
}
|
||||
|
||||
/// Parse a URL from an absolute or relative path.
|
||||
#[cfg(feature = "non-pep508-extensions")] // PEP 508 arguably only allows absolute file URLs.
|
||||
pub fn from_path(path: impl AsRef<str>, working_dir: impl AsRef<Path>) -> Self {
|
||||
pub fn parse_path(path: impl AsRef<str>, working_dir: impl AsRef<Path>) -> Self {
|
||||
// Expand any environment variables.
|
||||
let path = PathBuf::from(expand_env_vars(path.as_ref(), false).as_ref());
|
||||
|
||||
|
@ -58,7 +69,7 @@ impl VerbatimUrl {
|
|||
}
|
||||
|
||||
/// Parse a URL from an absolute path.
|
||||
pub fn from_absolute_path(path: impl AsRef<str>) -> Result<Self, VerbatimUrlError> {
|
||||
pub fn parse_absolute_path(path: impl AsRef<str>) -> Result<Self, VerbatimUrlError> {
|
||||
// Expand any environment variables.
|
||||
let path = PathBuf::from(expand_env_vars(path.as_ref(), false).as_ref());
|
||||
|
||||
|
@ -115,7 +126,9 @@ impl std::str::FromStr for VerbatimUrl {
|
|||
type Err = VerbatimUrlError;
|
||||
|
||||
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
||||
Self::parse(s).map(|url| url.with_given(s.to_owned()))
|
||||
Self::parse(s)
|
||||
.map(|url| url.with_given(s.to_owned()))
|
||||
.map_err(|e| VerbatimUrlError::Url(s.to_owned(), e))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -138,7 +151,7 @@ impl Deref for VerbatimUrl {
|
|||
pub enum VerbatimUrlError {
|
||||
/// Failed to parse a URL.
|
||||
#[error("{0}")]
|
||||
Url(String, #[source] url::ParseError),
|
||||
Url(String, #[source] ParseError),
|
||||
|
||||
/// Received a relative path, but no working directory was provided.
|
||||
#[error("relative path without a working directory: {0}")]
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue