fix bug: corruption when cargo killed while writing
### What does this PR try to resolve?
fix #11386, superseding #12362
### How should we test and review this PR?
Added unit test showing basic equivalency to existing `write(path, content)`. Full test suite should exercise write.
Added tests for cargo add and remove. These are timing tests, so take a bit of time to run. 5-10s each. They may not fail every time, but do so regularly. Making the change to these two writes seems to prevent me from failing these tests at all.
### Additional information
This uses tempfile::persist which was an existing dependency. atomicwrites crate, an alternative option for this fix, indicates `tempfile::persist` is the same thing. Since we already use tempfile as a dep, I stuck with that.
Disable custom_target::custom_bin_target on windows-gnu
The `custom_target::custom_bin_target` test has been crashing frequently in CI on the x86_64-pc-windows-gnu target since the last LLVM 17 update. This disables the test to reduce the disruption in CI. The issue is being tracked in https://github.com/rust-lang/rust/issues/115985.
feat(embedded): Hack in code fence support
### What does this PR try to resolve?
This is to allow us to get feedback on the design proposed
[on zulip](https://rust-lang.zulipchat.com/#narrow/stream/213817-t-lang/topic/Embedding.20cargo.20manifests.20in.20rust.20source/near/391427092)
to verify we want to make an RFC for this syntax.
````rust
#!/usr/bin/env cargo
```cargo
[dependencies]
clap = { version = "4.2", features = ["derive"] }
```
use clap::Parser;
#[derive(Parser, Debug)]
#[clap(version)]
struct Args {
#[clap(short, long, help = "Path to config")]
config: Option<std::path::PathBuf>,
}
fn main() {
let args = Args::parse();
println!("{:?}", args);
}
````
### How should we test and review this PR?
The tests were updated in a separate commit to ensure there was no regression while then migrating to the new syntax to make sure it worked.
This involves some future work
- Removing doc comment support
- Getting the syntax approved and implemented
- Migrating to rustc support for the syntax
#12207 was updated to record these items so we don't lose track of them
more specific registry index not found msg
### What does this PR try to resolve?
covers #12576
### How should we test and review this PR?
test covers exact text, so a review and passing tests.
The previous status line was a little awkward in the way it combined
both counts. I don't think showing the directories is particularly
interesting, so they are only displayed when no files are deleted.
feat(cli): Add '-n' to dry-run
This came from #12638 and my many small frustrations from wanting to use `-n` and not being able to.
We do not have any existing `-n` flags for this to be confused with.
I would wager that `-n` is such an entrenched short flag in build tools that it would not make sense for us to use it with any other flag.
For a survey of where `-n` is used as a short, see https://www.gnu.org/prep/standards/html_node/Option-Table.html#Option-Table
feat: stabilize credential-process and registry-auth
Stabilization PR for `registry-auth` and `credential-process`.
Tracking approval of this stabilization is done in the via the FCP in [#8933](https://github.com/rust-lang/cargo/issues/8933#issuecomment-1711990123). This PR is here to help reviewers of the FCP.
* Stabilizes `registry-auth` and `credential-process`
* Makes authenticated registries require a credential provider
* Adds stable documentation for credential providers and authenticated registries
Closes#8933Closes#10474
This came from #12638 and my many small frustrations from wanting to use
`-n` and not being able to.
We do not have any existing `-n` flags for this to be confused with.
I would wager that `-n` is such an entrenched short flag in build tools that it would
not make sense for us to use it with any other flag.
For a survey of where `-n` is used as a short, see
https://www.gnu.org/prep/standards/html_node/Option-Table.html#Option-Table
feat(help): Add styling to help output
### What does this PR try to resolve?
Try to make `--help` output easier to parse by using terminal styling
Screenshots:
![Screenshot from 2023-09-06 09-57-11](https://github.com/rust-lang/cargo/assets/60961/61069af4-ef05-40ad-9240-fedea44d4c71)
![Screenshot from 2023-09-06 09-57-21](https://github.com/rust-lang/cargo/assets/60961/d2e69024-42aa-47c0-ad0f-24e43551b8db)
![Screenshot from 2023-09-06 09-57-36](https://github.com/rust-lang/cargo/assets/60961/e3d895e2-745f-48c6-9e84-d6fb67198d6d)
*(`nargo` is my shell script wrapping `cargo run --manifest-path cargo/Cargo.toml`)*
### How should we test and review this PR?
At this time, the only styling snapshotting library I know of is a pain to use, so testing this requires manually running the commands which I did. Screenshots are included for easier evaluation of the general idea.
Snapshotting of the plain text output ensures we don't have accidental formatting regressions from this change since the formatting isn't as obvious from looking at the code.
### Additional information
Traditionally, cargo has disabled clap's styled output. My assumed
reason is that cargo mixes custom help output with auto-generated and
you couldn't previously make it all styled.
Clap 4.2 allowed users to pass in strings styled using ANSI escape
codes, allowing us to pass in styled text that matches clap, unblocking this. In clap
4.4.1, clap gained the ability for the user to override the style.
In this PR, I decided to use the new 4.4.1 feature to style clap's
output to match the rest of cargo's output. Alternatively, we could use
a more subdue style that clap uses by default.
I used the `color-print` crate to allow something almost html-like for styling `&static str`. Alternatively, we could directly embed the ANSI escape codes harder to get write, harder to inspect), or we could do the styling at runtime and enable the `string` feature in clap.
I decided to *not* style `Arg::help` messages because
- It might be distracting to have the descriptions lit up like a
christmas tree
- It is a lot more work
The one exception I made was for `--list` since it is for a
psuedo-command (`...`) and I wanted to intentionally draw attention to
it.
#12593 made styling of `cargo -h` cleaner imo.
#12592 and #12594 were improvements I noticed while doing this.
Ues strip_prefix for cleaner code
### What does this PR try to resolve?
In https://github.com/rust-lang/cargo/pull/12629#pullrequestreview-1614154046 Ed pointed out how much cleaner the code can be using `strip_prefix`, so I found a bunch more places where we should be using it.
### How should we test and review this PR?
Internal refactor and test still pass.
fix: improve warning for both token & credential-provider
Cargo issues a warning when both a `credential-provider` and a `token` are configured for a registry.
This change removes the warning if the `credential-provider` is `cargo:token` since that *will* use the token. The warning message text is also tweaked to include the name of the `credential-provider` that's overriding the token.
fix(resolver): Make resolver behavior independent of package order
This address one of the problems mentioned in #12599
The intent behind the `path_pkg` check is to make sure we update
workspace members in the lockfile if their version number changed.
In this case, we don't need to recursively walk, because the change
doesn't affect dependencies. However, we also shouldn't *prevent*
recursive walks which is what we are doing today, both for packages
marked to keep and for packages that have been "poisoned". So we fix
this by moving that call after all recursive adds are complete so as to
not interfere with them.
This should not affect `Cargo.lock` at rest, so no upgrade compatibility concerns.
This just allows more packages to be considered available to change which can prevent unclear failures.
The main case I can think of that this does something "undesirable" is when wanting to prevent another "bug" from manifesting: the updating of git dependencies when updating workspace members (#12599). I think I'm ok with that as that needs to be looked into separately.
fix(help): Provide better commands heading for styling
In working on #12578, I felt it would be weird to style the entire statement about commands but it also felt weird to not style it. So this change explores an alternatively way of communicating the information.
This addresses the ordering issue of for one of the problems from #12599.
The intent behind the `path_pkg` check is to make sure we update
workspace members in the lockfile if their version number changed.
In this case, we don't need to recursively walk, because the change
doesn't affect dependencies. However, we also shouldn't *prevent*
recursive walks which is what we are doing today, both for packages
marked to keep and for packages that have been "poisoned". So we fix
this by moving that call after all recursive adds are complete so as to
not interfere with them.
In working on #12578, I felt it would be weird to style the entire
statement about commands but it also felt weird to not style it. So
this change explores an alternatively way of communicating the
information.
fix: add error for unsupported credential provider version
Cargo currently ignores the version in the `CredentialHello` message, and proceeds to use version `1` regardless of what the credential provider claims it can support.
This change does the following:
* Adds a new error if Cargo doesn't support any of the supported protocol versions offered by the provider.
* Kills the credential provider subprocess if it fails. This prevents it from hanging or printing spurious errors such as "broken pipe" when it's attempting to read the next JSON message.
* Adds a new test for an unsupported credential provider protocol.
In working on #12578, I'm focusing on each help string to decide how it
should be handled and I noticed this. It feels weird to explain
something in terms of another command's CLI, so I took `rustc --help`s
message and added `rustc` to clarify it.
Looking back, the flag was added in #2551 with the message we have
today. Nothing seems to really be said about it.
In reflecting on this, I'm not 100% convinced and am open to other
opinions.
fix(help): Remove redundant information from new/init
Auditing all of the `--help` in prep for #12578 and noticed that we list the VCS information twice, once on our end and once by clap.
fix(lints): Fail when overriding inherited lints
### What does this PR try to resolve?
Overriding of inherited lints was reserved for the future but as pointed out in https://github.com/rust-lang/cargo/issues/12115#issuecomment-1695293006, we aren't failing on these when we should but silently ignoring the overrides.
This turns it into a hard error.
In fixing this, I had to add a `#[serde(expecting)]` attribute to maintain behavior on an error case (otherwise it would say "expecting struct WorkspaceLints"). Since this drew the error message to my attention, I also tweaked it to make it more specific.
### How should we test and review this PR?
Commits are broken down by the relevant tests and fixes to make the intended behavior changes obvious.
cargo install: suggest --git when package name is url
### What does this PR try to resolve?
Improve the error message when specifying a URL for a package name in `cargo install`.
Fixes#10485
### How should we test and review this PR?
Just cargo test and trying a common case like `cargo install https://github.com/rust-lang/cargo`
### Additional information
I found this PR after finishing this one: #10522
But it seems have a larger scope to refactor some of the related code.
Perhaps this one would be easier to merge and that one could focus on the refactor, otherwise sorry for the noise and feel free to close.
I assume the reason these aren't all individual tests is test-time but
if we divide by success/failure, I'll need to duplicate things to handle
partial versions.
Overall, I feel like this makes the tests make more sense.
When working on cargo-upgrade, I found the meaning of `--aggressive`
confusing and named it `--recursive` there.
Renaming this in `cargo update` (with a backwards compatible alias) was
referenced in #12425.
refactor: Pull out cargo-add MSRV code for reuse
### What does this PR try to resolve?
#12078 added MSRV code in `cargo add`. Our assumption when writing it is that we'd need to generalize the code before reusing it in other places, like `cargo install`. This PR focused purely on that refactor because I'm hopeful it will be useful for other work I'm doing. Despite not having a user for this yet, I think the `cargo install` case is inevitable and I feel this does a bit to clean up MSRV related code by using a more specific type everywhere.
### How should we test and review this PR?
Each commit gradually progresses things along
fix(toml): Improve parse errors
### What does this PR try to resolve?
When we adopted `toml_edit`, we got TOML syntax errors that showed the context for where the error occurred. However, the work was not done to extend this to semantic errors reported by serde.
This updates `Cargo.toml` and `Cargo.lock` code to provide that context on semantic errors. `config.toml` is not done because the schema is decentralized.
In theory, this will also improve performance because we aren't having to allocate a lot of intermediate data to then throw away for every `Cargo.toml` we read.
### How should we test and review this PR?
Check by commit to see this change gradually.
- The `package.cargo-features` change was made to drop out dependence on `toml::Table` so we could do the direct deserialization
Create dedicated unstable flag for asymmetric-token
Asymmetric tokens are gated by `-Zcredential-process`. Since we're considering stabilizing that soon, this moves asymmetric token support to have its own unstable flag.
It was previously gated by `-Zregistry-auth`, and some of the docs were not updated when it moved.
r? `@Eh2406`
Before, we'd render the source for TOML syntax errors but not semantic errors.
Now we render for both.
Originally I changed `parse_document` to returned `T: DeserializeOwned`
but that adds an extra "could not parse TOML" which is both redundant
and makes it sound like its a syntax issue.
Generally, cargo avoids positional arguments. Mostly for the commands
that might forward arguments to another command, like `cargo test`.
It also allows some flexibility in turning flags into options.
For `cargo add` and `cargo remove`, we decided to accept positionals
because the motivations didn't seem to apply as much (similar to `cargo
install`).
This applies the pattern to `cargo update` as well which is in the same
category of commands as `cargo add` and `cargo remove`.
As for `--help` formatting, I'm mixed on whether `[SPEC]...` should be at the top like
other positionals or should be relegated to "Package selection". I went
with the latter mostly to make it easier to visualize the less common
choice.
Switching to a positional for `cargo update` (while keeping `-p` for
backwards compatibility) was referenced in #12425.
feat(resolver): **Very** preliminary MSRV resolver support
### What does this PR try to resolve?
A bare bones implementation of an MSRV resolver that is good enough for people running on nightly when they really need it but is not ready for general use.
Current limitations
- Does not honor `--ignore-version`
- Gives terrible error messages
- Nothing is done yet regarding `cargo install`
- Doesn't inform the user when choosing non-latest
These will be noted in #9930 on merge.
Implementation wise, this is yet another hack (sorry `@Eh2406).` Our expectation to get this GA is to refactor the resolver to make the cargo/resolver boundary look a little more like the cargo/pubgrub boundary so we can better control policy without any of these hacks which will also make having all of the policy we need for this easier to maintain.
This is a part of #9930
### How should we test and review this PR?
Per commit
Improve deserialization errors of untagged enums
### What does this PR try to resolve?
```toml
# .cargo/config.toml
[http]
ssl-version.min = false
```
**Before:**
```console
$ cargo check
error: data did not match any variant of untagged enum SslVersionConfig
```
**After:**
```console
$ cargo check
error: error in /path/to/.cargo/config.toml: could not load config key `http.ssl-version`
Caused by:
error in /path/to/.cargo/config.toml: `http.ssl-version.min` expected a string, but found a boolean
```
### How should we test and review this PR?
The first commit adds tests showing the pre-existing error messages — mostly just _"data did not match any variant of untagged enum T"_ with no location information. The second commit replaces all `#[derive(Deserialize)] #[serde(untagged)]` with Deserialize impls based on https://docs.rs/serde-untagged/0.1, showing the effect on the error messages.
Tested with `cargo test`, and by handwriting some bad .cargo/config.toml files and looking at the error produced by `rust-lang/cargo/target/release/cargo check`.
config: merge lists in precedence order
When merging configuration lists, the current order does not match the expected precedence. This makes merged lists follow precedence order, with higher precedence items merged later in lists.
When a list in configuration exists in multiple places, Cargo merges the lists together. The ordering of this merging is unexpected and does not follow the precedence rules that non-list configuration uses.
The current merging order appears to be:
* project-specific `config.toml`
* global `config.toml`
* command-line (`--config`)
* environment variable (`CARGO_*`)
This PR changes the order to follow the precedence rules with higher precedence configuration merging later in the lists.
* global `config.toml`
* project-specific `config.toml`
* environment variable (`CARGO_*`)
* command-line (`--config`)
This aligns with config such as `build.rustflags` where later flags take precedence over earlier ones.
Since `--config` is relatively new, it's unlikely to cause too much breakage by making it come after environment variables.
Switching global and project-specific ordering is more likely to cause breakage, since it's been around longer (reported as an issue in #8128). Projects relying on global configuration flags (in `$CARGO_HOME\config.toml` or in `.cargo/config.toml` further from the project) being merged first in lists will be broken.
For most uses of merged lists (such as `build.rustflags`), if the flags do not conflict with each other, there will be no impact.
Fixes#12506Fixes#8128
login: allow passing additional args to provider
As part of moving asymmetric token support to a credential provider in #12334, support for passing `--key-subject` to `cargo login` was removed.
This change allows passing additional arguments to credential providers when running `cargo login`. For example:
`cargo login -- --key-subject foo`.
The asymmetric token provider (`cargo:paseto`) is updated to take advantage of this and re-enables setting `--key-subject` from `cargo login`.
r? `@Eh2406`
cc #8933
When merging configuration lists, the current order does not match
the expected precedence. This makes merged lists follow precedence
order, with higher precedence items merged later in lists.
Crate checksum lookup query should match on semver build metadata
Since crates.io allows crate versions to differ only by build metadata, a query using `OptVersionReq::exact` + `next()` can return nondeterministic results.
This change fixes the issue by adding an additional `filter` that ensures the version is equal (including build metadata).
It still feels somewhat wrong that a query using `exact` can match multiple crates, so an alternative fix would be to add a new variant of `OptVersionReq` that also matched on build metadata.
Fixes#11412
It confuses people that both `--no-fail-fast` and `--keep-going` exist
on `cargo test` and `cargo bench` but with slightly different behavior.
The intended use cases for `--keep-going` involve build commands like
`build`/`check`/`clippy` but never `test`/`bench`.
Hence, this commit removes `--keep-going` from `test`/`bench` and
provides guidance of `--no-fail-fast` instead.
If people really want to build as many tests as possible, they can also
do it in two steps:
cargo build --tests --keep-going
cargo test --test --no-fail-fast
prompt the use of `--nocapture` flag if `cargo test` process is terminated via a signal.
Fixes#10855
As per the discussion on this issue, we want to prompt the user to use `--nocapture` if a test is terminated abnormally. The motivation for this change is described in the issue.
We check for 3 things before we display this flag. -
- `!is_simple` (if the test ended with a non 101 status code)
- `harness` (if the standard test harness was used), and
- `!nocapture` (whether or not the `--nocapture` flag was already passed to the test)
There's further tests added to `test::nonzero_exit_status` that check that the `stderr` is correct for the various combinations possible when a test ends with a non-101 status code.
The new expected behavior is -
- Display `--nocapture` note for only non-zero exit statuses, when the `--nocapture` flag is not passed.
- Only display the note if we use a standard test harness since custom test harnesses do not implement the `--nocapture` flag.
To implement the check for the `--nocapture` flag, the function definition for `report_test_errors` was changed to add the `test_args: &[&str]` parameter. This parameter is passed from the immediate calling function. This private function is only called twice change and is not causing regression after making the appropriate changes to both the places it's called in.
Fix cargo remove incorrectly removing used patches
### What does this PR try to resolve?
Fixes an issue where patches are being removed when member dependencies don't explicitly contain the patched crate.
Fixes#12419
### How should we test and review this PR?
- Created a test for the failing use case
- Verify passing test
<!--
### Additional information
Other information you want to mention in this PR, such as prior arts,
future extensions, an unresolved problem, or a TODO list.
-->