mirror of
https://github.com/astral-sh/uv.git
synced 2025-11-03 13:14:41 +00:00
Add support for relative URLs in simple metadata responses (#721)
## Summary This PR adds support for relative URLs in the simple JSON responses. We already support relative URLs for HTML responses, but the handling has been consolidated between the two. Similar to index URLs, we now store the base alongside the metadata, and use the base when resolving the URL. Closes #455. ## Test Plan `cargo test` (to test HTML indexes). Separately, I also ran `cargo run -p puffin-cli -- pip-compile requirements.in -n --index-url=http://localhost:3141/packages/pypi/+simple` on the `zb/relative` branch with `packse` running, and forced both HTML and JSON by limiting the `accept` header.
This commit is contained in:
parent
ae83a74309
commit
007f52bb4e
17 changed files with 285 additions and 134 deletions
34
crates/distribution-types/src/base_url.rs
Normal file
34
crates/distribution-types/src/base_url.rs
Normal file
|
|
@ -0,0 +1,34 @@
|
|||
use serde::{Deserialize, Serialize};
|
||||
use url::Url;
|
||||
|
||||
#[derive(Debug, Clone, Hash, Eq, PartialEq, Serialize, Deserialize)]
|
||||
pub struct BaseUrl(Url);
|
||||
|
||||
impl BaseUrl {
|
||||
/// Parse the given URL. If it's relative, join it to the current [`BaseUrl`]. Allows for
|
||||
/// parsing URLs that may be absolute or relative, with a known base URL.
|
||||
pub fn join_relative(&self, url: &str) -> Result<Url, url::ParseError> {
|
||||
match Url::parse(url) {
|
||||
Ok(url) => Ok(url),
|
||||
Err(err) => {
|
||||
if err == url::ParseError::RelativeUrlWithoutBase {
|
||||
self.0.join(url)
|
||||
} else {
|
||||
Err(err)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<Url> for BaseUrl {
|
||||
fn from(url: Url) -> Self {
|
||||
Self(url)
|
||||
}
|
||||
}
|
||||
|
||||
impl std::fmt::Display for BaseUrl {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
self.0.fmt(f)
|
||||
}
|
||||
}
|
||||
|
|
@ -3,12 +3,13 @@ use std::ops::Deref;
|
|||
use std::str::FromStr;
|
||||
|
||||
use once_cell::sync::Lazy;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use url::Url;
|
||||
|
||||
static PYPI_URL: Lazy<Url> = Lazy::new(|| Url::parse("https://pypi.org/simple").unwrap());
|
||||
|
||||
/// The url of an index, newtype'd to avoid mixing it with file urls
|
||||
#[derive(Debug, Clone, Hash, Eq, PartialEq)]
|
||||
/// The url of an index, newtype'd to avoid mixing it with file urls.
|
||||
#[derive(Debug, Clone, Hash, Eq, PartialEq, Serialize, Deserialize)]
|
||||
pub enum IndexUrl {
|
||||
Pypi,
|
||||
Url(Url),
|
||||
|
|
|
|||
|
|
@ -47,6 +47,7 @@ use distribution_filename::WheelFilename;
|
|||
use pep440_rs::Version;
|
||||
use pep508_rs::VerbatimUrl;
|
||||
use puffin_normalize::PackageName;
|
||||
use pypi_types::BaseUrl;
|
||||
use requirements_txt::EditableRequirement;
|
||||
|
||||
pub use crate::any::*;
|
||||
|
|
@ -152,6 +153,7 @@ pub struct RegistryBuiltDist {
|
|||
pub version: Version,
|
||||
pub file: File,
|
||||
pub index: IndexUrl,
|
||||
pub base: BaseUrl,
|
||||
}
|
||||
|
||||
/// A built distribution (wheel) that exists at an arbitrary URL.
|
||||
|
|
@ -178,6 +180,7 @@ pub struct RegistrySourceDist {
|
|||
pub version: Version,
|
||||
pub file: File,
|
||||
pub index: IndexUrl,
|
||||
pub base: BaseUrl,
|
||||
}
|
||||
|
||||
/// A source distribution that exists at an arbitrary URL.
|
||||
|
|
@ -207,7 +210,13 @@ pub struct PathSourceDist {
|
|||
|
||||
impl Dist {
|
||||
/// Create a [`Dist`] for a registry-based distribution.
|
||||
pub fn from_registry(name: PackageName, version: Version, file: File, index: IndexUrl) -> Self {
|
||||
pub fn from_registry(
|
||||
name: PackageName,
|
||||
version: Version,
|
||||
file: File,
|
||||
index: IndexUrl,
|
||||
base: BaseUrl,
|
||||
) -> Self {
|
||||
if Path::new(&file.filename)
|
||||
.extension()
|
||||
.is_some_and(|ext| ext.eq_ignore_ascii_case("whl"))
|
||||
|
|
@ -217,6 +226,7 @@ impl Dist {
|
|||
version,
|
||||
file,
|
||||
index,
|
||||
base,
|
||||
}))
|
||||
} else {
|
||||
Self::Source(SourceDist::Registry(RegistrySourceDist {
|
||||
|
|
@ -224,6 +234,7 @@ impl Dist {
|
|||
version,
|
||||
file,
|
||||
index,
|
||||
base,
|
||||
}))
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue