From 0de9925f550cc3ec0ae874580344f9eccbf95094 Mon Sep 17 00:00:00 2001 From: Marijn Suijten Date: Wed, 1 May 2024 17:03:04 +0200 Subject: [PATCH 1/3] Allow publishing to crates with a `publish = ["custom-registry"]` set --- src/cli/main.rs | 1 + src/command/changelog.rs | 8 +++++++- src/command/mod.rs | 3 ++- src/command/release/mod.rs | 12 ++++++++++-- src/context.rs | 3 +++ src/traverse.rs | 18 ++++++++++++++---- 6 files changed, 37 insertions(+), 8 deletions(-) diff --git a/src/cli/main.rs b/src/cli/main.rs index 937de44..2a6ce1d 100644 --- a/src/cli/main.rs +++ b/src/cli/main.rs @@ -34,6 +34,7 @@ fn main() -> anyhow::Result<()> { dependencies: !no_dependencies, generator_segments: names_to_segment_selection(&without)?, capitalize_commit, + registry: None, // TODO: remove from args? not useful for a changelog }, crates, )? diff --git a/src/command/changelog.rs b/src/command/changelog.rs index 0f27131..46ed144 100644 --- a/src/command/changelog.rs +++ b/src/command/changelog.rs @@ -23,7 +23,13 @@ pub fn changelog(opts: Options, crates: Vec) -> anyhow::Result<()> { } = opts; let bump_spec = if dependencies { BumpSpec::Auto } else { BumpSpec::Keep }; let force_history_segmentation = false; - let ctx = crate::Context::new(crates.clone(), force_history_segmentation, bump_spec, bump_spec)?; + let ctx = crate::Context::new( + crates.clone(), + force_history_segmentation, + bump_spec, + bump_spec, + opts.registry.clone(), + )?; let crates: Vec<_> = { crate::traverse::dependencies( &ctx, diff --git a/src/command/mod.rs b/src/command/mod.rs index 13cbd7f..ed05263 100644 --- a/src/command/mod.rs +++ b/src/command/mod.rs @@ -36,7 +36,7 @@ pub use release_impl::release; pub mod changelog { use crate::changelog::section::segment; - #[derive(Debug, Clone, Copy)] + #[derive(Debug, Clone)] pub struct Options { pub dry_run: bool, pub dependencies: bool, @@ -46,6 +46,7 @@ pub mod changelog { pub generator_segments: segment::Selection, pub no_links: bool, pub capitalize_commit: bool, + pub registry: Option, } } #[path = "changelog.rs"] diff --git a/src/command/release/mod.rs b/src/command/release/mod.rs index 2bfca8b..15ee486 100644 --- a/src/command/release/mod.rs +++ b/src/command/release/mod.rs @@ -33,8 +33,9 @@ impl Context { bump_dependencies: BumpSpec, changelog: bool, changelog_links: bool, + registry: Option, ) -> anyhow::Result { - let base = crate::Context::new(crate_names, changelog, bump, bump_dependencies)?; + let base = crate::Context::new(crate_names, changelog, bump, bump_dependencies, registry)?; let changelog_links = if changelog_links { crate::git::remote_url(&base.repo)?.map_or(Linkables::AsText, |url| Linkables::AsLinks { repository_url: url.into(), @@ -69,7 +70,14 @@ pub fn release(opts: Options, crates: Vec, bump: BumpSpec, bump_dependen ); } - let ctx = Context::new(crates, bump, bump_dependencies, allow_changelog, opts.changelog_links)?; + let ctx = Context::new( + crates, + bump, + bump_dependencies, + allow_changelog, + opts.changelog_links, + opts.registry.clone(), + )?; if !ctx.base.crates_index.exists() { log::warn!("Crates.io index doesn't exist. Consider using --update-crates-index to help determining if release versions are published already"); } diff --git a/src/context.rs b/src/context.rs index 3e63cd3..b3ca25b 100644 --- a/src/context.rs +++ b/src/context.rs @@ -14,6 +14,7 @@ pub struct Context { pub history: Option, pub bump: BumpSpec, pub bump_dependencies: BumpSpec, + pub registry: Option, } impl Context { @@ -22,6 +23,7 @@ impl Context { force_history_segmentation: bool, bump: BumpSpec, bump_dependencies: BumpSpec, + registry: Option, ) -> anyhow::Result { let meta = cargo_metadata::MetadataCommand::new().exec()?; let root = meta.workspace_root.clone(); @@ -42,6 +44,7 @@ impl Context { history, bump, bump_dependencies, + registry, }) } diff --git a/src/traverse.rs b/src/traverse.rs index d328203..293d260 100644 --- a/src/traverse.rs +++ b/src/traverse.rs @@ -183,7 +183,7 @@ pub fn dependencies( crates_this_round.push(Dependency { package, kind: dependency::Kind::UserSelection, - mode: if package_may_be_published(package) { + mode: if package_may_be_published(package, ctx.registry.as_deref()) { dependency::Mode::ToBePublished { adjustment: VersionAdjustment::Changed { change: user_package_change, @@ -262,7 +262,7 @@ fn forward_propagate_breaking_changes_for_manifest_updates<'meta>( .workspace_members .iter() .map(|wmid| package_by_id(&ctx.meta, wmid)) - .filter(|p| package_may_be_published(p)) // will publish, non-publishing ones need no safety bumps + .filter(|p| package_may_be_published(p, ctx.registry.as_deref())) // will publish, non-publishing ones need no safety bumps .collect(); let mut set_to_expand_from = &backing; let mut seen = BTreeSet::default(); @@ -340,8 +340,18 @@ fn forward_propagate_breaking_changes_for_manifest_updates<'meta>( Ok(()) } -fn package_may_be_published(p: &Package) -> bool { - p.publish.is_none() +fn package_may_be_published(p: &Package, registry: Option<&str>) -> bool { + match &p.publish { + // Empty vec seems to be the translation of `publish = false` in Cargo.toml + Some(registries) if registries.is_empty() => false, + Some(registries) => match registry { + Some(registry) => registries.iter().any(|r| r == registry), + // TODO: The user didn't specify any registry on the cmdline, assume they want to publish anything + None => true, + }, + // TODO: Only do this if registry was unset, or equals the default crates-io registry? + None => true, + } } fn forward_propagate_breaking_changes_for_publishing( From 81306eb68cca0ad5205db667e81721345ba7f325 Mon Sep 17 00:00:00 2001 From: Marijn Suijten Date: Thu, 2 May 2024 11:13:52 +0200 Subject: [PATCH 2/3] release: Return timeout error (results in a warning) if crate doesn't show up in the index --- src/command/release/mod.rs | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/src/command/release/mod.rs b/src/command/release/mod.rs index 15ee486..9732f92 100644 --- a/src/command/release/mod.rs +++ b/src/command/release/mod.rs @@ -486,7 +486,12 @@ fn wait_for_release( let sleep_time = std::time::Duration::from_secs(1); let crate_version = crate_version.to_string(); - log::info!("Waiting for '{} v{}' to arrive in index…", crate_.name, crate_version); + log::info!( + "Waiting for '{} v{}' to arrive in index for {:.0?}…", + crate_.name, + crate_version, + timeout + ); let mut crates_index = crates_index::GitIndex::new_cargo_default()?; let mut attempt = 0; while start.elapsed() < timeout { @@ -506,13 +511,17 @@ fn wait_for_release( .rev() .any(|version| version.version() == crate_version) { - break; + return Ok(()); } std::thread::sleep(sleep_time); log::info!("attempt {}", attempt); } - Ok(()) + Err(anyhow::anyhow!( + "Timed out waiting for'{} v{}' to arrive in the index", + crate_.name, + crate_version + )) } enum WriteMode { From 20f6310f065c9fd397c5d75a212d86b811de8144 Mon Sep 17 00:00:00 2001 From: Marijn Suijten Date: Thu, 2 May 2024 11:30:27 +0200 Subject: [PATCH 3/3] Debug-print `anyhow` error so that we see the stacktrace, useful for `crate_index::Error::Git`'s `#[from]` --- src/command/release/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/command/release/mod.rs b/src/command/release/mod.rs index 9732f92..848439c 100644 --- a/src/command/release/mod.rs +++ b/src/command/release/mod.rs @@ -424,7 +424,7 @@ fn perform_release(ctx: &Context, options: Options, crates: &[Dependency<'_>]) - if let Some((crate_, version)) = successful_publishees_and_version.last() { if let Err(err) = wait_for_release(crate_, version, options.clone()) { log::warn!( - "Failed to wait for crates-index update - trying to publish '{} v{}' anyway: {}.", + "Failed to wait for crates-index update - trying to publish '{} v{}' anyway: {:?}.", publishee.name, new_version, err