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..848439c 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"); } @@ -416,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 @@ -478,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 { @@ -498,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 { 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(