Skip to content

Commit

Permalink
Review
Browse files Browse the repository at this point in the history
  • Loading branch information
konstin committed Sep 24, 2024
1 parent 23b75d9 commit 82d1351
Show file tree
Hide file tree
Showing 9 changed files with 36 additions and 27 deletions.
1 change: 1 addition & 0 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-cli/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4310,6 +4310,8 @@ pub struct DisplayTreeArgs {
#[derive(Args, Debug)]
pub struct PublishArgs {
/// Paths to the files to upload. Accepts glob expressions.
///
/// Defaults to the `dist` directory.
#[arg(default_value = "dist/*")]
pub files: Vec<String>,

Expand Down
1 change: 0 additions & 1 deletion crates/uv-configuration/src/preview.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
use std::fmt::{Display, Formatter};

#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
#[cfg_attr(feature = "clap", derive(clap::ValueEnum))]
pub enum PreviewMode {
#[default]
Disabled,
Expand Down
1 change: 1 addition & 0 deletions crates/uv-publish/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ krata-tokio-tar = { workspace = true }
python-pkginfo = { workspace = true }
reqwest = { workspace = true }
reqwest-middleware = { workspace = true }
rustc-hash = { workspace = true }
serde = { workspace = true, features = ["derive"] }
serde_json = { workspace = true }
sha2 = { workspace = true }
Expand Down
32 changes: 16 additions & 16 deletions crates/uv-publish/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,9 @@ use reqwest::header::AUTHORIZATION;
use reqwest::multipart::Part;
use reqwest::{Body, Response, StatusCode};
use reqwest_middleware::RequestBuilder;
use rustc_hash::FxHashSet;
use serde::Deserialize;
use sha2::{Digest, Sha256};
use std::collections::HashSet;
use std::io::BufReader;
use std::path::{Path, PathBuf};
use std::{fmt, io};
Expand All @@ -39,7 +39,7 @@ pub enum PublishError {
InvalidFilename(PathBuf),
#[error("Failed to publish: `{}`", _0.user_display())]
PublishPrepare(PathBuf, #[source] PublishPrepareError),
#[error("Failed to publish `{}` to `{}`", _0.user_display(), _1)]
#[error("Failed to publish `{}` to {}", _0.user_display(), _1)]
PublishSend(PathBuf, Url, #[source] PublishSendError),
}

Expand Down Expand Up @@ -71,11 +71,11 @@ pub enum PublishSendError {
StatusNoBody(StatusCode, #[source] reqwest::Error),
#[error("Upload failed with status code {0}: {1}")]
Status(StatusCode, String),
/// The registry returned a "403 Forbidden"
#[error("Incorrect credentials (status code {0}): {1}")]
IncorrectCredentials(StatusCode, String),
/// See inline comment
#[error("The request was redirected, but publishing doesn't support redirect, please use the canonical URL: `{0}`")]
/// The registry returned a "403 Forbidden".
#[error("Permission denied (status code {0}): {1}")]
PermissionDenied(StatusCode, String),
/// See inline comment.
#[error("The request was redirected, but redirects are not allowed when publishing, please use the canonical URL: `{0}`")]
RedirectError(Url),
}

Expand Down Expand Up @@ -177,23 +177,23 @@ impl PublishSendError {
pub fn files_for_publishing(
paths: Vec<String>,
) -> Result<Vec<(PathBuf, DistFilename)>, PublishError> {
let mut seen = HashSet::new();
let mut seen = FxHashSet::default();
let mut files = Vec::new();
for path in paths {
for entry in glob(&path).map_err(|err| PublishError::Pattern(path, err))? {
let entry = entry?;
if !seen.insert(entry.clone()) {
for dist in glob(&path).map_err(|err| PublishError::Pattern(path, err))? {
let dist = dist?;
if !dist.is_file() {
continue;
}
if !entry.is_file() {
if !seen.insert(dist.clone()) {
continue;
}
let Some(filename) = entry.file_name().and_then(|filename| filename.to_str()) else {
let Some(filename) = dist.file_name().and_then(|filename| filename.to_str()) else {
continue;
};
let filename = DistFilename::try_from_normalized_filename(filename)
.ok_or_else(|| PublishError::InvalidFilename(entry.clone()))?;
files.push((entry, filename));
.ok_or_else(|| PublishError::InvalidFilename(dist.clone()))?;
files.push((dist, filename));
}
}
// TODO(konsti): Should we sort those files, e.g. wheels before sdists because they are more
Expand Down Expand Up @@ -495,7 +495,7 @@ async fn handle_response(registry: &Url, response: Response) -> Result<bool, Pub
// Artifactory (https://jfrog.com/artifactory/)
Ok(false)
} else {
Err(PublishSendError::IncorrectCredentials(
Err(PublishSendError::PermissionDenied(
status_code,
PublishSendError::extract_error_message(
upload_error.to_string(),
Expand Down
4 changes: 2 additions & 2 deletions crates/uv/src/commands/publish.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,13 +32,13 @@ pub(crate) async fn publish(
}

let client = BaseClientBuilder::new()
// Don't try cloning the request for retries.
// https://github.com/seanmonstar/reqwest/issues/2416
.retries(0)
.keyring(keyring_provider)
.native_tls(native_tls)
.allow_insecure_host(allow_insecure_host)
// Don't try cloning the request to make an unauthenticated request first.
// https://github.com/seanmonstar/reqwest/issues/2416
.only_authenticated(true)
.build();

Expand All @@ -65,7 +65,7 @@ pub(crate) async fn publish(
writeln!(
printer.stderr(),
"{}",
"File already existed, skipping".dimmed()
"File already exists, skipping".dimmed()
)?;
}
}
Expand Down
2 changes: 1 addition & 1 deletion crates/uv/src/settings.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2470,7 +2470,7 @@ impl PublishSettings {
publish_url: args
.publish_url
.combine(publish_url)
.unwrap_or(Url::parse(PYPI_PUBLISH_URL).unwrap()),
.unwrap_or_else(|| Url::parse(PYPI_PUBLISH_URL).unwrap()),
keyring_provider: args
.keyring_provider
.combine(keyring_provider)
Expand Down
8 changes: 4 additions & 4 deletions crates/uv/tests/publish.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,10 @@ fn username_password_no_longer_supported() {
----- stdout -----
----- stderr -----
warning: `uv.sources` is experimental and may change without warning
warning: `uv publish` is experimental and may change without warning
Publishing 1 file
Uploading ok-1.0.0-py3-none-any.whl ([SIZE])
error: Failed to publish `../../scripts/links/ok-1.0.0-py3-none-any.whl` to `https://upload.pypi.org/legacy/`
error: Failed to publish `../../scripts/links/ok-1.0.0-py3-none-any.whl` to https://upload.pypi.org/legacy/
Caused by: Incorrect credentials (status code 403 Forbidden): 403 Username/Password authentication is no longer supported. Migrate to API Tokens or Trusted Publishers instead. See https://pypi.org/help/#apitoken and https://pypi.org/help/#trusted-publishers
"###
);
Expand All @@ -43,10 +43,10 @@ fn invalid_token() {
----- stdout -----
----- stderr -----
warning: `uv.sources` is experimental and may change without warning
warning: `uv publish` is experimental and may change without warning
Publishing 1 file
Uploading ok-1.0.0-py3-none-any.whl ([SIZE])
error: Failed to publish `../../scripts/links/ok-1.0.0-py3-none-any.whl` to `https://upload.pypi.org/legacy/`
error: Failed to publish `../../scripts/links/ok-1.0.0-py3-none-any.whl` to https://upload.pypi.org/legacy/
Caused by: Incorrect credentials (status code 403 Forbidden): 403 Invalid or non-existent authentication information. See https://pypi.org/help/#invalid-auth for more information.
"###
);
Expand Down
12 changes: 9 additions & 3 deletions docs/reference/cli.md
Original file line number Diff line number Diff line change
Expand Up @@ -6790,7 +6790,9 @@ uv publish [OPTIONS] [FILES]...

<h3 class="cli-reference">Arguments</h3>

<dl class="cli-reference"><dt><code>FILES</code></dt><dd><p>The paths to the files to uploads, as glob expressions</p>
<dl class="cli-reference"><dt><code>FILES</code></dt><dd><p>Paths to the files to upload. Accepts glob expressions.</p>

<p>Defaults to the <code>dist</code> directory.</p>

</dd></dl>

Expand Down Expand Up @@ -6871,7 +6873,11 @@ uv publish [OPTIONS] [FILES]...
</dd><dt><code>--password</code>, <code>-p</code> <i>password</i></dt><dd><p>The password for the upload</p>

<p>May also be set with the <code>UV_PUBLISH_PASSWORD</code> environment variable.</p>
</dd><dt><code>--publish-url</code> <i>publish-url</i></dt><dd><p>The URL to the upload endpoint. Note: This is usually not the same as the index URL.</p>
</dd><dt><code>--publish-url</code> <i>publish-url</i></dt><dd><p>The URL of the upload endpoint.</p>

<p>Note that this typically differs from the index URL.</p>

<p>Defaults to PyPI&#8217;s publish URL (&lt;https://upload.pypi.org/legacy/&gt;).</p>

<p>The default value is publish URL for PyPI (&lt;https://upload.pypi.org/legacy/&gt;).</p>

Expand All @@ -6896,7 +6902,7 @@ uv publish [OPTIONS] [FILES]...

</dd><dt><code>--token</code>, <code>-t</code> <i>token</i></dt><dd><p>The token for the upload.</p>

<p>Using a token is equivalent to using <code>__token__</code> as username and using the token as password.</p>
<p>Using a token is equivalent to passing <code>__token__</code> as <code>--username</code> and the token as <code>--password</code>. password.</p>

<p>May also be set with the <code>UV_PUBLISH_TOKEN</code> environment variable.</p>
</dd><dt><code>--username</code>, <code>-u</code> <i>username</i></dt><dd><p>The username for the upload</p>
Expand Down

0 comments on commit 82d1351

Please sign in to comment.