diff --git a/crates/uv/src/commands/publish.rs b/crates/uv/src/commands/publish.rs index dea625cba..2e5facb90 100644 --- a/crates/uv/src/commands/publish.rs +++ b/crates/uv/src/commands/publish.rs @@ -11,7 +11,6 @@ use uv_cache::Cache; use uv_client::{AuthIntegration, BaseClient, BaseClientBuilder, RegistryClientBuilder}; use uv_configuration::{KeyringProviderType, TrustedPublishing}; use uv_distribution_types::{IndexCapabilities, IndexLocations, IndexUrl}; -use uv_pep508::VerbatimUrl; use uv_publish::{ CheckUrlClient, FormMetadata, PublishError, TrustedPublishResult, check_trusted_publishing, files_for_publishing, upload, @@ -75,16 +74,15 @@ pub(crate) async fn publish( .publish_url .clone() .with_context(|| format!("Index is missing a publish URL: `{index_name}`"))?; - let check_url = index.url.clone(); - (publish_url, Some(check_url)) - } else if token_store.is_known_url(&publish_url) { - // If the user is publishing to a known index, construct the check URL from the publish - // URL. - let check_url = check_url.or_else(|| { - infer_check_url(&publish_url) - .inspect(|check_url| debug!("Inferred check URL: {check_url}")) - }); - (publish_url, check_url) + + // pyx has the same behavior as PyPI where uploads of identical + // files + contents are idempotent, so we don't need to pre-check. + if token_store.is_known_url(&publish_url) { + (publish_url, None) + } else { + let check_url = index.url.clone(); + (publish_url, Some(check_url)) + } } else { (publish_url, check_url) }; @@ -439,50 +437,6 @@ fn prompt_username_and_password() -> Result<(Option, Option)> { Ok((Some(username), Some(password))) } -/// Construct a Simple Index URL from a publish URL, if possible. -/// -/// Matches against a publish URL of the form `/v1/upload/{workspace}/{registry}` and returns -/// `/simple/{workspace}/{registry}`. -fn infer_check_url(publish_url: &DisplaySafeUrl) -> Option { - let mut segments = publish_url.path_segments()?; - - let v1 = segments.next()?; - if v1 != "v1" { - return None; - } - - let upload = segments.next()?; - if upload != "upload" { - return None; - } - - let workspace = segments.next()?; - if workspace.is_empty() { - return None; - } - - let registry = segments.next()?; - if registry.is_empty() { - return None; - } - - // Skip any empty segments (trailing slash handling) - for remaining in segments { - if !remaining.is_empty() { - return None; - } - } - - // Reconstruct the URL with `/simple/{workspace}/{registry}`. - let mut check_url = publish_url.clone(); - { - let mut segments = check_url.path_segments_mut().ok()?; - segments.clear(); - segments.push("simple").push(workspace).push(registry); - } - Some(IndexUrl::from(VerbatimUrl::from(check_url))) -} - #[cfg(test)] mod tests { use super::*; @@ -595,33 +549,4 @@ mod tests { @"The password can't be set both in the publish URL and in the CLI" ); } - - #[test] - fn test_infer_check_url() { - let url = - DisplaySafeUrl::from_str("https://example.com/v1/upload/workspace/registry").unwrap(); - let check_url = infer_check_url(&url); - assert_eq!( - check_url, - Some(IndexUrl::from_str("https://example.com/simple/workspace/registry").unwrap()) - ); - - let url = - DisplaySafeUrl::from_str("https://example.com/v1/upload/workspace/registry/").unwrap(); - let check_url = infer_check_url(&url); - assert_eq!( - check_url, - Some(IndexUrl::from_str("https://example.com/simple/workspace/registry").unwrap()) - ); - - let url = - DisplaySafeUrl::from_str("https://example.com/upload/workspace/registry").unwrap(); - let check_url = infer_check_url(&url); - assert_eq!(check_url, None); - - let url = DisplaySafeUrl::from_str("https://example.com/upload/workspace/registry/package") - .unwrap(); - let check_url = infer_check_url(&url); - assert_eq!(check_url, None); - } }