Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 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
21 changes: 18 additions & 3 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions crates/uv-cache-key/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ doctest = false
workspace = true

[dependencies]
uv-redacted = { workspace = true }

hex = { workspace = true }
memchr = { workspace = true }
percent-encoding = { workspace = true }
Expand Down
22 changes: 12 additions & 10 deletions crates/uv-cache-key/src/canonical_url.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ use std::hash::{Hash, Hasher};
use std::ops::Deref;

use url::Url;
use uv_redacted::LogSafeUrl;

use crate::cache_key::{CacheKey, CacheKeyHasher};

Expand All @@ -16,10 +17,10 @@ use crate::cache_key::{CacheKey, CacheKeyHasher};
/// string value of the `Url` it contains. This is intentional, because all fetching should still
/// happen within the context of the original URL.
#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Clone)]
pub struct CanonicalUrl(Url);
pub struct CanonicalUrl(LogSafeUrl);

impl CanonicalUrl {
pub fn new(url: &Url) -> Self {
pub fn new(url: &LogSafeUrl) -> Self {
let mut url = url.clone();

// If the URL cannot be a base, then it's not a valid URL anyway.
Expand All @@ -42,8 +43,8 @@ impl CanonicalUrl {
// almost certainly not using the same case conversion rules that GitHub
// does. (See issue #84)
if url.host_str() == Some("github.com") {
url.set_scheme(url.scheme().to_lowercase().as_str())
.unwrap();
let scheme = url.scheme().to_lowercase();
url.set_scheme(&scheme).unwrap();
let path = url.path().to_lowercase();
url.set_path(&path);
}
Expand All @@ -56,7 +57,8 @@ impl CanonicalUrl {
.is_some_and(|ext| ext.eq_ignore_ascii_case("git"));
if needs_chopping {
let prefix = &prefix[..prefix.len() - 4];
url.set_path(&format!("{prefix}@{suffix}"));
let path = format!("{prefix}@{suffix}");
url.set_path(&path);
}
} else {
// Ex) `git+https://github.com/pypa/sample-namespace-packages.git`
Expand Down Expand Up @@ -97,7 +99,7 @@ impl CanonicalUrl {
}

pub fn parse(url: &str) -> Result<Self, url::ParseError> {
Ok(Self::new(&Url::parse(url)?))
Ok(Self::new(&LogSafeUrl::parse(url)?))
}
}

Expand All @@ -117,7 +119,7 @@ impl Hash for CanonicalUrl {
}
}

impl From<CanonicalUrl> for Url {
impl From<CanonicalUrl> for LogSafeUrl {
fn from(value: CanonicalUrl) -> Self {
value.0
}
Expand All @@ -138,10 +140,10 @@ impl std::fmt::Display for CanonicalUrl {
/// [`CanonicalUrl`] values, but the same [`RepositoryUrl`], since they map to the same
/// resource.
#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Clone)]
pub struct RepositoryUrl(Url);
pub struct RepositoryUrl(LogSafeUrl);

impl RepositoryUrl {
pub fn new(url: &Url) -> Self {
pub fn new(url: &LogSafeUrl) -> Self {
let mut url = CanonicalUrl::new(url).0;

// If a Git URL ends in a reference (like a branch, tag, or commit), remove it.
Expand All @@ -163,7 +165,7 @@ impl RepositoryUrl {
}

pub fn parse(url: &str) -> Result<Self, url::ParseError> {
Ok(Self::new(&Url::parse(url)?))
Ok(Self::new(&LogSafeUrl::parse(url)?))
}
}

Expand Down
2 changes: 1 addition & 1 deletion crates/uv-cache/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ uv-distribution-types = { workspace = true }
uv-fs = { workspace = true, features = ["tokio"] }
uv-normalize = { workspace = true }
uv-pypi-types = { workspace = true }
uv-redacted = { workspace = true }
uv-static = { workspace = true }

clap = { workspace = true, features = ["derive", "env"], optional = true }
Expand All @@ -35,5 +36,4 @@ same-file = { workspace = true }
serde = { workspace = true, features = ["derive"] }
tempfile = { workspace = true }
tracing = { workspace = true }
url = { workspace = true }
walkdir = { workspace = true }
13 changes: 6 additions & 7 deletions crates/uv-cache/src/wheel.rs
Original file line number Diff line number Diff line change
@@ -1,26 +1,25 @@
use std::path::{Path, PathBuf};

use url::Url;

use uv_cache_key::{CanonicalUrl, cache_digest};
use uv_distribution_types::IndexUrl;
use uv_redacted::LogSafeUrl;

/// Cache wheels and their metadata, both from remote wheels and built from source distributions.
#[derive(Debug, Clone)]
pub enum WheelCache<'a> {
/// Either PyPI or an alternative index, which we key by index URL.
Index(&'a IndexUrl),
/// A direct URL dependency, which we key by URL.
Url(&'a Url),
Url(&'a LogSafeUrl),
/// A path dependency, which we key by URL.
Path(&'a Url),
Path(&'a LogSafeUrl),
/// An editable dependency, which we key by URL.
Editable(&'a Url),
Editable(&'a LogSafeUrl),
/// A Git dependency, which we key by URL and SHA.
///
/// Note that this variant only exists for source distributions; wheels can't be delivered
/// through Git.
Git(&'a Url, &'a str),
Git(&'a LogSafeUrl, &'a str),
}

impl WheelCache<'_> {
Expand All @@ -30,7 +29,7 @@ impl WheelCache<'_> {
WheelCache::Index(IndexUrl::Pypi(_)) => WheelCacheKind::Pypi.root(),
WheelCache::Index(url) => WheelCacheKind::Index
.root()
.join(cache_digest(&CanonicalUrl::new(url))),
.join(cache_digest(&CanonicalUrl::new(url.url()))),
WheelCache::Url(url) => WheelCacheKind::Url
.root()
.join(cache_digest(&CanonicalUrl::new(url))),
Expand Down
1 change: 1 addition & 0 deletions crates/uv-cli/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ uv-normalize = { workspace = true }
uv-pep508 = { workspace = true }
uv-pypi-types = { workspace = true }
uv-python = { workspace = true, features = ["clap", "schemars"]}
uv-redacted = { workspace = true }
uv-resolver = { workspace = true, features = ["clap"] }
uv-settings = { workspace = true, features = ["schemars"] }
uv-static = { workspace = true }
Expand Down
4 changes: 2 additions & 2 deletions crates/uv-cli/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ use clap::builder::Styles;
use clap::builder::styling::{AnsiColor, Effects, Style};
use clap::{Args, Parser, Subcommand};

use url::Url;
use uv_cache::CacheArgs;
use uv_configuration::{
ConfigSettingEntry, ExportFormat, IndexStrategy, KeyringProviderType, PackageNameSpecifier,
Expand All @@ -19,6 +18,7 @@ use uv_normalize::{ExtraName, GroupName, PackageName, PipGroupName};
use uv_pep508::{MarkerTree, Requirement};
use uv_pypi_types::VerbatimParsedUrl;
use uv_python::{PythonDownloads, PythonPreference, PythonVersion};
use uv_redacted::LogSafeUrl;
use uv_resolver::{AnnotationStyle, ExcludeNewer, ForkStrategy, PrereleaseMode, ResolutionMode};
use uv_static::EnvVars;
use uv_torch::TorchMode;
Expand Down Expand Up @@ -5838,7 +5838,7 @@ pub struct PublishArgs {
///
/// Defaults to PyPI's publish URL (<https://upload.pypi.org/legacy/>).
#[arg(long, env = EnvVars::UV_PUBLISH_URL)]
pub publish_url: Option<Url>,
pub publish_url: Option<LogSafeUrl>,

/// Check an index URL for existing files to skip duplicate uploads.
///
Expand Down
5 changes: 3 additions & 2 deletions crates/uv-client/src/base_client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ use uv_configuration::{KeyringProviderType, TrustedHost};
use uv_fs::Simplified;
use uv_pep508::MarkerEnvironment;
use uv_platform_tags::Platform;
use uv_redacted::LogSafeUrl;
use uv_static::EnvVars;
use uv_version::version;
use uv_warnings::warn_user_once;
Expand Down Expand Up @@ -407,7 +408,7 @@ enum Security {

impl BaseClient {
/// Selects the appropriate client based on the host's trustworthiness.
pub fn for_host(&self, url: &Url) -> &ClientWithMiddleware {
pub fn for_host(&self, url: &LogSafeUrl) -> &ClientWithMiddleware {
if self.disable_ssl(url) {
&self.dangerous_client
} else {
Expand All @@ -416,7 +417,7 @@ impl BaseClient {
}

/// Returns `true` if the host is trusted to use the insecure client.
pub fn disable_ssl(&self, url: &Url) -> bool {
pub fn disable_ssl(&self, url: &LogSafeUrl) -> bool {
self.allow_insecure_host
.iter()
.any(|allow_insecure_host| allow_insecure_host.matches(url))
Expand Down
7 changes: 4 additions & 3 deletions crates/uv-client/src/cached_client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ use tracing::{Instrument, debug, info_span, instrument, trace, warn};

use uv_cache::{CacheEntry, Freshness};
use uv_fs::write_atomic;
use uv_redacted::LogSafeUrl;

use crate::BaseClient;
use crate::base_client::is_extended_transient_error;
Expand Down Expand Up @@ -481,11 +482,11 @@ impl CachedClient {
cached: DataWithCachePolicy,
new_cache_policy_builder: CachePolicyBuilder,
) -> Result<CachedResponse, Error> {
let url = req.url().clone();
let url = LogSafeUrl::from(req.url().clone());
debug!("Sending revalidation request for: {url}");
let response = self
.0
.for_host(req.url())
.for_host(&url)
.execute(req)
.instrument(info_span!("revalidation_request", url = url.as_str()))
.await
Expand Down Expand Up @@ -521,7 +522,7 @@ impl CachedClient {
&self,
req: Request,
) -> Result<(Response, Option<Box<CachePolicy>>), Error> {
let url = req.url().clone();
let url = LogSafeUrl::from(req.url().clone());
trace!("Sending fresh {} request for {}", req.method(), url);
let cache_policy_builder = CachePolicyBuilder::new(&req);
let response = self
Expand Down
Loading
Loading