mirror of
https://github.com/astral-sh/uv.git
synced 2025-07-07 13:25:00 +00:00
Allow non-file:// paths to serve as --index-url
values (#4524)
## Summary pip allows these with the following logic: ```python if os.path.exists(location): # Is a local path. url = path_to_url(location) path = location elif location.startswith("file:"): # A file: URL. url = location path = url_to_path(location) elif is_url(location): url = location ``` Closes https://github.com/astral-sh/uv/issues/4510. ## Test Plan `cargo run pip install --index-url ../packse/index/simple-html/ example-a-961b4c22 --reinstall --no-cache --no-deps`
This commit is contained in:
parent
3379e4c8c2
commit
e39f5f72fe
1 changed files with 33 additions and 10 deletions
|
@ -1,14 +1,15 @@
|
|||
use std::borrow::Cow;
|
||||
use std::fmt::{Display, Formatter};
|
||||
use std::ops::Deref;
|
||||
use std::path::PathBuf;
|
||||
use std::path::{Path, PathBuf};
|
||||
use std::str::FromStr;
|
||||
|
||||
use itertools::Either;
|
||||
use once_cell::sync::Lazy;
|
||||
use url::Url;
|
||||
use thiserror::Error;
|
||||
use url::{ParseError, Url};
|
||||
|
||||
use pep508_rs::{expand_env_vars, split_scheme, strip_host, Scheme, VerbatimUrl};
|
||||
use pep508_rs::{expand_env_vars, split_scheme, strip_host, Scheme, VerbatimUrl, VerbatimUrlError};
|
||||
use uv_fs::normalize_url_path;
|
||||
|
||||
use crate::Verbatim;
|
||||
|
@ -90,18 +91,40 @@ impl Verbatim for IndexUrl {
|
|||
}
|
||||
}
|
||||
|
||||
/// An error that can occur when parsing an [`IndexUrl`].
|
||||
#[derive(Error, Debug)]
|
||||
pub enum IndexUrlError {
|
||||
#[error(transparent)]
|
||||
Io(#[from] std::io::Error),
|
||||
#[error(transparent)]
|
||||
Url(#[from] ParseError),
|
||||
#[error(transparent)]
|
||||
VerbatimUrl(#[from] VerbatimUrlError),
|
||||
#[error("Index URL must be a valid base URL")]
|
||||
CannotBeABase,
|
||||
}
|
||||
|
||||
impl FromStr for IndexUrl {
|
||||
type Err = url::ParseError;
|
||||
type Err = IndexUrlError;
|
||||
|
||||
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
||||
let url = Url::parse(s)?;
|
||||
let url = VerbatimUrl::from_url(url).with_given(s.to_owned());
|
||||
if *url.raw() == *PYPI_URL {
|
||||
Ok(Self::Pypi(url))
|
||||
} else if url.scheme() == "file" {
|
||||
if let Ok(path) = Path::new(s).canonicalize() {
|
||||
let url = VerbatimUrl::from_path(path)?.with_given(s.to_owned());
|
||||
Ok(Self::Path(url))
|
||||
} else {
|
||||
Ok(Self::Url(url))
|
||||
let url = Url::parse(s)?;
|
||||
if url.cannot_be_a_base() {
|
||||
Err(IndexUrlError::CannotBeABase)
|
||||
} else {
|
||||
let url = VerbatimUrl::from_url(url).with_given(s.to_owned());
|
||||
if *url.raw() == *PYPI_URL {
|
||||
Ok(Self::Pypi(url))
|
||||
} else if url.scheme() == "file" {
|
||||
Ok(Self::Path(url))
|
||||
} else {
|
||||
Ok(Self::Url(url))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue