diff --git a/.cargo/config.toml b/.cargo/config.toml
index c4cd35e56bc9..f1a267084187 100644
--- a/.cargo/config.toml
+++ b/.cargo/config.toml
@@ -2,6 +2,7 @@
build-man = "run --package xtask-build-man --"
stale-label = "run --package xtask-stale-label --"
bump-check = "run --package xtask-bump-check --"
+lint-docs = "run --package xtask-lint-docs --"
[env]
# HACK: Until this is stabilized, `snapbox`s polyfill could get confused
diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml
index e680a32d61fa..de81970f67db 100644
--- a/.github/workflows/main.yml
+++ b/.github/workflows/main.yml
@@ -83,6 +83,13 @@ jobs:
- run: rustup update stable && rustup default stable
- run: cargo stale-label
+ lint-docs:
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v4
+ - run: rustup update stable && rustup default stable
+ - run: cargo lint-docs --check
+
# Ensure Cargo.lock is up-to-date
lockfile:
runs-on: ubuntu-latest
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 5920bac277d3..2fec28b78ccf 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,23 +1,235 @@
# Changelog
+## Cargo 1.81 (2024-09-05)
+[34a6a87d...HEAD](https://github.com/rust-lang/cargo/compare/34a6a87d...HEAD)
+
+### Added
+
+### Changed
+
+- ❗️ cargo-package: Disallow `package.license-file` and `package.readme` pointing
+ to non-existent files during packaging.
+- ❗️ Disallow passing `--release`/`--debug` flag along with the `--profile` flag.
+ [#13971](https://github.com/rust-lang/cargo/pull/13971)
+ [#13921](https://github.com/rust-lang/cargo/pull/13921)
+- ❗️ Remove `lib.plugin` key support in Cargo.toml.
+ Rust plugin support has been deprecated for four years and was removed in 1.75.0.
+ [#13902](https://github.com/rust-lang/cargo/pull/13902)
+ [#14038](https://github.com/rust-lang/cargo/pull/14038)
+
+### Fixed
+
+- Fix a proc-macro example from a dependency affecting feature resolution.
+ [#13892](https://github.com/rust-lang/cargo/pull/13892)
+
+### Nightly only
+
+- 🔥 `update-breaking`: Add `--breaking` to `cargo update`,
+ allowing upgrading dependencies to breaking versions.
+ [docs](https://doc.rust-lang.org/nightly/cargo/reference/unstable.html#update-breaking)
+ [#13979](https://github.com/rust-lang/cargo/pull/13979)
+- `--artifact-dir`: Rename `--out-dir` to `--artifact-dir`.
+ The `--out-dir` flag is kept for compatibility
+ and may be removed when the feature gets stabilized.
+ [#13809](https://github.com/rust-lang/cargo/pull/13809)
+- `edition2024`: Ensure unused optional dependencies fire for shadowed dependencies.
+ [#14028](https://github.com/rust-lang/cargo/pull/14028)
+- `-Zcargo-lints`: Add `unknown_lints` to lints list.
+ [#14024](https://github.com/rust-lang/cargo/pull/14024)
+- `-Zcargo-lints`: Add tooling to document lints.
+ [#14025](https://github.com/rust-lang/cargo/pull/14025)
+- `-Zcargo-lints`: Keep lints updated and sorted.
+ [#14030](https://github.com/rust-lang/cargo/pull/14030)
+- cargo-update: Track the behavior of `--precise `.
+ [#14013](https://github.com/rust-lang/cargo/pull/14013)
+
+### Documentation
+
+- contrib: Suggest atomic commits with separate test commits.
+ [#14014](https://github.com/rust-lang/cargo/pull/14014)
+
+### Internal
+
+- Remove the temporary `__CARGO_GITOXIDE_DISABLE_LIST_FILES` environment variable.
+ [#14036](https://github.com/rust-lang/cargo/pull/14036)
+- Update dependencies.
+ [#13995](https://github.com/rust-lang/cargo/pull/13995)
+ [#13998](https://github.com/rust-lang/cargo/pull/13998)
+ [#14037](https://github.com/rust-lang/cargo/pull/14037)
+
## Cargo 1.80 (2024-07-25)
-[b60a1555...HEAD](https://github.com/rust-lang/cargo/compare/b60a1555...HEAD)
+[b60a1555...rust-1.80.0](https://github.com/rust-lang/cargo/compare/b60a1555...rust-1.80.0)
### Added
+- 🎉 Stabilize `-Zcheck-cfg`! This by default enables rustc's checking of
+ conditional compilation at compile time, which verifies that the crate is
+ correctly handling conditional compilation for different target platforms or
+ features. Internally, cargo will be passing a new command line option
+ `--check-cfg` to all rustc and rustdoc invocations.
+
+ A new build script invocation
+ [`cargo::rustc-check-cfg=CHECK_CFG`](https://doc.rust-lang.org/nightly/cargo/reference/build-scripts.html#rustc-check-cfg)
+ is added along with this stabilization, as a way to add custom cfgs to the
+ list of expected cfg names and values.
+
+ If a build script is not an option for your package, Cargo provides a config
+ [`[lints.rust.unexpected_cfgs.check-cfg]`](https://doc.rust-lang.org/nightly/rustc/check-cfg/cargo-specifics.html#check-cfg-in-lintsrust-table)
+ to add known custom cfgs statically.
+
+ ([RFC 3013](https://github.com/rust-lang/rfcs/blob/master/text/3013-conditional-compilation-checking.md))
+ ([docs](https://doc.rust-lang.org/nightly/rustc/check-cfg/cargo-specifics.html))
+ [#13571](https://github.com/rust-lang/cargo/pull/13571)
+ [#13865](https://github.com/rust-lang/cargo/pull/13865)
+ [#13869](https://github.com/rust-lang/cargo/pull/13869)
+ [#13884](https://github.com/rust-lang/cargo/pull/13884)
+ [#13913](https://github.com/rust-lang/cargo/pull/13913)
+ [#13937](https://github.com/rust-lang/cargo/pull/13937)
+ [#13958](https://github.com/rust-lang/cargo/pull/13958)
+
+- 🎉 cargo-update: Allows `--precise` to specify a yanked version of a package,
+ and will update the lockfile accordingly.
+ [#13974](https://github.com/rust-lang/cargo/pull/13974)
+
### Changed
+- ❗️ manifest: Disallow `[badges]` to inherit from `[workspace.package.badges]`.
+ This was considered a bug.
+ Keep in mind that `[badges]` is effectively deprecated.
+ [#13788](https://github.com/rust-lang/cargo/pull/13788)
+- build-script: Suggest old syntax based on MSRV.
+ [#13874](https://github.com/rust-lang/cargo/pull/13874)
+- cargo-add: Avoid escaping double quotes by using string literals.
+ [#14006](https://github.com/rust-lang/cargo/pull/14006)
+- cargo-clean: Performance improvements for cleaning specific packages via `-p` flag.
+ [#13818](https://github.com/rust-lang/cargo/pull/13818)
+- cargo-new: Use `i32` rather than `usize` as the "default integer" in library template.
+ [#13939](https://github.com/rust-lang/cargo/pull/13939)
+- cargo-package: Warn, rather than fail, if a Cargo target is excluded during packaging.
+ [#13713](https://github.com/rust-lang/cargo/pull/13713)
+- manifest: Warn, not error, on unsupported lint tool in the `[lints]` table.
+ [#13833](https://github.com/rust-lang/cargo/pull/13833)
+- perf: Avoid inferring when Cargo targets are known.
+ [#13849](https://github.com/rust-lang/cargo/pull/13849)
+- Populate git information when building Cargo from Rust's source tarball.
+ [#13832](https://github.com/rust-lang/cargo/pull/13832)
+- Improve the error message when deserializing Cargo configuration from partial environment variables.
+ [#13956](https://github.com/rust-lang/cargo/pull/13956)
+
### Fixed
+- resolver: Make path dependencies with the same name stay locked.
+ [#13572](https://github.com/rust-lang/cargo/pull/13572)
+- cargo-add: Preserve file permissions on Unix during `write_atomic`.
+ [#13898](https://github.com/rust-lang/cargo/pull/13898)
+- cargo-clean: Remove symlink directory on Windows.
+ [#13910](https://github.com/rust-lang/cargo/pull/13910)
+- cargo-fix: Don't fix into the standard library.
+ [#13792](https://github.com/rust-lang/cargo/pull/13792)
+- cargo-fix: Support IPv6-only networks.
+ [#13907](https://github.com/rust-lang/cargo/pull/13907)
+- cargo-new: Don't say we're adding to a workspace when a regular package is in the root.
+ [#13987](https://github.com/rust-lang/cargo/pull/13987)
+- cargo-vendor: Silence the warning about forgetting the vendoring.
+ [#13886](https://github.com/rust-lang/cargo/pull/13886)
+- cargo-publish/cargo-vendor: Ensure targets in generated Cargo.toml are in a deterministic order.
+ [#13989](https://github.com/rust-lang/cargo/pull/13989)
+ [#14004](https://github.com/rust-lang/cargo/pull/14004)
+- cargo-credential-libsecret: Load `libsecret` by its `SONAME`, `libsecret-1.so.0`.
+ [#13927](https://github.com/rust-lang/cargo/pull/13927)
+- Don't panic when an alias doesn't include a subcommand.
+ [#13819](https://github.com/rust-lang/cargo/pull/13819)
+- Workaround copying file returning EAGAIN on ZFS on macOS.
+ [#13845](https://github.com/rust-lang/cargo/pull/13845)
+- Fetch specific commits even if the GitHub fast path fails.
+ [#13946](https://github.com/rust-lang/cargo/pull/13946)
+ [#13969](https://github.com/rust-lang/cargo/pull/13969)
+- Distinguish Cargo config from different environment variables that share the same prefix.
+ [#14000](https://github.com/rust-lang/cargo/pull/14000)
+
### Nightly only
- `-Zcargo-lints`: Don't always inherit workspace lints.
[#13812](https://github.com/rust-lang/cargo/pull/13812)
+- `-Zcargo-lints`: Add a test to ensure cap-lints works.
+ [#13829](https://github.com/rust-lang/cargo/pull/13829)
+- `-Zcargo-lints`: Error when unstable lints are specified but not enabled.
+ [#13805](https://github.com/rust-lang/cargo/pull/13805)
+- `-Zcargo-lints`: Add cargo-lints to unstable docs.
+ [#13881](https://github.com/rust-lang/cargo/pull/13881)
+- `-Zcargo-lints`: Refactor cargo lint tests.
+ [#13880](https://github.com/rust-lang/cargo/pull/13880)
+- `-Zcargo-lints`: Remove ability to specify `-` in lint name.
+ [#13837](https://github.com/rust-lang/cargo/pull/13837)
+- `-Zscript`: Remove unstable rejected frontmatter syntax for cargo script.
+ The only allowed frontmatter syntax now is `---`.
+ [#13861](https://github.com/rust-lang/cargo/pull/13861)
+ [#13893](https://github.com/rust-lang/cargo/pull/13893)
+- `-Zbindeps`: Build only the specified artifact library when multiple types are available.
+ [#13842](https://github.com/rust-lang/cargo/pull/13842)
+- `-Zmsrv-policy`: Treat unset MSRV as compatible.
+ [#13791](https://github.com/rust-lang/cargo/pull/13791)
+- `-Zgit`/`-Zgitoxide`: Default configuration to be obtained from both environment variables and Cargo configuration.
+ [#13687](https://github.com/rust-lang/cargo/pull/13687)
+- `-Zpublic-dependency`: Don't lose 'public' when inheriting a dependency.
+ [#13836](https://github.com/rust-lang/cargo/pull/13836)
+- `edition2024`: Disallow ignored `default-features` when inheriting.
+ [#13839](https://github.com/rust-lang/cargo/pull/13839)
+- `edition2024`: Validate crate-types/proc-macro for bin like other Cargo targets.
+ [#13841](https://github.com/rust-lang/cargo/pull/13841)
### Documentation
+- cargo-package: Clarify no guarantee of VCS provenance.
+ [#13984](https://github.com/rust-lang/cargo/pull/13984)
+- cargo-metadata: Clarify dash replacement rule in Cargo target names.
+ [#13887](https://github.com/rust-lang/cargo/pull/13887)
+- config: Fix wrong type of `rustc-flags` in build script overrides.
+ [#13957](https://github.com/rust-lang/cargo/pull/13957)
+- resolver: Add README for `resolver-tests`.
+ [#13977](https://github.com/rust-lang/cargo/pull/13977)
+- contrib: Update UI example code in contributor guide.
+ [#13864](https://github.com/rust-lang/cargo/pull/13864)
+- Fix libcurl proxy documentation link.
+ [#13990](https://github.com/rust-lang/cargo/pull/13990)
+- Add missing `CARGO_MAKEFLAGS` env for plugins.
+ [#13872](https://github.com/rust-lang/cargo/pull/13872)
+- Include CircleCI reference in the Continuous Integration chapter.
+ [#13850](https://github.com/rust-lang/cargo/pull/13850)
+
### Internal
+- ci: Don't check `cargo` against beta channel.
+ [#13827](https://github.com/rust-lang/cargo/pull/13827)
+- test: Set safe.directory for git repo in apache container.
+ [#13920](https://github.com/rust-lang/cargo/pull/13920)
+- test: Silence warnings running embedded unittests.
+ [#13929](https://github.com/rust-lang/cargo/pull/13929)
+- test: Update test formatting due to nightly rustc changes.
+ [#13890](https://github.com/rust-lang/cargo/pull/13890)
+ [#13901](https://github.com/rust-lang/cargo/pull/13901)
+ [#13964](https://github.com/rust-lang/cargo/pull/13964)
+- test: Make `git::use_the_cli` test truly locale independent.
+ [#13935](https://github.com/rust-lang/cargo/pull/13935)
+- cargo-test-support: Transition direct assertions from cargo-test-support to snapbox.
+ [#13980](https://github.com/rust-lang/cargo/pull/13980)
+- cargo-test-support: Auto-redact elapsed time.
+ [#13973](https://github.com/rust-lang/cargo/pull/13973)
+- cargo-test-support: Clean up unnecessary uses of `match_exact`.
+ [#13879](https://github.com/rust-lang/cargo/pull/13879)
+- Split `RecursivePathSource` out of `PathSource`.
+ [#13993](https://github.com/rust-lang/cargo/pull/13993)
+- Adjust custom errors from cert-check due to libgit2 1.8 change.
+ [#13970](https://github.com/rust-lang/cargo/pull/13970)
+- Move diagnostic printing to Shell.
+ [#13813](https://github.com/rust-lang/cargo/pull/13813)
+- Update dependencies.
+ [#13834](https://github.com/rust-lang/cargo/pull/13834)
+ [#13840](https://github.com/rust-lang/cargo/pull/13840)
+ [#13948](https://github.com/rust-lang/cargo/pull/13948)
+ [#13963](https://github.com/rust-lang/cargo/pull/13963)
+ [#13976](https://github.com/rust-lang/cargo/pull/13976)
+
## Cargo 1.79 (2024-06-13)
[2fe739fc...rust-1.79.0](https://github.com/rust-lang/cargo/compare/2fe739fc...rust-1.79.0)
@@ -65,6 +277,8 @@
[#13664](https://github.com/rust-lang/cargo/pull/13664)
- Emit 1.77 build script syntax error only when msrv is incompatible.
[#13808](https://github.com/rust-lang/cargo/pull/13808)
+- Don't warn on `lints.rust.unexpected_cfgs.check-cfg`.
+ [#13925](https://github.com/rust-lang/cargo/pull/13925)
- cargo-init: don't assign `target.name` in Cargo.toml if the value can be inferred.
[#13606](https://github.com/rust-lang/cargo/pull/13606)
- cargo-package: normalize paths in `Cargo.toml`, including replacing `\` with `/`.
@@ -74,6 +288,9 @@
### Fixed
+- Ensure `--config net.git-fetch-with-cli=true` is respected.
+ [#13992](https://github.com/rust-lang/cargo/pull/13992)
+ [#13997](https://github.com/rust-lang/cargo/pull/13997)
- Dont panic when resolving an empty alias.
[#13613](https://github.com/rust-lang/cargo/pull/13613)
- When using `--target`, the default debuginfo strip rule also applies.
@@ -118,6 +335,8 @@
[#13797](https://github.com/rust-lang/cargo/pull/13797)
[#13740](https://github.com/rust-lang/cargo/pull/13740)
[#13801](https://github.com/rust-lang/cargo/pull/13801)
+ [#13852](https://github.com/rust-lang/cargo/pull/13852)
+ [#13853](https://github.com/rust-lang/cargo/pull/13853)
- 🔥 `edition2024`: Add default Edition2024 to resolver v3 (MSRV-aware resolver).
[#13785](https://github.com/rust-lang/cargo/pull/13785)
- `edition2024`: Remove underscore field support in 2024.
@@ -190,6 +409,7 @@
[#13692](https://github.com/rust-lang/cargo/pull/13692)
[#13731](https://github.com/rust-lang/cargo/pull/13731)
[#13760](https://github.com/rust-lang/cargo/pull/13760)
+ [#13950](https://github.com/rust-lang/cargo/pull/13950)
## Cargo 1.78 (2024-05-02)
[7bb7b539...rust-1.78.0](https://github.com/rust-lang/cargo/compare/7bb7b539...rust-1.78.0)
diff --git a/Cargo.lock b/Cargo.lock
index e2a42023b9c6..90a7e3779b3c 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -43,9 +43,9 @@ checksum = "4b46cbb362ab8752921c97e041f5e366ee6297bd428a31275b9fcf1e380f7299"
[[package]]
name = "annotate-snippets"
-version = "0.11.2"
+version = "0.11.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5a5a59f105fb9635e9eebdc1e29d53e764fa5795b9cf899a638a53e61567ef61"
+checksum = "086b0afab3b349e5691143adbfb26983821e3eec4ba4c51957104d372c2e1b7d"
dependencies = [
"anstyle",
"unicode-width",
@@ -53,23 +53,24 @@ dependencies = [
[[package]]
name = "anstream"
-version = "0.6.13"
+version = "0.6.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d96bd03f33fe50a863e394ee9718a706f988b9079b20c3784fb726e7678b62fb"
+checksum = "418c75fa768af9c03be99d17643f93f79bbba589895012a80e3452a19ddda15b"
dependencies = [
"anstyle",
"anstyle-parse",
"anstyle-query",
"anstyle-wincon",
"colorchoice",
+ "is_terminal_polyfill",
"utf8parse",
]
[[package]]
name = "anstyle"
-version = "1.0.6"
+version = "1.0.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8901269c6307e8d93993578286ac0edf7f195079ffff5ebdeea6a59ffb7e36bc"
+checksum = "038dfcf04a5feb68e9c60b21c9625a54c2c0616e79b72b0fd87075a056ae1d1b"
[[package]]
name = "anstyle-lossy"
@@ -123,9 +124,9 @@ dependencies = [
[[package]]
name = "anyhow"
-version = "1.0.82"
+version = "1.0.86"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f538837af36e6f6a9be0faa67f9a314f8119e4e4b5867c6ab40ed60360142519"
+checksum = "b3d1d046238990b9cf5bcde22a3fb3584ee5cf65fb2765f454ed428c7a0063da"
[[package]]
name = "arc-swap"
@@ -265,7 +266,7 @@ dependencies = [
[[package]]
name = "cargo"
-version = "0.81.0"
+version = "0.82.0"
dependencies = [
"annotate-snippets",
"anstream",
@@ -301,7 +302,7 @@ dependencies = [
"ignore",
"im-rc",
"indexmap",
- "itertools 0.12.1",
+ "itertools 0.13.0",
"jobserver",
"lazycell",
"libc",
@@ -412,7 +413,7 @@ version = "0.2.1"
[[package]]
name = "cargo-test-support"
-version = "0.2.1"
+version = "0.2.2"
dependencies = [
"anstream",
"anstyle",
@@ -424,7 +425,7 @@ dependencies = [
"flate2",
"git2",
"glob",
- "itertools 0.12.1",
+ "itertools 0.13.0",
"pasetors",
"regex",
"serde",
@@ -461,7 +462,7 @@ dependencies = [
[[package]]
name = "cargo-util-schemas"
-version = "0.4.0"
+version = "0.5.0"
dependencies = [
"semver",
"serde",
@@ -539,18 +540,18 @@ dependencies = [
[[package]]
name = "clap"
-version = "4.5.4"
+version = "4.5.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "90bc066a67923782aa8515dbaea16946c5bcc5addbd668bb80af688e53e548a0"
+checksum = "a9689a29b593160de5bc4aacab7b5d54fb52231de70122626c178e6a368994c7"
dependencies = [
"clap_builder",
]
[[package]]
name = "clap_builder"
-version = "4.5.2"
+version = "4.5.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ae129e2e766ae0ec03484e609954119f123cc1fe650337e155d03b022f24f7b4"
+checksum = "2e5387378c84f6faa26890ebf9f0a92989f8873d4d380467bcd0d8d8620424df"
dependencies = [
"anstream",
"anstyle",
@@ -2052,6 +2053,12 @@ dependencies = [
"windows-sys 0.52.0",
]
+[[package]]
+name = "is_terminal_polyfill"
+version = "1.70.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f8478577c03552c21db0e2724ffb8986a5ce7af88107e6be5d2ee6e158c12800"
+
[[package]]
name = "itertools"
version = "0.10.5"
@@ -2063,9 +2070,9 @@ dependencies = [
[[package]]
name = "itertools"
-version = "0.12.1"
+version = "0.13.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ba291022dbbd398a455acf126c1e341954079855bc60dfdda641363bd6922569"
+checksum = "413ee7dfc52ee1a4949ceeb7dbc8a33f2d6c088194d9f922fb8318faf1f01186"
dependencies = [
"either",
]
@@ -2129,9 +2136,9 @@ checksum = "884e2677b40cc8c339eaefcb701c32ef1fd2493d71118dc0ca4b6a736c93bd67"
[[package]]
name = "libc"
-version = "0.2.154"
+version = "0.2.155"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ae743338b92ff9146ce83992f766a31066a91a8c84a45e0e9f21e7cf6de6d346"
+checksum = "97b3888a4aecf77e811145cadf6eef5901f4782c53886191b2f693f24761847c"
[[package]]
name = "libdbus-sys"
@@ -2388,9 +2395,9 @@ checksum = "0ab1bc2a289d34bd04a330323ac98a1b4bc82c9d9fcb1e66b63caa84da26b575"
[[package]]
name = "opener"
-version = "0.7.0"
+version = "0.7.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f9901cb49d7fc923b256db329ee26ffed69130bf05d74b9efdd1875c92d6af01"
+checksum = "f8df34be653210fbe9ffaff41d3b92721c56ce82dfee58ee684f9afb5e3a90c0"
dependencies = [
"bstr",
"dbus",
@@ -2741,9 +2748,9 @@ dependencies = [
[[package]]
name = "pulldown-cmark"
-version = "0.10.3"
+version = "0.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "76979bea66e7875e7509c4ec5300112b316af87fa7a252ca91c448b32dfe3993"
+checksum = "8746739f11d39ce5ad5c2520a9b75285310dbfe78c541ccf832d38615765aec0"
dependencies = [
"bitflags 2.5.0",
"memchr",
@@ -2753,9 +2760,9 @@ dependencies = [
[[package]]
name = "pulldown-cmark-escape"
-version = "0.10.0"
+version = "0.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d5d8f9aa0e3cbcfaf8bf00300004ee3b72f74770f9cbac93f6928771f613276b"
+checksum = "007d8adb5ddab6f8e3f491ac63566a7d5002cc7ed73901f72057943fa71ae1ae"
[[package]]
name = "quick-error"
@@ -2851,9 +2858,9 @@ dependencies = [
[[package]]
name = "regex"
-version = "1.10.4"
+version = "1.10.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c117dbdfde9c8308975b6a18d71f3f385c89461f7b3fb054288ecf2a2058ba4c"
+checksum = "b91213439dad192326a0d7c6ee3955910425f441d7038e0d6933b0aec5c4517f"
dependencies = [
"aho-corasick",
"memchr",
@@ -3020,11 +3027,11 @@ dependencies = [
[[package]]
name = "security-framework"
-version = "2.10.0"
+version = "2.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "770452e37cad93e0a50d5abc3990d2bc351c36d0328f86cefec2f2fb206eaef6"
+checksum = "c627723fd09706bacdb5cf41499e95098555af3c3c29d014dc3c458ef6be11c0"
dependencies = [
- "bitflags 1.3.2",
+ "bitflags 2.5.0",
"core-foundation",
"core-foundation-sys",
"libc",
@@ -3033,9 +3040,9 @@ dependencies = [
[[package]]
name = "security-framework-sys"
-version = "2.10.0"
+version = "2.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "41f3cc463c0ef97e11c3461a9d3787412d30e8e7eb907c79180c4a57bf7c04ef"
+checksum = "317936bbbd05227752583946b9e66d7ce3b489f84e11a94a510b4437fef407d7"
dependencies = [
"core-foundation-sys",
"libc",
@@ -3043,9 +3050,9 @@ dependencies = [
[[package]]
name = "semver"
-version = "1.0.22"
+version = "1.0.23"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "92d43fe69e652f3df9bdc2b85b2854a0825b86e4fb76bc44d945137d053639ca"
+checksum = "61697e0a1c7e512e84a621326239844a24d8207b4669b41bc18b32ea5cbf988b"
dependencies = [
"serde",
]
@@ -3059,21 +3066,22 @@ dependencies = [
[[package]]
name = "serde"
-version = "1.0.199"
+version = "1.0.203"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0c9f6e76df036c77cd94996771fb40db98187f096dd0b9af39c6c6e452ba966a"
+checksum = "7253ab4de971e72fb7be983802300c30b5a7f0c2e56fab8abfc6a214307c0094"
dependencies = [
"serde_derive",
]
[[package]]
name = "serde-untagged"
-version = "0.1.5"
+version = "0.1.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6a160535368dfc353348e7eaa299156bd508c60c45a9249725f5f6d370d82a66"
+checksum = "2676ba99bd82f75cae5cbd2c8eda6fa0b8760f18978ea840e980dd5567b5c5b6"
dependencies = [
"erased-serde",
"serde",
+ "typeid",
]
[[package]]
@@ -3088,9 +3096,9 @@ dependencies = [
[[package]]
name = "serde_derive"
-version = "1.0.199"
+version = "1.0.203"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "11bd257a6541e141e42ca6d24ae26f7714887b47e89aa739099104c7e4d3b7fc"
+checksum = "500cbc0ebeb6f46627f50f3f5811ccf6bf00643be300b4c3eabc0ef55dc5b5ba"
dependencies = [
"proc-macro2",
"quote",
@@ -3108,9 +3116,9 @@ dependencies = [
[[package]]
name = "serde_json"
-version = "1.0.116"
+version = "1.0.117"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3e17db7126d17feb94eb3fad46bf1a96b034e8aacbc2e775fe81505f8b0b2813"
+checksum = "455182ea6142b14f93f4bc5320a2b31c1f266b66a4a5c858b013302a5d8cbfc3"
dependencies = [
"itoa 1.0.11",
"ryu",
@@ -3209,9 +3217,9 @@ checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67"
[[package]]
name = "snapbox"
-version = "0.6.7"
+version = "0.6.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "94204b12a4d3550420babdb4148c6639692e4e3e61060866929c5107f208aeb6"
+checksum = "9e5cb88aa548c9514cd7dba04a5d8d80a9464ae6d04a1d203fa7d469c71b75e9"
dependencies = [
"anstream",
"anstyle",
@@ -3222,6 +3230,7 @@ dependencies = [
"filetime",
"normalize-line-endings",
"regex",
+ "serde",
"serde_json",
"similar",
"snapbox-macros",
@@ -3324,9 +3333,9 @@ dependencies = [
[[package]]
name = "tar"
-version = "0.4.40"
+version = "0.4.41"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b16afcea1f22891c49a00c751c7b63b2233284064f11a200fc624137c51e2ddb"
+checksum = "cb797dad5fb5b76fcf519e702f4a589483b5ef06567f160c392832c1f5e44909"
dependencies = [
"filetime",
"libc",
@@ -3356,18 +3365,18 @@ dependencies = [
[[package]]
name = "thiserror"
-version = "1.0.59"
+version = "1.0.61"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f0126ad08bff79f29fc3ae6a55cc72352056dfff61e3ff8bb7129476d44b23aa"
+checksum = "c546c80d6be4bc6a00c0f01730c08df82eaa7a7a61f11d656526506112cc1709"
dependencies = [
"thiserror-impl",
]
[[package]]
name = "thiserror-impl"
-version = "1.0.59"
+version = "1.0.61"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d1cd413b5d558b4c5bf3680e324a6fa5014e7b7c067a51e69dbdf47eb7148b66"
+checksum = "46c3384250002a6d5af4d114f2845d37b57521033f30d5c3f46c4d70e1197533"
dependencies = [
"proc-macro2",
"quote",
@@ -3548,6 +3557,12 @@ dependencies = [
"tracing-log",
]
+[[package]]
+name = "typeid"
+version = "1.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "059d83cc991e7a42fc37bd50941885db0888e34209f8cfd9aab07ddec03bc9cf"
+
[[package]]
name = "typenum"
version = "1.17.0"
@@ -3604,9 +3619,9 @@ dependencies = [
[[package]]
name = "unicode-width"
-version = "0.1.12"
+version = "0.1.13"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "68f5e5f3158ecfd4b8ff6fe086db7c8467a2dfdac97fe420f2b7c4aa97af66d6"
+checksum = "0336d538f7abc86d282a4189614dfaa90810dfc2c6f6427eaf88e16311dd225d"
[[package]]
name = "unicode-xid"
@@ -4021,6 +4036,16 @@ dependencies = [
"tracing-subscriber",
]
+[[package]]
+name = "xtask-lint-docs"
+version = "0.1.0"
+dependencies = [
+ "anyhow",
+ "cargo",
+ "clap",
+ "itertools 0.13.0",
+]
+
[[package]]
name = "xtask-stale-label"
version = "0.0.0"
diff --git a/Cargo.toml b/Cargo.toml
index ae1f13a62abf..ebc6d5f15a2f 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -33,7 +33,7 @@ cargo-platform = { path = "crates/cargo-platform", version = "0.1.5" }
cargo-test-macro = { version = "0.2.0", path = "crates/cargo-test-macro" }
cargo-test-support = { version = "0.2.0", path = "crates/cargo-test-support" }
cargo-util = { version = "0.2.9", path = "crates/cargo-util" }
-cargo-util-schemas = { version = "0.4.0", path = "crates/cargo-util-schemas" }
+cargo-util-schemas = { version = "0.5.0", path = "crates/cargo-util-schemas" }
cargo_metadata = "0.18.1"
clap = "4.5.4"
color-print = "0.3.6"
@@ -57,7 +57,7 @@ humantime = "2.1.0"
ignore = "0.4.22"
im-rc = "15.1.0"
indexmap = "2.2.6"
-itertools = "0.12.1"
+itertools = "0.13.0"
jobserver = "0.1.31"
lazycell = "1.3.0"
libc = "0.2.154"
@@ -74,7 +74,7 @@ pathdiff = "0.2.1"
percent-encoding = "2.3.1"
pkg-config = "0.3.30"
proptest = "1.4.0"
-pulldown-cmark = { version = "0.10.3", default-features = false, features = ["html"] }
+pulldown-cmark = { version = "0.11.0", default-features = false, features = ["html"] }
rand = "0.8.5"
regex = "1.10.4"
rusqlite = { version = "0.31.0", features = ["bundled"] }
@@ -91,7 +91,7 @@ sha1 = "0.10.6"
sha2 = "0.10.8"
shell-escape = "0.1.5"
supports-hyperlinks = "3.0.0"
-snapbox = { version = "0.6.7", features = ["diff", "dir", "term-svg", "regex"] }
+snapbox = { version = "0.6.9", features = ["diff", "dir", "term-svg", "regex", "json"] }
tar = { version = "0.4.40", default-features = false }
tempfile = "3.10.1"
thiserror = "1.0.59"
@@ -125,7 +125,7 @@ self_named_module_files = "warn"
[package]
name = "cargo"
-version = "0.81.0"
+version = "0.82.0"
edition.workspace = true
license.workspace = true
rust-version = "1.78" # MSRV:1
diff --git a/benches/benchsuite/benches/resolve.rs b/benches/benchsuite/benches/resolve.rs
index 89d0212e378c..d798dd6d62bb 100644
--- a/benches/benchsuite/benches/resolve.rs
+++ b/benches/benchsuite/benches/resolve.rs
@@ -33,6 +33,7 @@ fn do_resolve<'gctx>(gctx: &'gctx GlobalContext, ws_root: &Path) -> ResolveInfo<
let force_all_targets = ForceAllTargets::No;
// Do an initial run to download anything necessary so that it does
// not confuse criterion's warmup.
+ let dry_run = false;
let ws_resolve = cargo::ops::resolve_ws_with_opts(
&ws,
&mut target_data,
@@ -41,6 +42,7 @@ fn do_resolve<'gctx>(gctx: &'gctx GlobalContext, ws_root: &Path) -> ResolveInfo<
&specs,
has_dev_units,
force_all_targets,
+ dry_run,
)
.unwrap();
ResolveInfo {
@@ -71,6 +73,7 @@ fn resolve_ws(c: &mut Criterion) {
// iterator once, and we don't want to call `do_resolve` in every
// "step", since that would just be some useless work.
let mut lazy_info = None;
+ let dry_run = false;
group.bench_function(&ws_name, |b| {
let ResolveInfo {
ws,
@@ -91,6 +94,7 @@ fn resolve_ws(c: &mut Criterion) {
specs,
*has_dev_units,
*force_all_targets,
+ dry_run,
)
.unwrap();
})
diff --git a/crates/cargo-test-support/Cargo.toml b/crates/cargo-test-support/Cargo.toml
index 9d6ca7303ef8..a8d5025f8de7 100644
--- a/crates/cargo-test-support/Cargo.toml
+++ b/crates/cargo-test-support/Cargo.toml
@@ -1,6 +1,6 @@
[package]
name = "cargo-test-support"
-version = "0.2.1"
+version = "0.2.2"
edition.workspace = true
rust-version = "1.78" # MSRV:1
license.workspace = true
diff --git a/crates/cargo-test-support/src/compare.rs b/crates/cargo-test-support/src/compare.rs
index 53b752621de8..9a7f93bc557e 100644
--- a/crates/cargo-test-support/src/compare.rs
+++ b/crates/cargo-test-support/src/compare.rs
@@ -36,8 +36,9 @@
//! a problem.
//! - Carriage returns are removed, which can help when running on Windows.
-use crate::diff;
+use crate::cross_compile::try_alternate;
use crate::paths;
+use crate::{diff, rustc_host};
use anyhow::{bail, Context, Result};
use serde_json::Value;
use std::fmt;
@@ -45,6 +46,15 @@ use std::path::Path;
use std::str;
use url::Url;
+/// This makes it easier to write regex replacements that are guaranteed to only
+/// get compiled once
+macro_rules! regex {
+ ($re:literal $(,)?) => {{
+ static RE: std::sync::OnceLock = std::sync::OnceLock::new();
+ RE.get_or_init(|| regex::Regex::new($re).unwrap())
+ }};
+}
+
/// Assertion policy for UI tests
///
/// This emphasizes showing as much content as possible at the cost of more brittleness
@@ -77,21 +87,8 @@ use url::Url;
/// a problem.
/// - Carriage returns are removed, which can help when running on Windows.
pub fn assert_ui() -> snapbox::Assert {
- let root = paths::root();
- // Use `from_file_path` instead of `from_dir_path` so the trailing slash is
- // put in the users output, rather than hidden in the variable
- let root_url = url::Url::from_file_path(&root).unwrap().to_string();
-
let mut subs = snapbox::Redactions::new();
- subs.extend(MIN_LITERAL_REDACTIONS.into_iter().cloned())
- .unwrap();
- subs.insert("[ROOT]", root).unwrap();
- subs.insert("[ROOTURL]", root_url).unwrap();
- subs.insert(
- "[ELAPSED]",
- regex::Regex::new("Finished.*in (?[0-9]+(\\.[0-9]+))s").unwrap(),
- )
- .unwrap();
+ add_common_redactions(&mut subs);
snapbox::Assert::new()
.action_env(snapbox::assert::DEFAULT_ACTION_ENV)
.redact_with(subs)
@@ -129,32 +126,80 @@ pub fn assert_ui() -> snapbox::Assert {
/// a problem.
/// - Carriage returns are removed, which can help when running on Windows.
pub fn assert_e2e() -> snapbox::Assert {
+ let mut subs = snapbox::Redactions::new();
+ add_common_redactions(&mut subs);
+ subs.extend(E2E_LITERAL_REDACTIONS.into_iter().cloned())
+ .unwrap();
+
+ snapbox::Assert::new()
+ .action_env(snapbox::assert::DEFAULT_ACTION_ENV)
+ .redact_with(subs)
+}
+
+fn add_common_redactions(subs: &mut snapbox::Redactions) {
let root = paths::root();
// Use `from_file_path` instead of `from_dir_path` so the trailing slash is
// put in the users output, rather than hidden in the variable
let root_url = url::Url::from_file_path(&root).unwrap().to_string();
- let mut subs = snapbox::Redactions::new();
subs.extend(MIN_LITERAL_REDACTIONS.into_iter().cloned())
.unwrap();
- subs.extend(E2E_LITERAL_REDACTIONS.into_iter().cloned())
- .unwrap();
subs.insert("[ROOT]", root).unwrap();
subs.insert("[ROOTURL]", root_url).unwrap();
+ // For e2e tests
subs.insert(
"[ELAPSED]",
- regex::Regex::new("[FINISHED].*in (?[0-9]+(\\.[0-9]+))s").unwrap(),
+ regex!("[FINISHED].*in (?[0-9]+(\\.[0-9]+))s"),
+ )
+ .unwrap();
+ // for UI tests
+ subs.insert(
+ "[ELAPSED]",
+ regex!("Finished.*in (?[0-9]+(\\.[0-9]+))s"),
+ )
+ .unwrap();
+ // output from libtest
+ subs.insert(
+ "[ELAPSED]",
+ regex!("; finished in (?[0-9]+(\\.[0-9]+))s"),
+ )
+ .unwrap();
+ subs.insert(
+ "[FILE_SIZE]",
+ regex!("(?[0-9]+(\\.[0-9]+)([a-zA-Z]i)?)B"),
+ )
+ .unwrap();
+ subs.insert(
+ "[HASH]",
+ regex!("home/\\.cargo/registry/src/-(?[a-z0-9]+)"),
+ )
+ .unwrap();
+ subs.insert("[HASH]", regex!("/[a-z0-9\\-_]+-(?[0-9a-f]{16})"))
+ .unwrap();
+ subs.insert("[HOST_TARGET]", rustc_host()).unwrap();
+ if let Some(alt_target) = try_alternate() {
+ subs.insert("[ALT_TARGET]", alt_target).unwrap();
+ }
+ subs.insert(
+ "[AVG_ELAPSED]",
+ regex!("(?[0-9]+(\\.[0-9]+)?) ns/iter"),
+ )
+ .unwrap();
+ subs.insert(
+ "[JITTER]",
+ regex!("ns/iter \\(\\+/- (?[0-9]+(\\.[0-9]+)?)\\)"),
)
.unwrap();
- snapbox::Assert::new()
- .action_env(snapbox::assert::DEFAULT_ACTION_ENV)
- .redact_with(subs)
}
static MIN_LITERAL_REDACTIONS: &[(&str, &str)] = &[
("[EXE]", std::env::consts::EXE_SUFFIX),
("[BROKEN_PIPE]", "Broken pipe (os error 32)"),
("[BROKEN_PIPE]", "The pipe is being closed. (os error 232)"),
+ // Unix message for exit status
+ ("[EXIT_STATUS]", "exit status"),
+ // Windows message for exit status
+ ("[EXIT_STATUS]", "exit code"),
];
static E2E_LITERAL_REDACTIONS: &[(&str, &str)] = &[
("[RUNNING]", " Running"),
@@ -176,6 +221,7 @@ static E2E_LITERAL_REDACTIONS: &[(&str, &str)] = &[
("[DIRTY]", " Dirty"),
("[LOCKING]", " Locking"),
("[UPDATING]", " Updating"),
+ ("[UPGRADING]", " Upgrading"),
("[ADDING]", " Adding"),
("[REMOVING]", " Removing"),
("[REMOVED]", " Removed"),
diff --git a/crates/cargo-test-support/src/cross_compile.rs b/crates/cargo-test-support/src/cross_compile.rs
index a2daf882d9dc..beda66165504 100644
--- a/crates/cargo-test-support/src/cross_compile.rs
+++ b/crates/cargo-test-support/src/cross_compile.rs
@@ -209,18 +209,23 @@ pub fn native_arch() -> &'static str {
///
/// Only use this function on tests that check `cross_compile::disabled`.
pub fn alternate() -> &'static str {
+ try_alternate().expect("This test should be gated on cross_compile::disabled.")
+}
+
+/// A possible alternate target-triple to build with.
+pub(crate) fn try_alternate() -> Option<&'static str> {
if cfg!(all(target_os = "macos", target_arch = "aarch64")) {
- "x86_64-apple-darwin"
+ Some("x86_64-apple-darwin")
} else if cfg!(target_os = "macos") {
- "x86_64-apple-ios"
+ Some("x86_64-apple-ios")
} else if cfg!(target_os = "linux") {
- "i686-unknown-linux-gnu"
+ Some("i686-unknown-linux-gnu")
} else if cfg!(all(target_os = "windows", target_env = "msvc")) {
- "i686-pc-windows-msvc"
+ Some("i686-pc-windows-msvc")
} else if cfg!(all(target_os = "windows", target_env = "gnu")) {
- "i686-pc-windows-gnu"
+ Some("i686-pc-windows-gnu")
} else {
- panic!("This test should be gated on cross_compile::disabled.");
+ None
}
}
diff --git a/crates/cargo-test-support/src/lib.rs b/crates/cargo-test-support/src/lib.rs
index 5db67b8ea900..09644298316b 100644
--- a/crates/cargo-test-support/src/lib.rs
+++ b/crates/cargo-test-support/src/lib.rs
@@ -25,6 +25,7 @@ use std::time::{self, Duration};
use anyhow::{bail, Result};
use cargo_util::{is_ci, ProcessBuilder, ProcessError};
+use snapbox::IntoData as _;
use url::Url;
use self::paths::CargoPathExt;
@@ -534,6 +535,8 @@ pub struct Execs {
expect_stdin: Option,
expect_stderr: Option,
expect_exit_code: Option,
+ expect_stdout_data: Option,
+ expect_stderr_data: Option,
expect_stdout_contains: Vec,
expect_stderr_contains: Vec,
expect_stdout_contains_n: Vec<(String, usize)>,
@@ -545,6 +548,7 @@ pub struct Execs {
expect_json: Option,
expect_json_contains_unordered: Option,
stream_output: bool,
+ assert: snapbox::Assert,
}
impl Execs {
@@ -555,6 +559,7 @@ impl Execs {
/// Verifies that stdout is equal to the given lines.
/// See [`compare`] for supported patterns.
+ #[deprecated(note = "replaced with `Execs::with_stdout_data(expected)`")]
pub fn with_stdout(&mut self, expected: S) -> &mut Self {
self.expect_stdout = Some(expected.to_string());
self
@@ -562,11 +567,28 @@ impl Execs {
/// Verifies that stderr is equal to the given lines.
/// See [`compare`] for supported patterns.
+ #[deprecated(note = "replaced with `Execs::with_stderr_data(expected)`")]
pub fn with_stderr(&mut self, expected: S) -> &mut Self {
self.expect_stderr = Some(expected.to_string());
self
}
+ /// Verifies that stdout is equal to the given lines.
+ ///
+ /// See [`compare::assert_e2e`] for assertion details.
+ pub fn with_stdout_data(&mut self, expected: impl snapbox::IntoData) -> &mut Self {
+ self.expect_stdout_data = Some(expected.into_data());
+ self
+ }
+
+ /// Verifies that stderr is equal to the given lines.
+ ///
+ /// See [`compare::assert_e2e`] for assertion details.
+ pub fn with_stderr_data(&mut self, expected: impl snapbox::IntoData) -> &mut Self {
+ self.expect_stderr_data = Some(expected.into_data());
+ self
+ }
+
/// Writes the given lines to stdin.
pub fn with_stdin(&mut self, expected: S) -> &mut Self {
self.expect_stdin = Some(expected.to_string());
@@ -593,6 +615,7 @@ impl Execs {
/// its output.
///
/// See [`compare`] for supported patterns.
+ #[deprecated(note = "replaced with `Execs::with_stdout_data(expected)`")]
pub fn with_stdout_contains(&mut self, expected: S) -> &mut Self {
self.expect_stdout_contains.push(expected.to_string());
self
@@ -602,6 +625,7 @@ impl Execs {
/// its output.
///
/// See [`compare`] for supported patterns.
+ #[deprecated(note = "replaced with `Execs::with_stderr_data(expected)`")]
pub fn with_stderr_contains(&mut self, expected: S) -> &mut Self {
self.expect_stderr_contains.push(expected.to_string());
self
@@ -611,6 +635,7 @@ impl Execs {
/// its output, and should be repeated `number` times.
///
/// See [`compare`] for supported patterns.
+ #[deprecated(note = "replaced with `Execs::with_stdout_data(expected)`")]
pub fn with_stdout_contains_n(&mut self, expected: S, number: usize) -> &mut Self {
self.expect_stdout_contains_n
.push((expected.to_string(), number));
@@ -622,6 +647,7 @@ impl Execs {
/// See [`compare`] for supported patterns.
///
/// See note on [`Self::with_stderr_does_not_contain`].
+ #[deprecated]
pub fn with_stdout_does_not_contain(&mut self, expected: S) -> &mut Self {
self.expect_stdout_not_contains.push(expected.to_string());
self
@@ -636,6 +662,7 @@ impl Execs {
/// your test will pass without verifying the correct behavior. If
/// possible, write the test first so that it fails, and then implement
/// your fix/feature to make it pass.
+ #[deprecated]
pub fn with_stderr_does_not_contain(&mut self, expected: S) -> &mut Self {
self.expect_stderr_not_contains.push(expected.to_string());
self
@@ -645,6 +672,7 @@ impl Execs {
/// ignoring the order of the lines.
///
/// See [`Execs::with_stderr_unordered`] for more details.
+ #[deprecated(note = "replaced with `Execs::with_stdout_data(expected.unordered())`")]
pub fn with_stdout_unordered(&mut self, expected: S) -> &mut Self {
self.expect_stdout_unordered.push(expected.to_string());
self
@@ -671,6 +699,7 @@ impl Execs {
///
/// This will randomly fail if the other crate name is `bar`, and the
/// order changes.
+ #[deprecated(note = "replaced with `Execs::with_stderr_data(expected.unordered())`")]
pub fn with_stderr_unordered(&mut self, expected: S) -> &mut Self {
self.expect_stderr_unordered.push(expected.to_string());
self
@@ -698,6 +727,7 @@ impl Execs {
///
/// Be careful writing the `without` fragments, see note in
/// `with_stderr_does_not_contain`.
+ #[deprecated]
pub fn with_stderr_line_without(
&mut self,
with: &[S],
@@ -730,6 +760,7 @@ impl Execs {
/// - The order of arrays is ignored.
/// - Strings support patterns described in [`compare`].
/// - Use `"{...}"` to match any object.
+ #[deprecated(note = "replaced with `Execs::with_stdout_data(expected.json_lines())`")]
pub fn with_json(&mut self, expected: &str) -> &mut Self {
self.expect_json = Some(expected.to_string());
self
@@ -744,6 +775,7 @@ impl Execs {
/// what you are doing.
///
/// See `with_json` for more detail.
+ #[deprecated]
pub fn with_json_contains_unordered(&mut self, expected: &str) -> &mut Self {
match &mut self.expect_json_contains_unordered {
None => self.expect_json_contains_unordered = Some(expected.to_string()),
@@ -845,6 +877,17 @@ impl Execs {
self
}
+ pub fn overlay_registry(&mut self, url: &Url, path: &str) -> &mut Self {
+ if let Some(ref mut p) = self.process_builder {
+ let env_value = format!("{}={}", url, path);
+ p.env(
+ "__CARGO_TEST_DEPENDENCY_CONFUSION_VULNERABILITY_DO_NOT_USE_THIS",
+ env_value,
+ );
+ }
+ self
+ }
+
pub fn enable_split_debuginfo_packed(&mut self) -> &mut Self {
self.env("CARGO_PROFILE_DEV_SPLIT_DEBUGINFO", "packed")
.env("CARGO_PROFILE_TEST_SPLIT_DEBUGINFO", "packed")
@@ -908,11 +951,14 @@ impl Execs {
}
}
+ #[track_caller]
fn verify_checks_output(&self, stdout: &[u8], stderr: &[u8]) {
if self.expect_exit_code.unwrap_or(0) != 0
&& self.expect_stdout.is_none()
&& self.expect_stdin.is_none()
&& self.expect_stderr.is_none()
+ && self.expect_stdout_data.is_none()
+ && self.expect_stderr_data.is_none()
&& self.expect_stdout_contains.is_empty()
&& self.expect_stderr_contains.is_empty()
&& self.expect_stdout_contains_n.is_empty()
@@ -934,6 +980,7 @@ impl Execs {
}
}
+ #[track_caller]
fn match_process(&self, process: &ProcessBuilder) -> Result {
println!("running {}", process);
let res = if self.stream_output {
@@ -984,6 +1031,7 @@ impl Execs {
}
}
+ #[track_caller]
fn match_output(&self, code: Option, stdout: &[u8], stderr: &[u8]) -> Result<()> {
self.verify_checks_output(stdout, stderr);
let stdout = std::str::from_utf8(stdout).expect("stdout is not utf8");
@@ -1008,6 +1056,24 @@ impl Execs {
if let Some(expect_stderr) = &self.expect_stderr {
compare::match_exact(expect_stderr, stderr, "stderr", stdout, cwd)?;
}
+ if let Some(expect_stdout_data) = &self.expect_stdout_data {
+ if let Err(err) = self.assert.try_eq(
+ Some(&"stdout"),
+ stdout.into_data(),
+ expect_stdout_data.clone(),
+ ) {
+ panic!("{err}")
+ }
+ }
+ if let Some(expect_stderr_data) = &self.expect_stderr_data {
+ if let Err(err) = self.assert.try_eq(
+ Some(&"stderr"),
+ stderr.into_data(),
+ expect_stderr_data.clone(),
+ ) {
+ panic!("{err}")
+ }
+ }
for expect in self.expect_stdout_contains.iter() {
compare::match_contains(expect, stdout, cwd)?;
}
@@ -1060,6 +1126,8 @@ pub fn execs() -> Execs {
expect_stderr: None,
expect_stdin: None,
expect_exit_code: Some(0),
+ expect_stdout_data: None,
+ expect_stderr_data: None,
expect_stdout_contains: Vec::new(),
expect_stderr_contains: Vec::new(),
expect_stdout_contains_n: Vec::new(),
@@ -1071,6 +1139,7 @@ pub fn execs() -> Execs {
expect_json: None,
expect_json_contains_unordered: None,
stream_output: false,
+ assert: compare::assert_e2e(),
}
}
diff --git a/crates/cargo-test-support/src/registry.rs b/crates/cargo-test-support/src/registry.rs
index f8b4b1447822..6ddd59e38a8c 100644
--- a/crates/cargo-test-support/src/registry.rs
+++ b/crates/cargo-test-support/src/registry.rs
@@ -1649,7 +1649,12 @@ impl Package {
/// Returns the path to the compressed package file.
pub fn archive_dst(&self) -> PathBuf {
if self.local {
- registry_path().join(format!("{}-{}.crate", self.name, self.vers))
+ let path = if self.alternative {
+ alt_registry_path()
+ } else {
+ registry_path()
+ };
+ path.join(format!("{}-{}.crate", self.name, self.vers))
} else if self.alternative {
alt_dl_path()
.join(&self.name)
diff --git a/crates/cargo-util-schemas/Cargo.toml b/crates/cargo-util-schemas/Cargo.toml
index 848e235a759c..fbf7ae87ea8d 100644
--- a/crates/cargo-util-schemas/Cargo.toml
+++ b/crates/cargo-util-schemas/Cargo.toml
@@ -1,6 +1,6 @@
[package]
name = "cargo-util-schemas"
-version = "0.4.0"
+version = "0.5.0"
rust-version = "1.78" # MSRV:1
edition.workspace = true
license.workspace = true
diff --git a/crates/cargo-util-schemas/src/manifest/mod.rs b/crates/cargo-util-schemas/src/manifest/mod.rs
index 25df09ba6f76..7ca2de5564dd 100644
--- a/crates/cargo-util-schemas/src/manifest/mod.rs
+++ b/crates/cargo-util-schemas/src/manifest/mod.rs
@@ -1223,7 +1223,6 @@ pub struct TomlTarget {
pub doctest: Option,
pub bench: Option,
pub doc: Option,
- pub plugin: Option,
pub doc_scrape_examples: Option,
pub proc_macro: Option,
#[serde(rename = "proc_macro")]
diff --git a/crates/mdman/src/format/man.rs b/crates/mdman/src/format/man.rs
index edb5c05e34bb..72d45d352774 100644
--- a/crates/mdman/src/format/man.rs
+++ b/crates/mdman/src/format/man.rs
@@ -140,7 +140,7 @@ impl<'e> ManRenderer<'e> {
suppress_paragraph = true;
}
}
- Tag::BlockQuote => {
+ Tag::BlockQuote(_kind) => {
self.flush();
// .RS = move left margin over 3
// .ll = shrink line length
@@ -356,6 +356,8 @@ impl<'e> ManRenderer<'e> {
}
Event::TaskListMarker(_b) => unimplemented!(),
Event::InlineHtml(..) => unimplemented!(),
+ Event::InlineMath(..) => unimplemented!(),
+ Event::DisplayMath(..) => unimplemented!(),
}
}
Ok(())
diff --git a/crates/mdman/src/format/text.rs b/crates/mdman/src/format/text.rs
index 5a858fcc792e..30e01d6faa98 100644
--- a/crates/mdman/src/format/text.rs
+++ b/crates/mdman/src/format/text.rs
@@ -137,7 +137,7 @@ impl<'e> TextRenderer<'e> {
self.indent = (level as usize - 1) * 3 + 1;
}
}
- Tag::BlockQuote => {
+ Tag::BlockQuote(_kind) => {
self.indent += 3;
}
Tag::CodeBlock(_kind) => {
@@ -347,6 +347,8 @@ impl<'e> TextRenderer<'e> {
}
Event::TaskListMarker(_b) => unimplemented!(),
Event::InlineHtml(..) => unimplemented!(),
+ Event::InlineMath(..) => unimplemented!(),
+ Event::DisplayMath(..) => unimplemented!(),
}
}
Ok(())
diff --git a/crates/xtask-bump-check/src/xtask.rs b/crates/xtask-bump-check/src/xtask.rs
index 07148e554f58..e602d5df3a7d 100644
--- a/crates/xtask-bump-check/src/xtask.rs
+++ b/crates/xtask-bump-check/src/xtask.rs
@@ -16,7 +16,6 @@ use std::fs;
use std::task;
use cargo::core::dependency::Dependency;
-use cargo::core::registry::PackageRegistry;
use cargo::core::Package;
use cargo::core::Registry;
use cargo::core::SourceId;
@@ -137,7 +136,7 @@ fn bump_check(args: &clap::ArgMatches, gctx: &cargo::util::GlobalContext) -> Car
let mut needs_bump = Vec::new();
- check_crates_io(gctx, &changed_members, &mut needs_bump)?;
+ check_crates_io(&ws, &changed_members, &mut needs_bump)?;
if let Some(referenced_commit) = referenced_commit.as_ref() {
status(&format!("compare against `{}`", referenced_commit.id()))?;
@@ -385,12 +384,13 @@ fn symmetric_diff<'a>(
///
/// Assumption: We always release a version larger than all existing versions.
fn check_crates_io<'a>(
- gctx: &GlobalContext,
+ ws: &Workspace<'a>,
changed_members: &HashMap<&'a str, &'a Package>,
needs_bump: &mut Vec<&'a Package>,
) -> CargoResult<()> {
+ let gctx = ws.gctx();
let source_id = SourceId::crates_io(gctx)?;
- let mut registry = PackageRegistry::new(gctx)?;
+ let mut registry = ws.package_registry()?;
let _lock = gctx.acquire_package_cache_lock(CacheLockMode::DownloadExclusive)?;
registry.lock_patches();
gctx.shell().status(
diff --git a/crates/xtask-lint-docs/Cargo.toml b/crates/xtask-lint-docs/Cargo.toml
new file mode 100644
index 000000000000..16f15d2efe70
--- /dev/null
+++ b/crates/xtask-lint-docs/Cargo.toml
@@ -0,0 +1,14 @@
+[package]
+name = "xtask-lint-docs"
+version = "0.1.0"
+edition.workspace = true
+publish = false
+
+[dependencies]
+anyhow.workspace = true
+cargo.workspace = true
+clap.workspace = true
+itertools.workspace = true
+
+[lints]
+workspace = true
diff --git a/crates/xtask-lint-docs/src/main.rs b/crates/xtask-lint-docs/src/main.rs
new file mode 100644
index 000000000000..79862d6c4002
--- /dev/null
+++ b/crates/xtask-lint-docs/src/main.rs
@@ -0,0 +1,108 @@
+use cargo::util::command_prelude::{flag, ArgMatchesExt};
+use cargo::util::lints::{Lint, LintLevel};
+use itertools::Itertools;
+use std::fmt::Write;
+use std::path::PathBuf;
+
+fn cli() -> clap::Command {
+ clap::Command::new("xtask-lint-docs").arg(flag("check", "Check that the docs are up-to-date"))
+}
+
+fn main() -> anyhow::Result<()> {
+ let args = cli().get_matches();
+ let check = args.flag("check");
+
+ let mut allow = Vec::new();
+ let mut warn = Vec::new();
+ let mut deny = Vec::new();
+ let mut forbid = Vec::new();
+
+ let mut lint_docs = String::new();
+ for lint in cargo::util::lints::LINTS
+ .iter()
+ .sorted_by_key(|lint| lint.name)
+ {
+ if lint.docs.is_some() {
+ let sectipn = match lint.default_level {
+ LintLevel::Allow => &mut allow,
+ LintLevel::Warn => &mut warn,
+ LintLevel::Deny => &mut deny,
+ LintLevel::Forbid => &mut forbid,
+ };
+ sectipn.push(lint.name);
+ add_lint(lint, &mut lint_docs)?;
+ }
+ }
+
+ let mut buf = String::new();
+ writeln!(buf, "# Lints\n")?;
+ writeln!(
+ buf,
+ "Note: [Cargo's linting system is unstable](unstable.md#lintscargo) and can only be used on nightly toolchains"
+ )?;
+ writeln!(buf)?;
+
+ if !allow.is_empty() {
+ add_level_section(LintLevel::Allow, &allow, &mut buf)?;
+ }
+ if !warn.is_empty() {
+ add_level_section(LintLevel::Warn, &warn, &mut buf)?;
+ }
+ if !deny.is_empty() {
+ add_level_section(LintLevel::Deny, &deny, &mut buf)?;
+ }
+ if !forbid.is_empty() {
+ add_level_section(LintLevel::Forbid, &forbid, &mut buf)?;
+ }
+
+ buf.push_str(&lint_docs);
+
+ if check {
+ let old = std::fs::read_to_string(lint_docs_path())?;
+ if old != buf {
+ anyhow::bail!(
+ "The lints documentation is out-of-date. Run `cargo lint-docs` to update it."
+ );
+ }
+ } else {
+ std::fs::write(lint_docs_path(), buf)?;
+ }
+ Ok(())
+}
+
+fn add_lint(lint: &Lint, buf: &mut String) -> std::fmt::Result {
+ writeln!(buf, "## `{}`", lint.name)?;
+ writeln!(buf, "Set to `{}` by default", lint.default_level)?;
+ writeln!(buf, "{}\n", lint.docs.as_ref().unwrap())
+}
+
+fn add_level_section(level: LintLevel, lint_names: &[&str], buf: &mut String) -> std::fmt::Result {
+ let title = match level {
+ LintLevel::Allow => "Allowed-by-default",
+ LintLevel::Warn => "Warn-by-default",
+ LintLevel::Deny => "Deny-by-default",
+ LintLevel::Forbid => "Forbid-by-default",
+ };
+ writeln!(buf, "## {title}\n")?;
+ writeln!(
+ buf,
+ "These lints are all set to the '{}' level by default.",
+ level
+ )?;
+
+ for name in lint_names {
+ writeln!(buf, "- [`{}`](#{})", name, name)?;
+ }
+ writeln!(buf)?;
+ Ok(())
+}
+
+fn lint_docs_path() -> PathBuf {
+ let pkg_root = env!("CARGO_MANIFEST_DIR");
+ let ws_root = PathBuf::from(format!("{pkg_root}/../.."));
+ let path = {
+ let path = ws_root.join("src/doc/src/reference/lints.md");
+ path.canonicalize().unwrap_or(path)
+ };
+ path
+}
diff --git a/src/bin/cargo/commands/add.rs b/src/bin/cargo/commands/add.rs
index 9c67eb8343cb..30956b00479f 100644
--- a/src/bin/cargo/commands/add.rs
+++ b/src/bin/cargo/commands/add.rs
@@ -214,11 +214,9 @@ pub fn exec(gctx: &mut GlobalContext, args: &ArgMatches) -> CliResult {
};
add(&ws, &options)?;
- if !dry_run {
- // Reload the workspace since we've changed dependencies
- let ws = args.workspace(gctx)?;
- resolve_ws(&ws)?;
- }
+ // Reload the workspace since we've changed dependencies
+ let ws = args.workspace(gctx)?;
+ resolve_ws(&ws, dry_run)?;
Ok(())
}
diff --git a/src/bin/cargo/commands/bench.rs b/src/bin/cargo/commands/bench.rs
index f6d8766570d6..c79d7cb350d0 100644
--- a/src/bin/cargo/commands/bench.rs
+++ b/src/bin/cargo/commands/bench.rs
@@ -63,7 +63,7 @@ pub fn exec(gctx: &mut GlobalContext, args: &ArgMatches) -> CliResult {
args.compile_options(gctx, CompileMode::Bench, Some(&ws), ProfileChecking::Custom)?;
compile_opts.build_config.requested_profile =
- args.get_profile_name(gctx, "bench", ProfileChecking::Custom)?;
+ args.get_profile_name("bench", ProfileChecking::Custom)?;
let ops = TestOptions {
no_run: args.flag("no-run"),
diff --git a/src/bin/cargo/commands/build.rs b/src/bin/cargo/commands/build.rs
index 308ce2ce6a71..26f7af316097 100644
--- a/src/bin/cargo/commands/build.rs
+++ b/src/bin/cargo/commands/build.rs
@@ -34,7 +34,7 @@ pub fn cli() -> Command {
.arg_parallel()
.arg_target_triple("Build for the target triple")
.arg_target_dir()
- .arg_out_dir()
+ .arg_artifact_dir()
.arg_build_plan()
.arg_unit_graph()
.arg_timings()
@@ -50,15 +50,32 @@ pub fn exec(gctx: &mut GlobalContext, args: &ArgMatches) -> CliResult {
let mut compile_opts =
args.compile_options(gctx, CompileMode::Build, Some(&ws), ProfileChecking::Custom)?;
- if let Some(out_dir) = args.value_of_path("out-dir", gctx) {
- compile_opts.build_config.export_dir = Some(out_dir);
- } else if let Some(out_dir) = gctx.build_config()?.out_dir.as_ref() {
- let out_dir = out_dir.resolve_path(gctx);
- compile_opts.build_config.export_dir = Some(out_dir);
+ if let Some(artifact_dir) = args.value_of_path("artifact-dir", gctx) {
+ // If the user specifies `--artifact-dir`, use that
+ compile_opts.build_config.export_dir = Some(artifact_dir);
+ } else if let Some(artifact_dir) = args.value_of_path("out-dir", gctx) {
+ // `--out-dir` is deprecated, but still supported for now
+ gctx.shell()
+ .warn("the --out-dir flag has been changed to --artifact-dir")?;
+ compile_opts.build_config.export_dir = Some(artifact_dir);
+ } else if let Some(artifact_dir) = gctx.build_config()?.artifact_dir.as_ref() {
+ // If a CLI option is not specified for choosing the artifact dir, use the `artifact-dir` from the build config, if
+ // present
+ let artifact_dir = artifact_dir.resolve_path(gctx);
+ compile_opts.build_config.export_dir = Some(artifact_dir);
+ } else if let Some(artifact_dir) = gctx.build_config()?.out_dir.as_ref() {
+ // As a last priority, check `out-dir` in the build config
+ gctx.shell()
+ .warn("the out-dir config option has been changed to artifact-dir")?;
+ let artifact_dir = artifact_dir.resolve_path(gctx);
+ compile_opts.build_config.export_dir = Some(artifact_dir);
}
+
if compile_opts.build_config.export_dir.is_some() {
- gctx.cli_unstable().fail_if_stable_opt("--out-dir", 6790)?;
+ gctx.cli_unstable()
+ .fail_if_stable_opt("--artifact-dir", 6790)?;
}
+
ops::compile(&ws, &compile_opts)?;
Ok(())
}
diff --git a/src/bin/cargo/commands/clean.rs b/src/bin/cargo/commands/clean.rs
index e358b9671509..1764c0bca1c9 100644
--- a/src/bin/cargo/commands/clean.rs
+++ b/src/bin/cargo/commands/clean.rs
@@ -146,7 +146,7 @@ pub fn exec(gctx: &mut GlobalContext, args: &ArgMatches) -> CliResult {
gctx,
spec: values(args, "package"),
targets: args.targets()?,
- requested_profile: args.get_profile_name(gctx, "dev", ProfileChecking::Custom)?,
+ requested_profile: args.get_profile_name("dev", ProfileChecking::Custom)?,
profile_specified: args.contains_id("profile") || args.flag("release"),
doc: args.flag("doc"),
dry_run: args.dry_run(),
diff --git a/src/bin/cargo/commands/install.rs b/src/bin/cargo/commands/install.rs
index e188d6a0d677..8aaaeb87b0e4 100644
--- a/src/bin/cargo/commands/install.rs
+++ b/src/bin/cargo/commands/install.rs
@@ -85,10 +85,13 @@ pub fn cli() -> Command {
)
.arg_features()
.arg_parallel()
- .arg(flag(
- "debug",
- "Build in debug mode (with the 'dev' profile) instead of release mode",
- ))
+ .arg(
+ flag(
+ "debug",
+ "Build in debug mode (with the 'dev' profile) instead of release mode",
+ )
+ .conflicts_with("profile"),
+ )
.arg_redundant_default_mode("release", "install", "debug")
.arg_profile("Install artifacts with the specified profile")
.arg_target_triple("Build for the target triple")
@@ -196,7 +199,7 @@ pub fn exec(gctx: &mut GlobalContext, args: &ArgMatches) -> CliResult {
)?;
compile_opts.build_config.requested_profile =
- args.get_profile_name(gctx, "release", ProfileChecking::Custom)?;
+ args.get_profile_name("release", ProfileChecking::Custom)?;
if args.flag("list") {
ops::install_list(root, gctx)?;
diff --git a/src/bin/cargo/commands/remove.rs b/src/bin/cargo/commands/remove.rs
index 25179487c934..b5695e59937f 100644
--- a/src/bin/cargo/commands/remove.rs
+++ b/src/bin/cargo/commands/remove.rs
@@ -121,7 +121,7 @@ pub fn exec(gctx: &mut GlobalContext, args: &ArgMatches) -> CliResult {
ws.gctx()
.shell()
.set_verbosity(cargo::core::Verbosity::Quiet);
- let resolve = resolve_ws(&ws);
+ let resolve = resolve_ws(&ws, dry_run);
ws.gctx().shell().set_verbosity(verbosity);
resolve?.1
};
@@ -129,7 +129,7 @@ pub fn exec(gctx: &mut GlobalContext, args: &ArgMatches) -> CliResult {
// Attempt to gc unused patches and re-resolve if anything is removed
if gc_unused_patches(&workspace, &resolve)? {
let ws = args.workspace(gctx)?;
- resolve_ws(&ws)?;
+ resolve_ws(&ws, dry_run)?;
}
}
Ok(())
diff --git a/src/bin/cargo/commands/test.rs b/src/bin/cargo/commands/test.rs
index 1815ee62f9f7..c2657a78f054 100644
--- a/src/bin/cargo/commands/test.rs
+++ b/src/bin/cargo/commands/test.rs
@@ -74,7 +74,7 @@ pub fn exec(gctx: &mut GlobalContext, args: &ArgMatches) -> CliResult {
args.compile_options(gctx, CompileMode::Test, Some(&ws), ProfileChecking::Custom)?;
compile_opts.build_config.requested_profile =
- args.get_profile_name(gctx, "test", ProfileChecking::Custom)?;
+ args.get_profile_name("test", ProfileChecking::Custom)?;
// `TESTNAME` is actually an argument of the test binary, but it's
// important, so we explicitly mention it and reconfigure.
diff --git a/src/bin/cargo/commands/update.rs b/src/bin/cargo/commands/update.rs
index fb394e4aa336..492be07c783a 100644
--- a/src/bin/cargo/commands/update.rs
+++ b/src/bin/cargo/commands/update.rs
@@ -35,6 +35,13 @@ pub fn cli() -> Command {
.value_name("PRECISE")
.requires("package-group"),
)
+ .arg(
+ flag(
+ "breaking",
+ "Update [SPEC] to latest SemVer-breaking version (unstable)",
+ )
+ .short('b'),
+ )
.arg_silent_suggestion()
.arg(
flag("workspace", "Only update the workspace packages")
@@ -59,7 +66,8 @@ pub fn exec(gctx: &mut GlobalContext, args: &ArgMatches) -> CliResult {
gctx.cli_unstable().msrv_policy,
)?;
}
- let ws = args.workspace(gctx)?;
+
+ let mut ws = args.workspace(gctx)?;
if args.is_present_with_zero_values("package") {
print_available_packages(&ws)?;
@@ -89,6 +97,24 @@ pub fn exec(gctx: &mut GlobalContext, args: &ArgMatches) -> CliResult {
workspace: args.flag("workspace"),
gctx,
};
- ops::update_lockfile(&ws, &update_opts)?;
+
+ if args.flag("breaking") {
+ gctx.cli_unstable()
+ .fail_if_stable_opt("--breaking", 12425)?;
+
+ let upgrades = ops::upgrade_manifests(&mut ws, &update_opts.to_update)?;
+ ops::resolve_ws(&ws, update_opts.dry_run)?;
+ ops::write_manifest_upgrades(&ws, &upgrades, update_opts.dry_run)?;
+
+ if update_opts.dry_run {
+ update_opts
+ .gctx
+ .shell()
+ .warn("aborting update due to dry run")?;
+ }
+ } else {
+ ops::update_lockfile(&ws, &update_opts)?;
+ }
+
Ok(())
}
diff --git a/src/cargo/core/compiler/build_config.rs b/src/cargo/core/compiler/build_config.rs
index 9536e58be566..0f66d6dbbc66 100644
--- a/src/cargo/core/compiler/build_config.rs
+++ b/src/cargo/core/compiler/build_config.rs
@@ -36,11 +36,11 @@ pub struct BuildConfig {
/// A thread used by `cargo fix` to receive messages on a socket regarding
/// the success/failure of applying fixes.
pub rustfix_diagnostic_server: Rc>>,
- /// The directory to copy final artifacts to. Note that even if `out_dir` is
- /// set, a copy of artifacts still could be found a `target/(debug\release)`
- /// as usual.
- // Note that, although the cmd-line flag name is `out-dir`, in code we use
- // `export_dir`, to avoid confusion with out dir at `target/debug/deps`.
+ /// The directory to copy final artifacts to. Note that even if
+ /// `artifact-dir` is set, a copy of artifacts still can be found at
+ /// `target/(debug\release)` as usual.
+ /// Named `export_dir` to avoid confusion with
+ /// `CompilationFiles::artifact_dir`.
pub export_dir: Option,
/// `true` to output a future incompatibility report at the end of the build
pub future_incompat_report: bool,
diff --git a/src/cargo/core/compiler/build_runner/compilation_files.rs b/src/cargo/core/compiler/build_runner/compilation_files.rs
index 27c555a26941..41ef89d6f0b6 100644
--- a/src/cargo/core/compiler/build_runner/compilation_files.rs
+++ b/src/cargo/core/compiler/build_runner/compilation_files.rs
@@ -121,7 +121,7 @@ pub struct OutputFile {
/// If it should be linked into `target`, and what it should be called
/// (e.g., without metadata).
pub hardlink: Option,
- /// If `--out-dir` is specified, the absolute path to the exported file.
+ /// If `--artifact-dir` is specified, the absolute path to the exported file.
pub export_path: Option,
/// Type of the file (library / debug symbol / else).
pub flavor: FileFlavor,
@@ -213,7 +213,7 @@ impl<'a, 'gctx: 'a> CompilationFiles<'a, 'gctx> {
}
}
- /// Additional export directory from `--out-dir`.
+ /// Additional export directory from `--artifact-dir`.
pub fn export_dir(&self) -> Option {
self.export_dir.clone()
}
diff --git a/src/cargo/core/compiler/build_runner/mod.rs b/src/cargo/core/compiler/build_runner/mod.rs
index c5a926d50afa..ed4d6fcdc354 100644
--- a/src/cargo/core/compiler/build_runner/mod.rs
+++ b/src/cargo/core/compiler/build_runner/mod.rs
@@ -574,7 +574,7 @@ impl<'a, 'gctx> BuildRunner<'a, 'gctx> {
if let Some(ref export_path) = output.export_path {
if let Some(other_unit) = output_collisions.insert(export_path.clone(), unit) {
self.bcx.gctx.shell().warn(format!(
- "`--out-dir` filename collision.\n\
+ "`--artifact-dir` filename collision.\n\
{}\
The exported filenames should be unique.\n\
{}",
diff --git a/src/cargo/core/compiler/standard_lib.rs b/src/cargo/core/compiler/standard_lib.rs
index 684e4426c04a..3e387bdddccf 100644
--- a/src/cargo/core/compiler/standard_lib.rs
+++ b/src/cargo/core/compiler/standard_lib.rs
@@ -149,6 +149,7 @@ pub fn resolve_std<'gctx>(
let cli_features = CliFeatures::from_command_line(
&features, /*all_features*/ false, /*uses_default_features*/ false,
)?;
+ let dry_run = false;
let resolve = ops::resolve_ws_with_opts(
&std_ws,
target_data,
@@ -157,6 +158,7 @@ pub fn resolve_std<'gctx>(
&specs,
HasDevUnits::No,
crate::core::resolver::features::ForceAllTargets::No,
+ dry_run,
)?;
Ok((
resolve.pkg_set,
diff --git a/src/cargo/core/manifest.rs b/src/cargo/core/manifest.rs
index 14245c410e82..a45a26a765ff 100644
--- a/src/cargo/core/manifest.rs
+++ b/src/cargo/core/manifest.rs
@@ -905,7 +905,7 @@ impl Target {
pub fn documented(&self) -> bool {
self.inner.doc
}
- // A plugin, proc-macro, or build-script.
+ // A proc-macro or build-script.
pub fn for_host(&self) -> bool {
self.inner.for_host
}
diff --git a/src/cargo/core/registry.rs b/src/cargo/core/registry.rs
index 192369c48842..bcbd819905a2 100644
--- a/src/cargo/core/registry.rs
+++ b/src/cargo/core/registry.rs
@@ -194,8 +194,10 @@ pub struct LockedPatchDependency {
}
impl<'gctx> PackageRegistry<'gctx> {
- pub fn new(gctx: &'gctx GlobalContext) -> CargoResult> {
- let source_config = SourceConfigMap::new(gctx)?;
+ pub fn new_with_source_config(
+ gctx: &'gctx GlobalContext,
+ source_config: SourceConfigMap<'gctx>,
+ ) -> CargoResult> {
Ok(PackageRegistry {
gctx,
sources: SourceMap::new(),
diff --git a/src/cargo/core/resolver/features.rs b/src/cargo/core/resolver/features.rs
index fdb49c0bf9f5..807bdc4533a8 100644
--- a/src/cargo/core/resolver/features.rs
+++ b/src/cargo/core/resolver/features.rs
@@ -426,10 +426,12 @@ pub struct FeatureResolver<'a, 'gctx> {
/// If this is `true`, then a non-default `feature_key` needs to be tracked while
/// traversing the graph.
///
- /// This is only here to avoid calling `is_proc_macro` when all feature
- /// options are disabled (because `is_proc_macro` can trigger downloads).
- /// This has to be separate from `FeatureOpts.decouple_host_deps` because
+ /// This is only here to avoid calling [`has_any_proc_macro`] when all feature
+ /// options are disabled (because [`has_any_proc_macro`] can trigger downloads).
+ /// This has to be separate from [`FeatureOpts::decouple_host_deps`] because
/// `for_host` tracking is also needed for `itarget` to work properly.
+ ///
+ /// [`has_any_proc_macro`]: FeatureResolver::has_any_proc_macro
track_for_host: bool,
/// `dep_name?/feat_name` features that will be activated if `dep_name` is
/// ever activated.
@@ -490,7 +492,7 @@ impl<'a, 'gctx> FeatureResolver<'a, 'gctx> {
let member_features = self.ws.members_with_features(specs, cli_features)?;
for (member, cli_features) in &member_features {
let fvs = self.fvs_from_requested(member.package_id(), cli_features);
- let fk = if self.track_for_host && self.is_proc_macro(member.package_id()) {
+ let fk = if self.track_for_host && self.has_any_proc_macro(member.package_id()) {
// Also activate for normal dependencies. This is needed if the
// proc-macro includes other targets (like binaries or tests),
// or running in `cargo test`. Note that in a workspace, if
@@ -852,7 +854,7 @@ impl<'a, 'gctx> FeatureResolver<'a, 'gctx> {
// for various targets which are either specified in the manifest
// or on the cargo command-line.
let lib_fk = if fk == FeaturesFor::default() {
- (self.track_for_host && (dep.is_build() || self.is_proc_macro(dep_id)))
+ (self.track_for_host && (dep.is_build() || self.has_proc_macro_lib(dep_id)))
.then(|| FeaturesFor::HostDep)
.unwrap_or_default()
} else {
@@ -957,10 +959,24 @@ impl<'a, 'gctx> FeatureResolver<'a, 'gctx> {
}
}
- fn is_proc_macro(&self, package_id: PackageId) -> bool {
+ /// Whether the given package has any proc macro target, including proc-macro examples.
+ fn has_any_proc_macro(&self, package_id: PackageId) -> bool {
self.package_set
.get_one(package_id)
.expect("packages downloaded")
.proc_macro()
}
+
+ /// Whether the given package is a proc macro lib target.
+ ///
+ /// This is useful for checking if a dependency is a proc macro,
+ /// as it is not possible to depend on a non-lib target as a proc-macro.
+ fn has_proc_macro_lib(&self, package_id: PackageId) -> bool {
+ self.package_set
+ .get_one(package_id)
+ .expect("packages downloaded")
+ .library()
+ .map(|lib| lib.proc_macro())
+ .unwrap_or_default()
+ }
}
diff --git a/src/cargo/core/summary.rs b/src/cargo/core/summary.rs
index ec0197cf40d0..d7744e24ef73 100644
--- a/src/cargo/core/summary.rs
+++ b/src/cargo/core/summary.rs
@@ -103,15 +103,25 @@ impl Summary {
Rc::make_mut(&mut self.inner).checksum = Some(cksum);
}
- pub fn map_dependencies(mut self, f: F) -> Summary
+ pub fn map_dependencies(self, mut f: F) -> Summary
where
F: FnMut(Dependency) -> Dependency,
+ {
+ self.try_map_dependencies(|dep| Ok(f(dep))).unwrap()
+ }
+
+ pub fn try_map_dependencies(mut self, f: F) -> CargoResult
+ where
+ F: FnMut(Dependency) -> CargoResult,
{
{
let slot = &mut Rc::make_mut(&mut self.inner).dependencies;
- *slot = mem::take(slot).into_iter().map(f).collect();
+ *slot = mem::take(slot)
+ .into_iter()
+ .map(f)
+ .collect::>()?;
}
- self
+ Ok(self)
}
pub fn map_source(self, to_replace: SourceId, replace_with: SourceId) -> Summary {
diff --git a/src/cargo/core/workspace.rs b/src/cargo/core/workspace.rs
index 1dc75c881e4a..d1999aafc2f8 100644
--- a/src/cargo/core/workspace.rs
+++ b/src/cargo/core/workspace.rs
@@ -20,7 +20,7 @@ use crate::core::{
};
use crate::core::{EitherManifest, Package, SourceId, VirtualManifest};
use crate::ops;
-use crate::sources::{PathSource, CRATES_IO_INDEX, CRATES_IO_REGISTRY};
+use crate::sources::{PathSource, SourceConfigMap, CRATES_IO_INDEX, CRATES_IO_REGISTRY};
use crate::util::edit_distance;
use crate::util::errors::{CargoResult, ManifestError};
use crate::util::interning::InternedString;
@@ -109,6 +109,9 @@ pub struct Workspace<'gctx> {
/// Workspace-level custom metadata
custom_metadata: Option,
+
+ /// Local overlay configuration. See [`crate::sources::overlay`].
+ local_overlays: HashMap,
}
// Separate structure for tracking loaded packages (to avoid loading anything
@@ -237,6 +240,7 @@ impl<'gctx> Workspace<'gctx> {
resolve_behavior: ResolveBehavior::V1,
resolve_honors_rust_version: false,
custom_metadata: None,
+ local_overlays: HashMap::new(),
}
}
@@ -1674,6 +1678,44 @@ impl<'gctx> Workspace<'gctx> {
// Cargo to panic, see issue #10545.
self.is_member(&unit.pkg) && !(unit.target.for_host() || unit.pkg.proc_macro())
}
+
+ /// Adds a local package registry overlaying a `SourceId`.
+ ///
+ /// See [`crate::sources::overlay::DependencyConfusionThreatOverlaySource`] for why you shouldn't use this.
+ pub fn add_local_overlay(&mut self, id: SourceId, registry_path: PathBuf) {
+ self.local_overlays.insert(id, registry_path);
+ }
+
+ /// Builds a package registry that reflects this workspace configuration.
+ pub fn package_registry(&self) -> CargoResult> {
+ let source_config =
+ SourceConfigMap::new_with_overlays(self.gctx(), self.local_overlays()?)?;
+ PackageRegistry::new_with_source_config(self.gctx(), source_config)
+ }
+
+ /// Returns all the configured local overlays, including the ones from our secret environment variable.
+ fn local_overlays(&self) -> CargoResult> {
+ let mut ret = self
+ .local_overlays
+ .iter()
+ .map(|(id, path)| Ok((*id, SourceId::for_local_registry(path)?)))
+ .collect::>>()?;
+
+ if let Ok(overlay) = self
+ .gctx
+ .get_env("__CARGO_TEST_DEPENDENCY_CONFUSION_VULNERABILITY_DO_NOT_USE_THIS")
+ {
+ let (url, path) = overlay.split_once('=').ok_or(anyhow::anyhow!(
+ "invalid overlay format. I won't tell you why; you shouldn't be using it anyway"
+ ))?;
+ ret.push((
+ SourceId::from_url(url)?,
+ SourceId::for_local_registry(path.as_ref())?,
+ ));
+ }
+
+ Ok(ret.into_iter())
+ }
}
impl<'gctx> Packages<'gctx> {
diff --git a/src/cargo/ops/cargo_add/mod.rs b/src/cargo/ops/cargo_add/mod.rs
index 1781d4c93598..a8fa97afe07a 100644
--- a/src/cargo/ops/cargo_add/mod.rs
+++ b/src/cargo/ops/cargo_add/mod.rs
@@ -78,7 +78,7 @@ pub fn add(workspace: &Workspace<'_>, options: &AddOptions<'_>) -> CargoResult<(
);
}
- let mut registry = PackageRegistry::new(options.gctx)?;
+ let mut registry = workspace.package_registry()?;
let deps = {
let _lock = options
diff --git a/src/cargo/ops/cargo_clean.rs b/src/cargo/ops/cargo_clean.rs
index 5969bf287eb9..5297430b175a 100644
--- a/src/cargo/ops/cargo_clean.rs
+++ b/src/cargo/ops/cargo_clean.rs
@@ -77,7 +77,14 @@ pub fn clean(ws: &Workspace<'_>, opts: &CleanOptions<'_>) -> CargoResult<()> {
if opts.spec.is_empty() {
clean_ctx.remove_paths(&[target_dir.into_path_unlocked()])?;
} else {
- clean_specs(&mut clean_ctx, &ws, &profiles, &opts.targets, &opts.spec)?;
+ clean_specs(
+ &mut clean_ctx,
+ &ws,
+ &profiles,
+ &opts.targets,
+ &opts.spec,
+ opts.dry_run,
+ )?;
}
}
@@ -91,11 +98,12 @@ fn clean_specs(
profiles: &Profiles,
targets: &[String],
spec: &[String],
+ dry_run: bool,
) -> CargoResult<()> {
// Clean specific packages.
let requested_kinds = CompileKind::from_requested_targets(clean_ctx.gctx, targets)?;
let target_data = RustcTargetData::new(ws, &requested_kinds)?;
- let (pkg_set, resolve) = ops::resolve_ws(ws)?;
+ let (pkg_set, resolve) = ops::resolve_ws(ws, dry_run)?;
let prof_dir_name = profiles.get_dir_name();
let host_layout = Layout::new(ws, None, &prof_dir_name)?;
// Convert requested kinds to a Vec of layouts.
diff --git a/src/cargo/ops/cargo_compile/mod.rs b/src/cargo/ops/cargo_compile/mod.rs
index 68f1df76ba6f..0553e5e2d5de 100644
--- a/src/cargo/ops/cargo_compile/mod.rs
+++ b/src/cargo/ops/cargo_compile/mod.rs
@@ -264,6 +264,7 @@ pub fn create_bcx<'a, 'gctx>(
HasDevUnits::No
}
};
+ let dry_run = false;
let resolve = ops::resolve_ws_with_opts(
ws,
&mut target_data,
@@ -272,6 +273,7 @@ pub fn create_bcx<'a, 'gctx>(
&specs,
has_dev_units,
crate::core::resolver::features::ForceAllTargets::No,
+ dry_run,
)?;
let WorkspaceResolve {
mut pkg_set,
diff --git a/src/cargo/ops/cargo_fetch.rs b/src/cargo/ops/cargo_fetch.rs
index 761f171f1f69..37b56438cd60 100644
--- a/src/cargo/ops/cargo_fetch.rs
+++ b/src/cargo/ops/cargo_fetch.rs
@@ -19,7 +19,8 @@ pub fn fetch<'a>(
options: &FetchOptions<'a>,
) -> CargoResult<(Resolve, PackageSet<'a>)> {
ws.emit_warnings()?;
- let (mut packages, resolve) = ops::resolve_ws(ws)?;
+ let dry_run = false;
+ let (mut packages, resolve) = ops::resolve_ws(ws, dry_run)?;
let jobs = Some(JobsConfig::Integer(1));
let keep_going = false;
diff --git a/src/cargo/ops/cargo_install.rs b/src/cargo/ops/cargo_install.rs
index a662e891f387..e4304d74829c 100644
--- a/src/cargo/ops/cargo_install.rs
+++ b/src/cargo/ops/cargo_install.rs
@@ -561,7 +561,8 @@ impl<'gctx> InstallablePackage<'gctx> {
// It would be best if `source` could be passed in here to avoid a
// duplicate "Updating", but since `source` is taken by value, then it
// wouldn't be available for `compile_ws`.
- let (pkg_set, resolve) = ops::resolve_ws(&self.ws)?;
+ let dry_run = false;
+ let (pkg_set, resolve) = ops::resolve_ws(&self.ws, dry_run)?;
ops::check_yanked(
self.ws.gctx(),
&pkg_set,
diff --git a/src/cargo/ops/cargo_output_metadata.rs b/src/cargo/ops/cargo_output_metadata.rs
index 408be75faf38..1aadc05d77a3 100644
--- a/src/cargo/ops/cargo_output_metadata.rs
+++ b/src/cargo/ops/cargo_output_metadata.rs
@@ -142,6 +142,7 @@ fn build_resolve_graph(
// Note that even with --filter-platform we end up downloading host dependencies as well,
// as that is the behavior of download_accessible.
+ let dry_run = false;
let ws_resolve = ops::resolve_ws_with_opts(
ws,
&mut target_data,
@@ -150,6 +151,7 @@ fn build_resolve_graph(
&specs,
HasDevUnits::Yes,
force_all,
+ dry_run,
)?;
let package_map: BTreeMap = ws_resolve
diff --git a/src/cargo/ops/cargo_package.rs b/src/cargo/ops/cargo_package.rs
index 533852551c20..c9fc22c79307 100644
--- a/src/cargo/ops/cargo_package.rs
+++ b/src/cargo/ops/cargo_package.rs
@@ -9,7 +9,7 @@ use std::task::Poll;
use crate::core::compiler::{BuildConfig, CompileMode, DefaultExecutor, Executor};
use crate::core::manifest::Target;
use crate::core::resolver::CliFeatures;
-use crate::core::{registry::PackageRegistry, resolver::HasDevUnits};
+use crate::core::resolver::HasDevUnits;
use crate::core::{Feature, PackageIdSpecQuery, Shell, Verbosity, Workspace};
use crate::core::{Package, PackageId, PackageSet, Resolve, SourceId};
use crate::sources::PathSource;
@@ -190,7 +190,8 @@ pub fn package(ws: &Workspace<'_>, opts: &PackageOpts<'_>) -> CargoResult
This option is unstable and available only on the
nightly channel
diff --git a/src/doc/src/commands/cargo-update.md b/src/doc/src/commands/cargo-update.md
index 8de0bee9850c..3c7eb59e7f18 100644
--- a/src/doc/src/commands/cargo-update.md
+++ b/src/doc/src/commands/cargo-update.md
@@ -47,6 +47,22 @@ from the maintainers of the package.
requirement in Cargo.toml doesn’t contain any pre-release identifier (nightly only).
+
--breakingdirectory
+
Update spec to latest SemVer-breaking version.
+
Version requirements will be modified to allow this update.
+
This only applies to dependencies when
+
+
The package is a dependency of a workspace member
+
The dependency is not renamed
+
A SemVer-incompatible version is available
+
The “SemVer operator” is used (^ which is the default)