diff --git a/crates/cargo-test-support/src/compare.rs b/crates/cargo-test-support/src/compare.rs index 6d0e299f5681..9d33904d4304 100644 --- a/crates/cargo-test-support/src/compare.rs +++ b/crates/cargo-test-support/src/compare.rs @@ -197,6 +197,7 @@ fn substitute_macros(input: &str) -> String { ("[MIGRATING]", " Migrating"), ("[EXECUTABLE]", " Executable"), ("[SKIPPING]", " Skipping"), + ("[WAITING]", " Waiting"), ]; let mut result = input.to_owned(); for &(pat, subst) in ¯os { diff --git a/src/cargo/ops/registry.rs b/src/cargo/ops/registry.rs index a94341c16a7a..cd9a8e99b02e 100644 --- a/src/cargo/ops/registry.rs +++ b/src/cargo/ops/registry.rs @@ -18,9 +18,11 @@ use termcolor::Color::Green; use termcolor::ColorSpec; use crate::core::dependency::DepKind; +use crate::core::dependency::Dependency; use crate::core::manifest::ManifestMetadata; use crate::core::resolver::CliFeatures; use crate::core::source::Source; +use crate::core::QueryKind; use crate::core::{Package, SourceId, Workspace}; use crate::ops; use crate::ops::Packages; @@ -183,6 +185,10 @@ pub fn publish(ws: &Workspace<'_>, opts: &PublishOpts<'_>) -> CargoResult<()> { reg_id, opts.dry_run, )?; + if !opts.dry_run { + let timeout = std::time::Duration::from_secs(60); + wait_for_publish(opts.config, reg_id, pkg, timeout)?; + } Ok(()) } @@ -374,6 +380,72 @@ fn transmit( Ok(()) } +fn wait_for_publish( + config: &Config, + registry_src: SourceId, + pkg: &Package, + timeout: std::time::Duration, +) -> CargoResult<()> { + let version_req = format!("={}", pkg.version()); + let mut source = SourceConfigMap::empty(config)?.load(registry_src, &HashSet::new())?; + let source_description = source.describe(); + let query = Dependency::parse(pkg.name(), Some(&version_req), registry_src)?; + + let now = std::time::Instant::now(); + let sleep_time = std::time::Duration::from_secs(1); + let mut logged = false; + loop { + { + let _lock = config.acquire_package_cache_lock()?; + // Force re-fetching the source + // + // As pulling from a git source is expensive, we track when we've done it within the + // process to only do it once, but we are one of the rare cases that needs to do it + // multiple times + config + .updated_sources() + .remove(&source.replaced_source_id()); + source.invalidate_cache(); + let summaries = loop { + // Exact to avoid returning all for path/git + match source.query_vec(&query, QueryKind::Exact) { + std::task::Poll::Ready(res) => { + break res?; + } + std::task::Poll::Pending => source.block_until_ready()?, + } + }; + if !summaries.is_empty() { + break; + } + } + + if timeout < now.elapsed() { + config.shell().warn(format!( + "timed out waiting for `{}` to be in {}", + pkg.name(), + source_description + ))?; + break; + } + + if !logged { + config.shell().status( + "Waiting", + format!( + "on `{}` to propagate to {} (ctrl-c to wait asynchronously)", + pkg.name(), + source_description + ), + )?; + logged = true; + } + std::thread::sleep(sleep_time); + } + + Ok(()) +} + /// Returns the index and token from the config file for the given registry. /// /// `registry` is typically the registry specified on the command-line. If diff --git a/tests/testsuite/artifact_dep.rs b/tests/testsuite/artifact_dep.rs index 8935d80ab6f8..f63320283e5f 100644 --- a/tests/testsuite/artifact_dep.rs +++ b/tests/testsuite/artifact_dep.rs @@ -1920,6 +1920,7 @@ fn publish_artifact_dep() { [UPDATING] [..] [PACKAGING] foo v0.1.0 [..] [UPLOADING] foo v0.1.0 [..] +[UPDATING] [..] ", ) .run(); diff --git a/tests/testsuite/credential_process.rs b/tests/testsuite/credential_process.rs index 0939592458be..5c706b14544f 100644 --- a/tests/testsuite/credential_process.rs +++ b/tests/testsuite/credential_process.rs @@ -135,6 +135,7 @@ Only one of these values may be set, remove one or the other to proceed. [UPDATING] [..] [PACKAGING] foo v0.1.0 [..] [UPLOADING] foo v0.1.0 [..] +[UPDATING] [..] ", ) .run(); @@ -208,6 +209,7 @@ fn publish() { [UPDATING] [..] [PACKAGING] foo v0.1.0 [..] [UPLOADING] foo v0.1.0 [..] +[UPDATING] [..] ", ) .run(); diff --git a/tests/testsuite/features_namespaced.rs b/tests/testsuite/features_namespaced.rs index 7d061da5ba9e..d5cdca8ddea5 100644 --- a/tests/testsuite/features_namespaced.rs +++ b/tests/testsuite/features_namespaced.rs @@ -903,6 +903,7 @@ fn publish_no_implicit() { [UPDATING] [..] [PACKAGING] foo v0.1.0 [..] [UPLOADING] foo v0.1.0 [..] +[UPDATING] [..] ", ) .run(); @@ -1029,6 +1030,7 @@ fn publish() { [COMPILING] foo v0.1.0 [..] [FINISHED] [..] [UPLOADING] foo v0.1.0 [..] +[UPDATING] [..] ", ) .run(); diff --git a/tests/testsuite/publish.rs b/tests/testsuite/publish.rs index 231d7539b33e..dec3d6a63a6f 100644 --- a/tests/testsuite/publish.rs +++ b/tests/testsuite/publish.rs @@ -123,6 +123,7 @@ fn simple() { See [..] [PACKAGING] foo v0.0.1 ([CWD]) [UPLOADING] foo v0.0.1 ([CWD]) +[UPDATING] [..] ", ) .run(); @@ -176,6 +177,7 @@ fn old_token_location() { See [..] [PACKAGING] foo v0.0.1 ([CWD]) [UPLOADING] foo v0.0.1 ([CWD]) +[UPDATING] [..] ", ) .run(); @@ -215,7 +217,9 @@ fn simple_with_index() { [..] [..] [..] -[UPLOADING] foo v0.0.1 ([CWD])", +[UPLOADING] foo v0.0.1 ([CWD]) +[UPDATING] [..] +", ) .run(); @@ -410,7 +414,9 @@ fn publish_clean() { [VERIFYING] foo v0.0.1 ([CWD]) [..] [..] -[UPLOADING] foo v0.0.1 ([CWD])", +[UPLOADING] foo v0.0.1 ([CWD]) +[UPDATING] [..] +", ) .run(); @@ -453,7 +459,9 @@ fn publish_in_sub_repo() { [VERIFYING] foo v0.0.1 ([CWD]) [..] [..] -[UPLOADING] foo v0.0.1 ([CWD])", +[UPLOADING] foo v0.0.1 ([CWD]) +[UPDATING] [..] +", ) .run(); @@ -496,7 +504,9 @@ fn publish_when_ignored() { [VERIFYING] foo v0.0.1 ([CWD]) [..] [..] -[UPLOADING] foo v0.0.1 ([CWD])", +[UPLOADING] foo v0.0.1 ([CWD]) +[UPDATING] [..] +", ) .run(); @@ -538,7 +548,9 @@ fn ignore_when_crate_ignored() { [VERIFYING] foo v0.0.1 ([CWD]) [..] [..] -[UPLOADING] foo v0.0.1 ([CWD])", +[UPLOADING] foo v0.0.1 ([CWD]) +[UPDATING] [..] +", ) .run(); @@ -727,7 +739,9 @@ fn publish_allowed_registry() { [VERIFYING] foo v0.0.1 ([CWD]) [..] [..] -[UPLOADING] foo v0.0.1 ([CWD])", +[UPLOADING] foo v0.0.1 ([CWD]) +[UPDATING] `alternative` index +", ) .run(); @@ -789,7 +803,9 @@ fn publish_implicitly_to_only_allowed_registry() { [VERIFYING] foo v0.0.1 ([CWD]) [..] [..] -[UPLOADING] foo v0.0.1 ([CWD])", +[UPLOADING] foo v0.0.1 ([CWD]) +[UPDATING] `alternative` index +", ) .run(); @@ -912,7 +928,9 @@ The registry `alternative` is not listed in the `publish` value in Cargo.toml. [VERIFYING] foo v0.0.1 ([CWD]) [..] [..] -[UPLOADING] foo v0.0.1 ([CWD])", +[UPLOADING] foo v0.0.1 ([CWD]) +[UPDATING] crates.io index +", ) .run(); } @@ -958,6 +976,7 @@ fn publish_with_select_features() { [..] [..] [UPLOADING] foo v0.0.1 ([CWD]) +[UPDATING] crates.io index ", ) .run(); @@ -1004,6 +1023,7 @@ fn publish_with_all_features() { [..] [..] [UPLOADING] foo v0.0.1 ([CWD]) +[UPDATING] crates.io index ", ) .run(); @@ -1112,7 +1132,9 @@ fn publish_with_patch() { [..] [..] [..] -[UPLOADING] foo v0.0.1 ([CWD])", +[UPLOADING] foo v0.0.1 ([CWD]) +[UPDATING] crates.io index +", ) .run(); @@ -1316,7 +1338,9 @@ fn publish_git_with_version() { [..] [..] [..] -[UPLOADING] foo v0.1.0 ([CWD])", +[UPLOADING] foo v0.1.0 ([CWD]) +[UPDATING] crates.io index +", ) .run(); @@ -1443,6 +1467,7 @@ fn publish_dev_dep_no_version() { [UPDATING] [..] [PACKAGING] foo v0.1.0 [..] [UPLOADING] foo v0.1.0 [..] +[UPDATING] crates.io index ", ) .run(); @@ -1526,6 +1551,7 @@ fn credentials_ambiguous_filename() { [..] [..] [UPLOADING] foo v0.0.1 [..] +[UPDATING] crates.io index ", ) .run(); @@ -1934,6 +1960,7 @@ fn in_package_workspace() { See [..] [PACKAGING] li v0.0.1 ([CWD]/li) [UPLOADING] li v0.0.1 ([CWD]/li) +[UPDATING] crates.io index ", ) .run(); @@ -2039,6 +2066,7 @@ fn in_package_workspace_with_members_with_features_old() { See [..] [PACKAGING] li v0.0.1 ([CWD]/li) [UPLOADING] li v0.0.1 ([CWD]/li) +[UPDATING] crates.io index ", ) .run(); @@ -2129,6 +2157,7 @@ fn in_virtual_workspace_with_p() { See [..] [PACKAGING] li v0.0.1 ([CWD]/li) [UPLOADING] li v0.0.1 ([CWD]/li) +[UPDATING] crates.io index ", ) .run(); @@ -2313,7 +2342,9 @@ fn http_api_not_noop() { [VERIFYING] foo v0.0.1 ([CWD]) [..] [..] -[UPLOADING] foo v0.0.1 ([CWD])", +[UPLOADING] foo v0.0.1 ([CWD]) +[UPDATING] [..] +", ) .run(); @@ -2339,7 +2370,7 @@ fn http_api_not_noop() { } #[cargo_test] -fn delayed_publish_errors() { +fn wait_for_publish() { // Counter for number of tries before the package is "published" let arc: Arc> = Arc::new(Mutex::new(0)); let arc2 = arc.clone(); @@ -2393,13 +2424,15 @@ fn delayed_publish_errors() { See [..] [PACKAGING] delay v0.0.1 ([CWD]) [UPLOADING] delay v0.0.1 ([CWD]) +[UPDATING] crates.io index +[WAITING] on `delay` to propagate to crates.io index (which is replacing registry `crates-io`) (ctrl-c to wait asynchronously) ", ) .run(); - // Check nothing has touched the responder + // Verify the responder has been pinged let lock = arc2.lock().unwrap(); - assert_eq!(*lock, 0); + assert_eq!(*lock, 2); drop(lock); let p = project() @@ -2417,23 +2450,6 @@ See [..] .file("src/main.rs", "fn main() {}") .build(); - p.cargo("build -Z sparse-registry") - .masquerade_as_nightly_cargo(&["sparse-registry"]) - .with_status(101) - .with_stderr( - "\ -[UPDATING] [..] -[ERROR] no matching package named `delay` found -location searched: registry `crates-io` -required by package `foo v0.0.1 ([..]/foo)` -", - ) - .run(); - - let lock = arc2.lock().unwrap(); - assert_eq!(*lock, 1); - drop(lock); - p.cargo("build -Z sparse-registry") .masquerade_as_nightly_cargo(&["sparse-registry"]) .with_status(0) @@ -2444,7 +2460,7 @@ required by package `foo v0.0.1 ([..]/foo)` /// the responder twice per cargo invocation. If that ever gets changed /// this test will need to be changed accordingly. #[cargo_test] -fn delayed_publish_errors_underscore() { +fn wait_for_publish_underscore() { // Counter for number of tries before the package is "published" let arc: Arc> = Arc::new(Mutex::new(0)); let arc2 = arc.clone(); @@ -2498,13 +2514,16 @@ fn delayed_publish_errors_underscore() { See [..] [PACKAGING] delay_with_underscore v0.0.1 ([CWD]) [UPLOADING] delay_with_underscore v0.0.1 ([CWD]) +[UPDATING] crates.io index +[WAITING] on `delay_with_underscore` to propagate to crates.io index (which is replacing registry `crates-io`) (ctrl-c to wait asynchronously) ", ) .run(); - // Check nothing has touched the responder + // Verify the repsponder has been pinged let lock = arc2.lock().unwrap(); - assert_eq!(*lock, 0); + // NOTE: package names with - or _ hit the responder twice per cargo invocation + assert_eq!(*lock, 3); drop(lock); let p = project() @@ -2522,24 +2541,6 @@ See [..] .file("src/main.rs", "fn main() {}") .build(); - p.cargo("build -Z sparse-registry") - .masquerade_as_nightly_cargo(&["sparse-registry"]) - .with_status(101) - .with_stderr( - "\ -[UPDATING] [..] -[ERROR] no matching package named `delay_with_underscore` found -location searched: registry `crates-io` -required by package `foo v0.0.1 ([..]/foo)` -", - ) - .run(); - - let lock = arc2.lock().unwrap(); - // package names with - or _ hit the responder twice per cargo invocation - assert_eq!(*lock, 2); - drop(lock); - p.cargo("build -Z sparse-registry") .masquerade_as_nightly_cargo(&["sparse-registry"]) .with_status(0) diff --git a/tests/testsuite/source_replacement.rs b/tests/testsuite/source_replacement.rs index 8401cd403ea0..9b87bf34c00b 100644 --- a/tests/testsuite/source_replacement.rs +++ b/tests/testsuite/source_replacement.rs @@ -206,7 +206,8 @@ fn publish_with_replacement() { p.cargo("publish --registry crates-io") .replace_crates_io(crates_io.index_url()) .with_stderr( - "[UPDATING] crates.io index + "\ +[UPDATING] crates.io index [WARNING] manifest has no documentation, homepage or repository. See https://doc.rust-lang.org/cargo/reference/manifest.html#package-metadata for more info. [PACKAGING] foo v0.0.1 ([..]) @@ -217,7 +218,9 @@ See https://doc.rust-lang.org/cargo/reference/manifest.html#package-metadata for [COMPILING] bar v1.0.0 [COMPILING] foo v0.0.1 ([..]foo-0.0.1) [FINISHED] dev [..] -[UPLOADING] foo v0.0.1 ([..])", +[UPLOADING] foo v0.0.1 ([..]) +[UPDATING] crates.io index +", ) .run(); } diff --git a/tests/testsuite/weak_dep_features.rs b/tests/testsuite/weak_dep_features.rs index e0c06d729ccd..30f5de860817 100644 --- a/tests/testsuite/weak_dep_features.rs +++ b/tests/testsuite/weak_dep_features.rs @@ -569,6 +569,7 @@ fn publish() { [COMPILING] foo v0.1.0 [..] [FINISHED] [..] [UPLOADING] foo v0.1.0 [..] +[UPDATING] [..] ", ) .run();