diff --git a/crates/uv/src/commands/publish.rs b/crates/uv/src/commands/publish.rs index 88dcdf684245..9fc781a77720 100644 --- a/crates/uv/src/commands/publish.rs +++ b/crates/uv/src/commands/publish.rs @@ -21,12 +21,12 @@ use uv_warnings::warn_user_once; pub(crate) async fn publish( paths: Vec, - publish_url: Url, + mut publish_url: Url, trusted_publishing: TrustedPublishing, keyring_provider: KeyringProviderType, allow_insecure_host: &[TrustedHost], - username: Option, - password: Option, + mut username: Option, + mut password: Option, check_url: Option, cache: &Cache, connectivity: Connectivity, @@ -44,6 +44,27 @@ pub(crate) async fn publish( n => writeln!(printer.stderr(), "Publishing {n} files {publish_url}")?, } + // Support reading username and password from the URL, for symmetry with the index API. + if let Some(url_password) = publish_url.password() { + if password.is_some() { + bail!("The password can't be set both in the publish URL and in the CLI"); + } + password = Some(url_password.to_string()); + publish_url + .set_password(None) + .expect("Failed to clear publish URL password"); + } + + if !publish_url.username().is_empty() { + if username.is_some() { + bail!("The username can't be set both in the publish URL and in the CLI"); + } + username = Some(publish_url.username().to_string()); + publish_url + .set_username("") + .expect("Failed to clear publish URL username"); + } + // * For the uploads themselves, we roll our own retries due to // https://github.com/seanmonstar/reqwest/issues/2416, but for trusted publishing, we want // the default retries.