From d2a6dcb43e5a666ef629a04abe72c1fdf99b8d71 Mon Sep 17 00:00:00 2001 From: Ojus Chugh Date: Sat, 23 Aug 2025 00:09:09 +0530 Subject: [PATCH] fix(publish): Show remaining packages to be published --- src/cargo/ops/registry/publish.rs | 23 ++++++++++++++++++++--- tests/testsuite/publish.rs | 8 ++++++-- 2 files changed, 26 insertions(+), 5 deletions(-) diff --git a/src/cargo/ops/registry/publish.rs b/src/cargo/ops/registry/publish.rs index ce2117b1e..7e3b758e0 100644 --- a/src/cargo/ops/registry/publish.rs +++ b/src/cargo/ops/registry/publish.rs @@ -210,7 +210,8 @@ pub fn publish(ws: &Workspace<'_>, opts: &PublishOpts<'_>) -> CargoResult<()> { // `b`, and we uploaded `a` and `b` but only confirmed `a`, then on // the following pass through the outer loop nothing will be ready for // upload. - for pkg_id in plan.take_ready() { + let mut ready = plan.take_ready(); + while let Some(pkg_id) = ready.pop_first() { let (pkg, (_features, tarball)) = &pkg_dep_graph.packages[&pkg_id]; opts.gctx.shell().status("Uploading", pkg.package_id())?; @@ -236,6 +237,19 @@ pub fn publish(ws: &Workspace<'_>, opts: &PublishOpts<'_>) -> CargoResult<()> { )?)); } + let workspace_context = || { + let mut remaining = ready.clone(); + remaining.extend(plan.iter()); + if !remaining.is_empty() { + format!( + "\n\nnote: the following crates have not been published yet:\n {}", + remaining.into_iter().join("\n ") + ) + } else { + String::new() + } + }; + transmit( opts.gctx, ws, @@ -244,6 +258,7 @@ pub fn publish(ws: &Workspace<'_>, opts: &PublishOpts<'_>) -> CargoResult<()> { &mut registry, source_ids.original, opts.dry_run, + workspace_context, )?; to_confirm.insert(pkg_id); @@ -632,6 +647,7 @@ fn transmit( registry: &mut Registry, registry_id: SourceId, dry_run: bool, + workspace_context: impl Fn() -> String, ) -> CargoResult<()> { let new_crate = prepare_transmit(gctx, ws, pkg, registry_id)?; @@ -643,10 +659,11 @@ fn transmit( let warnings = registry.publish(&new_crate, tarball).with_context(|| { format!( - "failed to publish {} v{} to registry at {}", + "failed to publish {} v{} to registry at {}{}", pkg.name(), pkg.version(), - registry.host() + registry.host(), + workspace_context() ) })?; diff --git a/tests/testsuite/publish.rs b/tests/testsuite/publish.rs index 4e8b69cca..88fbd7ab4 100644 --- a/tests/testsuite/publish.rs +++ b/tests/testsuite/publish.rs @@ -4474,8 +4474,8 @@ fn workspace_publish_rate_limit_error() { .file("package_c/src/lib.rs", "") .build(); - // This demonstrates the current non-actionable error message - // The user doesn't know which package failed or what packages remain to be published + // This demonstrates the improved error message after the fix + // The user now knows which package failed and what packages remain to be published p.cargo("publish --workspace --no-verify") .replace_crates_io(registry.index_url()) .with_status(101) @@ -4491,6 +4491,10 @@ fn workspace_publish_rate_limit_error() { [UPLOADING] package_a v0.1.0 ([ROOT]/foo/package_a) [ERROR] failed to publish package_a v0.1.0 to registry at http://127.0.0.1:[..]/ +[NOTE] the following crates have not been published yet: + package_b v0.1.0 ([ROOT]/foo/package_b) + package_c v0.1.0 ([ROOT]/foo/package_c) + Caused by: failed to get a 200 OK response, got 429 headers: