This commit makes lockfile version 4 the default version when Cargo
tries to write to a lockfile.
The lockfile version 4 has been stabilized since 1.78.0,
and will become default in 1.83.0.
the length of transition period is pretty similar as before.
One caveat is that in other output from Cargo,
e.g., `cargo metatada`, status messages,
`SourceID` will display in the v4 URL encoded format.
This shouldn't affect the majority of Rust users,
as `SourceId` representation should be opaque to them,
unless comparing `SourceId` across different version of toolchains.
This is for `cargo generate-lockfile` and when syncing the lockfile with
the manifest.
We still show it for `cargo update` because of `cargo update
--workspace`.
We hacked around this previously by filtering out the `num_pkgs==1` case
for single packages but this didn't help with workspaces.
I was considering moving this into `paths` and noticed `CargoPathExt`.
I figured if we had any extension traits for `Path`, then this is a
reasonable one to add.
We now include the prelude in so many places, this simplifies how we can
present how `cargo-test-support` works.
Yes, this included some `use` clean ups but its already painful enough
walking through every test file, I didn't want to do it twice.
While this is noisy and hides other deprecations, I figured deprecations would
make it easier for people to discover what tasks remain and allow us to
divide and conquer this work rather than doing a heroic PR.
In theory, this will be short lived and we'll go back to seeing
deprecations in our tests.
This is to help with #9930
Example changes:
```diff
-[LOCKING] 4 packages
+[LOCKING] 4 packages to latest version
-[LOCKING] 2 packages
+[LOCKING] 2 packages to latest Rust 1.60.0 compatible versions
-[LOCKING] 2 packages
+[LOCKING] 2 packages to earliest versions
```
Benefits
- The package count is of "added" packages and this makes that more
logically clear
- This gives users transparency into what is happening, especially with
- what rust-version is use
- the transition to this feature in the new edition
- whether the planned config was applied or not (as I don't want it to
require an MSRV bump)
- Will make it easier in tests to show what changed
- Provides more motiviation to show this message in `cargo update` and
`cargo install` (that will be explored in a follow up PR)
This does come at the cost of more verbose output but hopefully not too
verbose. This is why I left off other factors, like avoid-dev-deps.
fix(metadata): Stabilize id format as PackageIDSpec
### What does this PR try to resolve?
For tools integrating with cargo, `cargo metadata` is the primary interface. Limitations include:
- There isn't an unambiguous way to map a package entry from `cargo metadata` to a parameter to pass to other `cargo` commands. An `id` field exists but it is documented as an opaque string, useful only for comparisons with other `id`s within the document.
- There isn't an unambiguous way of taking user parameters (`--package`) and mapping them to `cargo metadata` entries. `cargo pkgid` could help but it returns a `PackageIdSpec` which doesn't exist within the `cargo metadata` output.
This attempts to solve these problems by switching the `id` field from `PackageId` to `PackageIdSpec` which is a [publicly documented format](https://doc.rust-lang.org/cargo/reference/pkgid-spec.html), can be generated by `cargo pkgid`, and is accepted by most commands via the `--package` flag.
As the `"id"` field is documented as opaque, this technically isn't a breaking change though people could be parsing it.
For `cargo_metadata` they do [use a new type that documents it as opaque but publicly expose the inner `String`](https://docs.rs/cargo_metadata/latest/cargo_metadata/struct.PackageId.html). The `String` wasn't publicly exposed due to a request by users but instead their `PackageId` type replaced using `String`s in the API in oli-obk/cargo_metadata#59 with no indication given as to why the `String` was still exposed. However, you'll note that before that PR, they had `WorkspaceMember` that parsed `PackageId`. This was introduced in oli-obk/cargo_metadata#26 without a motivation given.
**Note that `PackageIdSpec` has multiple representation that might uniquely identify a package and we can return any one of them.**
Fixes#7267
### How should we test and review this PR?
### Additional information
cc `@oli-obk`
`cargo update --precise` might pass in any arbitrary Git reference,
and `git2::Oid::from_str` would always zero-pad the given str if it is
not a full SHA hex string.
This introduces an enum `Revision` to represent `locked_rev`
that is either deferred or resolved to an actual object ID.
When `locked_rev` is a short ID or any other Git reference,
Cargo first performs a Git fetch to resolve it (without --offline),
and then locks it to an actual commit object ID.
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.
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.
Git only assumes a submodule URL is a relative path if it starts with `./`
or `../` [^1]. To fetch the correct repo, we need to construct an aboslute
submodule URL.
At this moment it comes with some limitations:
* GitHub doesn't accept non-normalized URLs wth relative paths.
(`ssh://git@github.com/rust-lang/cargo.git/relative/..` is invalid)
* `url` crate cannot parse SCP-like URLs.
(`git@github.com:rust-lang/cargo.git` is not a valid WHATWG URL)
To overcome these, this patch always tries `Url::parse` first to normalize
the path. If it couldn't, append the relative path as the last resort and
pray the remote git service supports non-normalized URLs.
See also rust-lang/cargo#12404 and rust-lang/cargo#12295.
[^1]: <https://git-scm.com/docs/git-submodule>
`parent_remote_url` used to be `&str` before #12244. However, we changed
the type to `Url` and it started failing to parse scp-like URLs since
they are not compliant with WHATWG URL spec.
In this commit, we change it back to `&str` and construct the URL
manually. This should be safe since Cargo already checks if it is a
relative URL for that if branch.
Doing so seems cleaner as there should be no logical difference between
shallow or not-shallow when fetching. We want a specific object, and should
get it with the refspec. `git` will assure we see all objects we need,
handling shallow-ness for us.
Note that one test needed adjustments due to the different mechanism used
when fetching local repositories, requiring more changes to properly 'break'
the submodule repo when `gitoxide` is used.
This is an improvement over the previous version which would use unshallowing that effectively
makes a shallow repo *not* shallow.
Furthermore, we will now only fetch a single commit, each time we fetch, which should be faster
for the server as well as for the client.
We also make it possible to fetch individual commits that would be specified via Cargo.lock.
A couple of test expectations are adjusted accordingly.
Is this desirable behaviour? Unfortunately, there is no alternative
as adding shallow to an existing index most definitely breaks backwards
compatibility.
The implementation hinges on passing information about the kind of clone
and fetch to the `fetch()` method, which then configures the fetch accordingly.
Note that it doesn't differentiate between initial clones and fetches as
the shallow-ness of the repository is maintained nonetheless.
This allows to use `gitoxide` for all fetch operations, boosting performance
for fetching the `crates.io` index by a factor of 2.2x, while being consistent
on all platforms.
For trying it, nightly builds of `cargo` can specify `-Zgitoxide=fetch`.
It's also possible to set the `__CARGO_USE_GITOXIDE_INSTEAD_OF_GIT2=1` environment
variable (value matters), which is when `-Zgitoxide=none` can be used
to use `git2` instead.
Limitations
-----------
Note that what follows are current shortcomings that will be addressed in future PRs.
- it's likely that authentication around the `ssh` protocol will work differently in practice
as it uses the `ssh` program.
- clones from `file://` based crates indices will need the `git` binary to serve the locatl repository.
- the progress bar shown when fetching doesn't work like the orgiinal, but should already feel 'faster'.