feat(resolver): Stabilize min-publish-age - #17335
Conversation
To ensure dependencies have had a chance to be scanned, a user can set:
```toml
[registry]
global-min-publish-age = "7 days"
```
To force a critical update through, a user can
```console
$ CARGO_RESOLVER_INCOMPATIBLE_PUBLISH_AGE=allow cargo update -p foo
```
That will be preserved within the lockfile.
To ensure users can observe what is going on and address concerns,
- Locking messages notify of:
- That min-publish-age is in use and what the age is if there is a
single one
- a newer, unpicked version is available and its age
- a version is being used that is incompatible with min-publish-age
(either through `allow` or an unchange dep shown through `-v`)
- Error messages notify of:
- a newer, unpicked version is available and its age
- a compatible version requirement to downgrade to
- how to use `CARGO_RESOLVER_INCOMPATIBLE_PUBLISH_AGE`
Items from the tracking issue:
- `deny` precedence between this and `incompatible-rust-version`: we can
always adjust this over time
- the `registry.min-publish-age` / `registries.*.min-publish-age` precedence rule: mimics credential providers
- `cargo install` behavior
- there was some confusion over what was being stabilized due to edits
that happened during the FCP that weren't noticed
- `resolver` is defined as not affecting `cargo install` which this
preserves, just like `incompatible-rust-version`
- `cargo update --breaking`: this feature is being stabilized first and
the other is being considered for removal (rust-lang#17333)
Fixes rust-lang#17009
|
r? @weihanglo rustbot has assigned @weihanglo. Use Why was this reviewer chosen?The reviewer was selected based on:
|
There was a problem hiding this comment.
Before diving into other aspects of the stabilization, have we got any feedback for this using in CI / production?
|
|
||
| See [Registry Authentication](registry-authentication.md) for more information. | ||
|
|
||
| #### `registry.min-publish-age` |
There was a problem hiding this comment.
This is listed as an unsolved question:
The registry.min-publish-age / registries.min-publish-age precedence rule
[registry]table and[registries.crates-io]is confusing- feat:
-Zmin-publish-age(RFC 3923) #17012 (comment)
Still not sure about the [registry] table. Feel like the table was a mistake and a source of confusion that I'd like to avoid adding any new features to it. Like registry.default can change the default registry but registry.token or registry.min-publish-age is still crates.io only.
There was a problem hiding this comment.
This is the only "soft" blocker I have. I am totally fine that we stabilize this as is.
There was a problem hiding this comment.
Only historical context I've seen so far: #12334 (comment)
There was a problem hiding this comment.
weihanglo#100 has some (LLM-generated, sorry) analysis showing the inconsistency, pretty much matching what I remembered.
|
This PR was rebased onto a different master commit. Here's a range-diff highlighting what actually changed. Rebasing is a normal part of keeping PRs up to date, so no action is needed—this note is just to help reviewers. |
|
☔ The latest upstream changes (possibly #17345) made this pull request unmergeable. Please resolve the merge conflicts. |
As identified at rust-lang#17335 (comment)
### What does this PR try to resolve? As identified at rust-lang#17335 (comment) ### How to test and review this PR?
# `[registry]` vs `[registries.<name>]` per-key semantics Review notes for [rust-lang#17335] (min-publish-age stabilization), comparing how each config key behaves across the two tables. Verified against PR head `7b009184` with repro tests in `tests/testsuite/registry_table_confusion.rs` and the PR's own `tests/testsuite/min_publish_age.rs`. [rust-lang#17335]: rust-lang#17335 (comment) | Key | `[registry]` | `[registries.crates-io]` | `[registries.<alt>]` | Evidence | |---|---|---|---|---| | `token` | works for crates.io; does **not** follow `registry.default` | **silently ignored** (config and `CARGO_REGISTRIES_CRATES_IO_TOKEN` env) | works | `registries_crates_io_token_ignored_for_crates_io`, `registry_token_does_not_follow_registry_default` | | `credential-provider` | works for crates.io | **silently ignored** | works | `registries_crates_io_credential_provider_ignored` | | `secret-key` / `secret-key-subject` | works for crates.io | silently ignored (same code path as `token`) | works | code: `src/util/auth/mod.rs:212` returns `[registry]` for crates.io before any name lookup | | `min-publish-age` (new) | crates.io only; ignored for alt registries even with `registry.default` pointing at them | **honored; overrides `registry.min-publish-age`** | honored | `registry_alt_ignores_min_publish_age`, `registries_crates_io_overrides_registry_default` | | `global-min-publish-age` (new) | fallback for **all** registries | silently ignored (not a `RegistryConfig` field) | silently ignored | code: `src/context/schema.rs:530` | | `protocol` | silently ignored (not a `GlobalRegistryConfig` field) | honored | parsed but unused (`_protocol`) | code: `SourceId::crates_io_is_sparse` reads `registries.crates-io.protocol` only | | `index` | hard error: "no longer supported" | silently ignored (`SourceId::alt_registry` short-circuits `crates-io`) | required; defines the registry | code: `check_registry_index_not_set`, `src/workspace/source_id.rs:296` | | `default` | selects target registry for `publish`/`login`/`owner`/`yank` when `--registry`/`--index` absent | silently ignored | n/a | code: `src/util/command_prelude.rs:919` | | `global-credential-providers` | fallback providers for **all** registries | silently ignored | silently ignored | code: `src/util/auth/mod.rs:57` | Key asymmetries: * `min-publish-age` is the first key where `[registries.crates-io]` both works and overrides its `[registry]` counterpart; for the auth keys, `[registries.crates-io]` is dead config. * Auth resolves crates.io **by URL first** (`is_crates_io()`, `src/util/auth/mod.rs:212`); min-publish-age resolves **by name first** (`alt_registry_key()`, `src/resolver/version_prefs.rs:279`). A named mirror of crates.io's index gets `[registry]` credentials but `registries.<mirror>.min-publish-age`. * `registries.<name>.global-min-publish-age` and `registry.protocol` are silent no-ops — the same "subtle `s` distinction" concern raised in [rust-lang#12334](rust-lang#12334 (comment)).
What does this PR try to resolve?
To ensure dependencies have had a chance to be scanned, a user can set:
To force a critical update through, a user can
$ CARGO_RESOLVER_INCOMPATIBLE_PUBLISH_AGE=allow cargo update -p fooThat will be preserved within the lockfile.
To ensure users can observe what is going on and address concerns,
allowor an unchange dep shown through-v)CARGO_RESOLVER_INCOMPATIBLE_PUBLISH_AGEFixes #17009
How to test and review this PR?
Items from the tracking issue:
denyprecedence between this andincompatible-rust-version: we can always adjust this over timeregistry.min-publish-age/registries.*.min-publish-ageprecedence rule: mimics credential providerscargo installbehaviorresolveris defined as not affectingcargo installwhich this preserves, just likeincompatible-rust-versioncargo update --breaking: this feature is being stabilized first and the other is being considered for removal (fix(update)!: Remove unstable--breaking#17333)