diff --git a/doc/book/src/reference/config.md b/doc/book/src/reference/config.md index a6389adc03f..fc4d4487f88 100644 --- a/doc/book/src/reference/config.md +++ b/doc/book/src/reference/config.md @@ -152,11 +152,13 @@ rpath = false # Sets the rpath linking option. [resolver] lockfile-path = "…" # Overrides the path used for incompatible-rust-versions = "allow" # Specifies how resolver reacts to these +incompatible-publish-age = "deny" # Specifies how resolver treats recently published versions [registries.] # registries other than crates.io index = "…" # URL of the registry index token = "…" # authentication token for the registry credential-provider = "cargo:token" # The credential provider for this registry. +min-publish-age = "7 days" # Override `registry.global-min-publish-age` for this registry [registries.crates-io] protocol = "sparse" # The protocol to use to access crates.io. @@ -166,6 +168,8 @@ default = "…" # name of the default registry token = "…" # authentication token for crates.io credential-provider = "cargo:token" # The credential provider for crates.io. global-credential-providers = ["cargo:token"] # The credential providers to use by default. +min-publish-age = "7 days" # Override `registry.global-min-publish-age` for crates.io +global-min-publish-age = "7 days" # The time span allowed for registry packages to use by default. [source.] # source definition and replacement replace-with = "…" # replace this source with the given named source @@ -1154,6 +1158,23 @@ See the [resolver](resolver.md#rust-version) chapter for more details. > - `allow` is supported on any version > - `fallback` is respected as of 1.84 +#### `resolver.incompatible-publish-age` +* Type: string +* Default: `"deny"` +* Environment: `CARGO_RESOLVER_INCOMPATIBLE_PUBLISH_AGE` + +When resolving the version of a dependency, +specify the behavior for versions with a `pubtime` (if present) +that is incompatible with `registry.min-publish-age`. +Values include: + +- `allow`: treat pubtime-incompatible versions like any other version +- `deny`: ignore pubtime-incompatible versions unless they already exist in the lock file + +See the [resolver](resolver.md#publish-age) chapter for more details. + +> **MSRV:** Respected as of 1.99+ + ### `[registries]` The `[registries]` table is used for specifying additional [registries]. It @@ -1193,6 +1214,26 @@ If the value exists in the [`[credential-alias]`](#credential-alias) table, the See [Registry Authentication](registry-authentication.md) for more information. +#### `registries..min-publish-age` +* Type: string +* Default: [`registry.global-min-publish-age`](#registryglobal-min-publish-age) +* Environment: `CARGO_REGISTRIES__MIN_PUBLISH_AGE` + +Specifies the minimum timespan since a version's `pubtime` that may be +considered for [`resolver.incompatible-publish-age`] for packages from this +registry. If not set, [`registry.global-min-publish-age`](#registryglobal-min-publish-age) will be used. + +Will be ignored if the registry does not support this. + +It supports the following values: + +- An integer followed by "seconds", "minutes", "hours", "days", "weeks", or "months" +- `"0"` to allow all packages + +Generally, `"0"`, `"N days"`, and `"N weeks"` will be used. + +> **MSRV:** Respected as of 1.99+ + #### `registries.crates-io.protocol` * Type: string * Default: `"sparse"` @@ -1242,6 +1283,24 @@ If the value exists in the `[credential-alias]` table, the alias will be used. See [Registry Authentication](registry-authentication.md) for more information. +#### `registry.min-publish-age` +* Type: string +* Default: [`registry.global-min-publish-age`](#registryglobal-min-publish-age) +* Environment: `CARGO_REGISTRY_MIN_PUBLISH_AGE` + +Specifies the minimum timespan since a version's `pubtime` that it may be +considered for [`resolver.incompatible-publish-age`] for packages from crates.io. +If not set, [`registry.global-min-publish-age`](#registryglobal-min-publish-age) will be used. + +It supports the following values: + +- An integer followed by "seconds", "minutes", "hours", "days", "weeks", or "months" +- `"0"` to allow all packages + +Generally, `"0"`, `"N days"`, and `"N weeks"` will be used. + +> **MSRV:** Respected as of 1.99+ + #### `registry.token` * Type: string * Default: none @@ -1268,6 +1327,25 @@ referenced here by its alias. See [Registry Authentication](registry-authentication.md) for more information. +#### `registry.global-min-publish-age` +* Type: string +* Default: `"0"` +* Environment: `CARGO_REGISTRY_GLOBAL_MIN_PUBLISH_AGE` + +Specifies the global minimum timespan since a version's `pubtime` that it may +be considered for [`resolver.incompatible-publish-age`] for packages. +If `min-publish-age` is not set for a specific registry using +`registries..min-publish-age`, Cargo will use this minimum publish age. + +It supports the following values: + +- An integer followed by "seconds", "minutes", "hours", "days", "weeks", or "months" +- `"0"` to allow all packages + +Generally, `"0"`, `"N days"`, and `"N weeks"` will be used. + +> **MSRV:** Respected as of 1.99+ + ### `[source]` The `[source]` table defines the registry sources available. See [Source @@ -1555,3 +1633,4 @@ Report progress to the terminal emulator for display in places like the task bar [crates.io]: https://crates.io/ [target triple]: ../appendix/glossary.md#target '"target" (glossary)' [``]: ../appendix/glossary.md#target '"target" (glossary)' +[`resolver.incompatible-publish-age`]: config.md#resolverincompatible-publish-age diff --git a/doc/book/src/reference/environment-variables.md b/doc/book/src/reference/environment-variables.md index df1b180a097..46d8264c298 100644 --- a/doc/book/src/reference/environment-variables.md +++ b/doc/book/src/reference/environment-variables.md @@ -131,11 +131,15 @@ In summary, the supported environment variables are: * `CARGO_PROFILE__STRIP` --- Controls stripping of symbols and/or debuginfos, see [`profile..strip`]. * `CARGO_REGISTRIES__CREDENTIAL_PROVIDER` --- Credential provider for a registry, see [`registries..credential-provider`]. * `CARGO_REGISTRIES__INDEX` --- URL of a registry index, see [`registries..index`]. +* `CARGO_REGISTRIES__MIN_PUBLISH_AGE` --- Minimum publish age for packages from a registry, see [`registries..min-publish-age`]. * `CARGO_REGISTRIES__TOKEN` --- Authentication token of a registry, see [`registries..token`]. * `CARGO_REGISTRY_CREDENTIAL_PROVIDER` --- Credential provider for [crates.io], see [`registry.credential-provider`]. * `CARGO_REGISTRY_DEFAULT` --- Default registry for the `--registry` flag, see [`registry.default`]. * `CARGO_REGISTRY_GLOBAL_CREDENTIAL_PROVIDERS` --- Credential providers for registries that do not have a specific provider defined. See [`registry.global-credential-providers`]. +* `CARGO_REGISTRY_GLOBAL_MIN_PUBLISH_AGE` --- Default minimum publish age for packages from registries, see [`registry.global-min-publish-age`]. +* `CARGO_REGISTRY_MIN_PUBLISH_AGE` --- Minimum publish age for packages from [crates.io], see [`registry.min-publish-age`]. * `CARGO_REGISTRY_TOKEN` --- Authentication token for [crates.io], see [`registry.token`]. +* `CARGO_RESOLVER_INCOMPATIBLE_PUBLISH_AGE` --- How recently published versions are treated during dependency resolution, see [`resolver.incompatible-publish-age`]. * `CARGO_TARGET__LINKER` --- The linker to use, see [`target..linker`]. The triple must be [converted to uppercase and underscores](config.md#environment-variables). * `CARGO_TARGET__RUNNER` --- The executable runner, see [`target..runner`]. * `CARGO_TARGET__RUSTFLAGS` --- Extra `rustc` flags for a target, see [`target..rustflags`]. @@ -198,12 +202,16 @@ In summary, the supported environment variables are: [`profile..rpath`]: config.md#profilenamerpath [`profile..split-debuginfo`]: config.md#profilenamesplit-debuginfo [`profile..strip`]: config.md#profilenamestrip +[`resolver.incompatible-publish-age`]: config.md#resolverincompatible-publish-age [`registries..credential-provider`]: config.md#registriesnamecredential-provider [`registries..index`]: config.md#registriesnameindex +[`registries..min-publish-age`]: config.md#registriesnamemin-publish-age [`registries..token`]: config.md#registriesnametoken [`registry.credential-provider`]: config.md#registrycredential-provider [`registry.default`]: config.md#registrydefault [`registry.global-credential-providers`]: config.md#registryglobal-credential-providers +[`registry.global-min-publish-age`]: config.md#registryglobal-min-publish-age +[`registry.min-publish-age`]: config.md#registrymin-publish-age [`registry.token`]: config.md#registrytoken [`target..linker`]: config.md#targettriplelinker [`target..runner`]: config.md#targettriplerunner diff --git a/doc/book/src/reference/resolver.md b/doc/book/src/reference/resolver.md index ad6956dcd70..8a08bb0138b 100644 --- a/doc/book/src/reference/resolver.md +++ b/doc/book/src/reference/resolver.md @@ -310,6 +310,20 @@ the resolver will need to pick one version that works in both cases and that wou [Rust version]: rust-version.md [`resolver.incompatible-rust-versions`]: config.md#resolverincompatible-rust-versions +### Publish age + +Versions with a publish time newer than the configured [`min-publish-age`][`registry.global-min-publish-age`] +are considered pubtime-incompatible. +When [`resolver.incompatible-publish-age`] is set to `deny`, +the resolver will ignore these versions +unless they already exist in the `Cargo.lock` file. +Setting the config to `allow` would disable the check, +which if combined with `cargo update --precise`, +cargo would pull in a specific version and its transitive dependencies. + +[`registry.global-min-publish-age`]: config.md#registryglobal-min-publish-age +[`resolver.incompatible-publish-age`]: config.md#resolverincompatible-publish-age + ### Features For the purpose of generating `Cargo.lock`, the resolver builds the dependency diff --git a/doc/book/src/reference/unstable.md b/doc/book/src/reference/unstable.md index 8766f7693b7..0b4f73288bf 100644 --- a/doc/book/src/reference/unstable.md +++ b/doc/book/src/reference/unstable.md @@ -80,7 +80,6 @@ Each new feature described below should explain how to use it. * [update-breaking](#update-breaking) --- Allows upgrading to breaking versions with `update --breaking` * [feature-unification](#feature-unification) --- Enable new feature unification modes in workspaces * [lockfile-publish-time](#lockfile-publish-time) --- Limit resolver to packages older than the specified time - * [min-publish-age](#min-publish-age) --- Filters out dependency versions published more recently than a configured minimum age. * Output behavior * [artifact-dir](#artifact-dir) --- Adds a directory where artifacts are copied to. * [build-dir-new-layout](#build-dir-new-layout) --- Enables the new build-dir filesystem layout @@ -2093,121 +2092,6 @@ option: hint-msrv = true ``` -## min-publish-age - -* Tracking Issue: [#17009](https://github.com/rust-lang/cargo/issues/17009) -* RFC: [#3923](https://github.com/rust-lang/rfcs/pull/3923) - -The `-Zmin-publish-age` feature allows users to specify a minimum age for -dependency versions. When specified, Cargo won't use a version of a registry -crate that is newer than the minimum age, with a way to override for exceptions -like urgent security fixes. - -For example, in your `/.cargo/config.toml`: - -```toml -[registry] -global-min-publish-age = "14 days" -``` - -### Added to Configuration - -The following will be added to Cargo's configuration format: - -```toml -[resolver] -incompatible-publish-age = "deny" # Specifies how resolver reacts to these - -[registries.] -min-publish-age = "..." # Override `registry.global-min-publish-age` for this registry - -[registry] -min-publish-age = "..." # Override `registry.global-min-publish-age` for crates.io -global-min-publish-age = "0" # Minimum time span allowed for packages from this registry -``` - -#### `resolver.incompatible-publish-age` - -* Type: String -* Default: `"deny"` -* Environment: `CARGO_RESOLVER_INCOMPATIBLE_PUBLISH_AGE` - -When resolving the version of a dependency, -specify the behavior for versions with a `pubtime` (if present) -that is incompatible with `registry.min-publish-age`. -Values include: - -- `allow`: treat pubtime-incompatible versions like any other version -- `deny`: ignore pubtime-incompatible versions unless they already exist in the lock file - -#### `registries..min-publish-age` - -* Type: String -* Default: none -* Environment: `CARGO_REGISTRIES__MIN_PUBLISH_AGE` - -Specifies the minimum timespan since a version's `pubtime` that it may be -considered for `resolver.incompatible-publish-age` for packages from this -registry. If not set, `registry.global-min-publish-age` will be used. - -Will be ignored if the registry does not support this. - -It supports the following values: - -- An integer followed by "seconds", "minutes", "hours", "days", "weeks", or "months" -- `"0"` to allow all packages - -#### `registry.min-publish-age` - -* Type: String -* Default: none -* Environment: `CARGO_REGISTRY_MIN_PUBLISH_AGE` - -Specifies the minimum timespan since a version's `pubtime` that it may be -considered for `resolver.incompatible-publish-age` for packages from crates.io. -If not set, `registry.global-min-publish-age` will be used. - -It supports the following values: - -- An integer followed by "seconds", "minutes", "hours", "days", "weeks", or "months" -- `"0"` to allow all packages - -Generally, `"0"`, `"N days"`, and `"N weeks"` will be used. - -#### `registry.global-min-publish-age` - -* Type: String -* Default: `"0"` -* Environment: `CARGO_REGISTRY_GLOBAL_MIN_PUBLISH_AGE` - -Specifies the global minimum timespan since a version's `pubtime` that it may -be considered for `resolver.incompatible-publish-age` for packages. -If `min-publish-age` is not set for a specific registry using -`registries..min-publish-age`, Cargo will use this minimum publish age. - -It supports the following values: - -- An integer followed by "seconds", "minutes", "hours", "days", "weeks", or "months" -- `"0"` to allow all packages - -### Added to Resolver - -The following will be added to the [resolver chapter] as a sibling section to -"Yanked versions": - -> "Pubtime-incompatible versions" -> -> Versions with a publish time newer than the configured `min-publish-age` -> are considered pubtime-incompatible. -> When `resolver.incompatible-publish-age` is set to `deny`, -> the resolver will ignore these versions -> unless they already exist in the `Cargo.lock` file. -> Setting the config to `allow` would disable the check, -> which if combined with `cargo update --precise`, -> cargo would pull in a specific version and its transitive dependencies. - -[resolver chapter]: ../reference/resolver.md - # Stabilized and removed features ## Compile progress @@ -2502,3 +2386,9 @@ Support for `resolver.lockfile-path` config field has been stabilized in Rust 1. ## warnings The `build.warnings` config field has been stabilized in Rust 1.97. + +## min-publish-age + +Minimum publish-age configuration for dependency resolution was stabilized in Rust 1.99. +See the [minimum publish-age configuration](config.md#registryglobal-min-publish-age) +and [resolver behavior](resolver.md#publish-age) for more information. diff --git a/src/resolver/version_prefs.rs b/src/resolver/version_prefs.rs index ddfe2f63563..6ec5bed2960 100644 --- a/src/resolver/version_prefs.rs +++ b/src/resolver/version_prefs.rs @@ -173,7 +173,6 @@ impl PublishAgePolicy { /// /// Returns `None` when either meets /// - /// * the `-Zmin-publish-age` gate is off /// * the resolver is configured to allow pubtime-incompatible versions /// * no threshold is configured at all pub fn new(now: Option, gctx: &GlobalContext) -> CargoResult> { @@ -194,10 +193,6 @@ impl PublishAgePolicy { now: Option, gctx: &GlobalContext, ) -> CargoResult> { - if !gctx.cli_unstable().min_publish_age { - return Ok(None); - } - let parse = |key: &str, config: Option| -> CargoResult { let Some(config) = config else { return Ok(MinPublishAge::Unset); diff --git a/src/workspace/features.rs b/src/workspace/features.rs index 3eb25add58e..f29b7c372de 100644 --- a/src/workspace/features.rs +++ b/src/workspace/features.rs @@ -907,7 +907,6 @@ unstable_cli_options!( hint_msrv: bool = ("Enable passing `package.rust-version` to rustc for lints"), host_config: bool = ("Enable the `[host]` section in the .cargo/config.toml file"), json_target_spec: bool = ("Enable `.json` target spec files"), - min_publish_age: bool = ("Enable the `min-publish-age` configuration for dependency version age filtering"), minimal_versions: bool = ("Resolve minimal dependency versions instead of maximum"), msrv_policy: bool = ("Enable rust-version aware policy within cargo"), mtime_on_use: bool = ("Configure Cargo to update the mtime of used files"), @@ -1023,6 +1022,9 @@ const STABILIZED_LOCKFILE_PATH: &str = "The `lockfile-path` config key is now al const STABILIZED_WARNINGS: &str = "The `build.warnings` config key is now always available"; +const STABILIZED_MIN_PUBLISH_AGE: &str = + "The `min-publish-age` configuration is now always available."; + fn deserialize_comma_separated_list<'de, D>( deserializer: D, ) -> Result>, D::Error> @@ -1423,6 +1425,7 @@ impl CliUnstable { "config-include" => stabilized_warn(k, "1.93", STABILIZED_CONFIG_INCLUDE), "lockfile-path" => stabilized_warn(k, "1.97", STABILIZED_LOCKFILE_PATH), "warnings" => stabilized_warn(k, "1.97", STABILIZED_WARNINGS), + "min-publish-age" => stabilized_warn(k, "1.99", STABILIZED_MIN_PUBLISH_AGE), // Unstable features // Sorted alphabetically: @@ -1461,7 +1464,6 @@ impl CliUnstable { } "host-config" => self.host_config = parse_empty(k, v)?, "json-target-spec" => self.json_target_spec = parse_empty(k, v)?, - "min-publish-age" => self.min_publish_age = parse_empty(k, v)?, "hint-msrv" => self.hint_msrv = parse_empty(k, v)?, "next-lockfile-bump" => self.next_lockfile_bump = parse_empty(k, v)?, "minimal-versions" => self.minimal_versions = parse_empty(k, v)?, diff --git a/src/workspace/workspace.rs b/src/workspace/workspace.rs index 98b4e6d9d10..976dad96ffb 100644 --- a/src/workspace/workspace.rs +++ b/src/workspace/workspace.rs @@ -358,15 +358,6 @@ impl<'gctx> Workspace<'gctx> { .warn("ignoring `resolver.feature-unification` without `-Zfeature-unification`")?; }; - if !self.gctx().cli_unstable().min_publish_age { - if config.incompatible_publish_age.is_some() { - self.gctx().shell().warn( - "ignoring `resolver.incompatible-publish-age` without `-Zmin-publish-age`", - )?; - } - warn_unused_min_publish_age(self.gctx())?; - } - if let Some(lockfile_path) = config.lockfile_path { // Reserve the ability to add templates in the future. let replacements: [(&str, &str); 0] = []; @@ -2099,38 +2090,6 @@ impl WorkspaceRootConfig { } } -fn warn_unused_min_publish_age(gctx: &GlobalContext) -> CargoResult<()> { - if gctx - .get::>("registry.global-min-publish-age")? - .is_some() - { - gctx.shell() - .warn("ignoring `registry.global-min-publish-age` without `-Zmin-publish-age`")?; - } - - if gctx - .get::>("registry.min-publish-age")? - .is_some() - { - gctx.shell() - .warn("ignoring `registry.min-publish-age` without `-Zmin-publish-age`")?; - } - - if let Some(context::ConfigValue::Table(registries, _)) = gctx.values()?.get("registries") { - for (name, val) in registries { - if let context::ConfigValue::Table(val, _) = val { - if val.contains_key("min-publish-age") { - gctx.shell().warn(format!( - "ignoring `registries.{name}.min-publish-age` without `-Zmin-publish-age`" - ))?; - } - } - } - } - - Ok(()) -} - pub fn resolve_relative_path( label: &str, old_root: &Path, diff --git a/tests/testsuite/cargo/z_help/stdout.term.svg b/tests/testsuite/cargo/z_help/stdout.term.svg index f8f602766b3..120b02e314b 100644 --- a/tests/testsuite/cargo/z_help/stdout.term.svg +++ b/tests/testsuite/cargo/z_help/stdout.term.svg @@ -1,4 +1,4 @@ - +