Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(publish): Support 'publish.timeout' config behind '-Zpublish-timeout' #11230

Merged
merged 3 commits into from
Oct 13, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions crates/cargo-test-support/src/compare.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 &macros {
Expand Down
2 changes: 2 additions & 0 deletions src/cargo/core/features.rs
Original file line number Diff line number Diff line change
Expand Up @@ -686,6 +686,7 @@ unstable_cli_options!(
rustdoc_map: bool = ("Allow passing external documentation mappings to rustdoc"),
separate_nightlies: bool = (HIDDEN),
terminal_width: Option<Option<usize>> = ("Provide a terminal width to rustc for error truncation"),
publish_timeout: bool = ("Enable the `publish.timeout` key in .cargo/config.toml file"),
unstable_options: bool = ("Allow the usage of unstable options"),
// TODO(wcrichto): move scrape example configuration into Cargo.toml before stabilization
// See: https://github.com/rust-lang/cargo/pull/9525#discussion_r728470927
Expand Down Expand Up @@ -930,6 +931,7 @@ impl CliUnstable {
"jobserver-per-rustc" => self.jobserver_per_rustc = parse_empty(k, v)?,
"host-config" => self.host_config = parse_empty(k, v)?,
"target-applies-to-host" => self.target_applies_to_host = parse_empty(k, v)?,
"publish-timeout" => self.publish_timeout = parse_empty(k, v)?,
"features" => {
// `-Z features` has been stabilized since 1.51,
// but `-Z features=compare` is still allowed for convenience
Expand Down
81 changes: 81 additions & 0 deletions src/cargo/ops/registry.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -183,6 +185,19 @@ pub fn publish(ws: &Workspace<'_>, opts: &PublishOpts<'_>) -> CargoResult<()> {
reg_ids.original,
opts.dry_run,
)?;
if !opts.dry_run {
const DEFAULT_TIMEOUT: u64 = 0;
let timeout = if opts.config.cli_unstable().publish_timeout {
let timeout: Option<u64> = opts.config.get("publish.timeout")?;
timeout.unwrap_or(DEFAULT_TIMEOUT)
} else {
DEFAULT_TIMEOUT
};
if 0 < timeout {
let timeout = std::time::Duration::from_secs(timeout);
wait_for_publish(opts.config, reg_ids.original, pkg, timeout)?;
}
}

Ok(())
}
Expand Down Expand Up @@ -374,6 +389,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
Expand Down
18 changes: 18 additions & 0 deletions src/doc/src/reference/unstable.md
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,7 @@ Each new feature described below should explain how to use it.
* [credential-process](#credential-process) — Adds support for fetching registry tokens from an external authentication program.
* [`cargo logout`](#cargo-logout) — Adds the `logout` command to remove the currently saved registry token.
* [sparse-registry](#sparse-registry) — Adds support for fetching from static-file HTTP registries (`sparse+`)
* [publish-timeout](#publish-timeout) — Controls the timeout between uploading the crate and being available in the index

### allow-features

Expand Down Expand Up @@ -841,6 +842,23 @@ crates, which can save significant time and bandwidth.

The format of the sparse index is identical to a checkout of a git-based index.

### publish-timeout
* Tracking Issue: [11222](https://github.com/rust-lang/cargo/issues/11222)

The `publish.timeout` key in a config file can be used to control how long
`cargo publish` waits between posting a package to the registry and it being
available in the local index.

A timeout of `0` prevents any checks from occurring.

It requires the `-Zpublish-timeout` command-line options to be set.

```toml
# config.toml
[publish]
timeout = 300 # in seconds
```

### credential-process
* Tracking Issue: [#8933](https://github.com/rust-lang/cargo/issues/8933)
* RFC: [#2730](https://github.com/rust-lang/rfcs/pull/2730)
Expand Down
Loading