Skip to content

Commit

Permalink
Auto merge of #12545 - epage:positional, r=weihanglo
Browse files Browse the repository at this point in the history
fix(update): Make `-p` more convenient by being positional

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.
  • Loading branch information
bors committed Aug 29, 2023
2 parents 5522091 + dc37222 commit 94770a5
Show file tree
Hide file tree
Showing 28 changed files with 158 additions and 99 deletions.
36 changes: 33 additions & 3 deletions src/bin/cargo/commands/update.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,26 @@
use crate::command_prelude::*;

use anyhow::anyhow;
use cargo::ops::{self, UpdateOptions};
use cargo::util::print_available_packages;

pub fn cli() -> Command {
subcommand("update")
.about("Update dependencies as recorded in the local lock file")
.args([clap::Arg::new("package2")
.action(clap::ArgAction::Append)
.num_args(1..)
.value_name("SPEC")
.help_heading(heading::PACKAGE_SELECTION)
.group("package-group")
.help("Package to update")])
.arg(
optional_multi_opt("package", "SPEC", "Package to update")
.short('p')
.hide(true)
.help_heading(heading::PACKAGE_SELECTION)
.group("package-group"),
)
.arg_dry_run("Don't actually write the lockfile")
.arg(
flag(
Expand All @@ -20,15 +35,14 @@ pub fn cli() -> Command {
"Update a single dependency to exactly PRECISE when used with -p",
)
.value_name("PRECISE")
.requires("package"),
.requires("package-group"),
)
.arg_quiet()
.arg(
flag("workspace", "Only update the workspace packages")
.short('w')
.help_heading(heading::PACKAGE_SELECTION),
)
.arg_package_spec_simple("Package to update")
.arg_manifest_path()
.after_help("Run `cargo help update` for more detailed information.\n")
}
Expand All @@ -40,10 +54,26 @@ pub fn exec(config: &mut Config, args: &ArgMatches) -> CliResult {
print_available_packages(&ws)?;
}

let to_update = if args.contains_id("package") {
"package"
} else {
"package2"
};
let to_update = values(args, to_update);
for crate_name in to_update.iter() {
if let Some(toolchain) = crate_name.strip_prefix("+") {
return Err(anyhow!(
"invalid character `+` in package name: `+{toolchain}`
Use `cargo +{toolchain} update` if you meant to use the `{toolchain}` toolchain."
)
.into());
}
}

let update_opts = UpdateOptions {
aggressive: args.flag("aggressive"),
precise: args.get_one::<String>("precise").map(String::as_str),
to_update: values(args, "package"),
to_update,
dry_run: args.dry_run(),
workspace: args.flag("workspace"),
config,
Expand Down
2 changes: 1 addition & 1 deletion src/cargo/ops/cargo_compile/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -508,7 +508,7 @@ pub fn create_bcx<'a, 'cfg>(
} else if !unit.is_local() {
format!(
"Either upgrade to rustc {} or newer, or use\n\
cargo update -p {}@{} --precise ver\n\
cargo update {}@{} --precise ver\n\
where `ver` is the latest version of `{}` supporting rustc {}",
version,
unit.pkg.name(),
Expand Down
4 changes: 2 additions & 2 deletions src/cargo/ops/resolve.rs
Original file line number Diff line number Diff line change
Expand Up @@ -612,7 +612,7 @@ fn register_previous_locks(

// Ok so we've been passed in a `keep` function which basically says "if I
// return `true` then this package wasn't listed for an update on the command
// line". That is, if we run `cargo update -p foo` then `keep(bar)` will return
// line". That is, if we run `cargo update foo` then `keep(bar)` will return
// `true`, whereas `keep(foo)` will return `false` (roughly speaking).
//
// This isn't actually quite what we want, however. Instead we want to
Expand All @@ -622,7 +622,7 @@ fn register_previous_locks(
// * There's a crate `log`.
// * There's a crate `serde` which depends on `log`.
//
// Let's say we then run `cargo update -p serde`. This may *also* want to
// Let's say we then run `cargo update serde`. This may *also* want to
// update the `log` dependency as our newer version of `serde` may have a
// new minimum version required for `log`. Now this isn't always guaranteed
// to work. What'll happen here is we *won't* lock the `log` dependency nor
Expand Down
2 changes: 1 addition & 1 deletion src/cargo/sources/registry/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -251,7 +251,7 @@ pub struct RegistrySource<'cfg> {
/// yanked.
///
/// This is populated from the entries in `Cargo.lock` to ensure that
/// `cargo update -p somepkg` won't unlock yanked entries in `Cargo.lock`.
/// `cargo update somepkg` won't unlock yanked entries in `Cargo.lock`.
/// Otherwise, the resolver would think that those entries no longer
/// exist, and it would trigger updates to unrelated packages.
yanked_whitelist: HashSet<PackageId>,
Expand Down
16 changes: 8 additions & 8 deletions src/doc/man/cargo-update.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ cargo-update --- Update dependencies as recorded in the local lock file

## SYNOPSIS

`cargo update` [_options_]
`cargo update` [_options_] _spec_

## DESCRIPTION

Expand All @@ -20,26 +20,26 @@ latest available versions.

{{#options}}

{{#option "`-p` _spec_..." "`--package` _spec_..." }}
{{#option "_spec_..." }}
Update only the specified packages. This flag may be specified
multiple times. See {{man "cargo-pkgid" 1}} for the SPEC format.

If packages are specified with the `-p` flag, then a conservative update of
If packages are specified with _spec_, then a conservative update of
the lockfile will be performed. This means that only the dependency specified
by SPEC will be updated. Its transitive dependencies will be updated only if
SPEC cannot be updated without updating dependencies. All other dependencies
will remain locked at their currently recorded versions.

If `-p` is not specified, all dependencies are updated.
If _spec_ is not specified, all dependencies are updated.
{{/option}}

{{#option "`--aggressive`" }}
When used with `-p`, dependencies of _spec_ are forced to update as well.
When used with _spec_, dependencies of _spec_ are forced to update as well.
Cannot be used with `--precise`.
{{/option}}

{{#option "`--precise` _precise_" }}
When used with `-p`, allows you to specify a specific version number to set
When used with _spec_, allows you to specify a specific version number to set
the package to. If the package comes from a git repository, this can be a git
revision (such as a SHA hash or tag).
{{/option}}
Expand Down Expand Up @@ -87,11 +87,11 @@ Displays what would be updated, but doesn't actually write the lockfile.

2. Update only specific dependencies:

cargo update -p foo -p bar
cargo update foo bar

3. Set a specific dependency to a specific version:

cargo update -p foo --precise 1.2.3
cargo update foo --precise 1.2.3

## SEE ALSO
{{man "cargo" 1}}, {{man "cargo-generate-lockfile" 1}}
26 changes: 13 additions & 13 deletions src/doc/man/generated_txt/cargo-update.txt
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ NAME
cargo-update — Update dependencies as recorded in the local lock file

SYNOPSIS
cargo update [options]
cargo update [options] spec

DESCRIPTION
This command will update dependencies in the Cargo.lock file to the
Expand All @@ -13,25 +13,25 @@ DESCRIPTION

OPTIONS
Update Options
-p spec…, --package spec…
spec…
Update only the specified packages. This flag may be specified
multiple times. See cargo-pkgid(1) for the SPEC format.

If packages are specified with the -p flag, then a conservative
update of the lockfile will be performed. This means that only the
dependency specified by SPEC will be updated. Its transitive
dependencies will be updated only if SPEC cannot be updated without
updating dependencies. All other dependencies will remain locked at
their currently recorded versions.
If packages are specified with spec, then a conservative update of
the lockfile will be performed. This means that only the dependency
specified by SPEC will be updated. Its transitive dependencies will
be updated only if SPEC cannot be updated without updating
dependencies. All other dependencies will remain locked at their
currently recorded versions.

If -p is not specified, all dependencies are updated.
If spec is not specified, all dependencies are updated.

--aggressive
When used with -p, dependencies of spec are forced to update as
When used with spec, dependencies of spec are forced to update as
well. Cannot be used with --precise.

--precise precise
When used with -p, allows you to specify a specific version number
When used with spec, allows you to specify a specific version number
to set the package to. If the package comes from a git repository,
this can be a git revision (such as a SHA hash or tag).

Expand Down Expand Up @@ -155,11 +155,11 @@ EXAMPLES

2. Update only specific dependencies:

cargo update -p foo -p bar
cargo update foo bar

3. Set a specific dependency to a specific version:

cargo update -p foo --precise 1.2.3
cargo update foo --precise 1.2.3

SEE ALSO
cargo(1), cargo-generate-lockfile(1)
Expand Down
17 changes: 8 additions & 9 deletions src/doc/src/commands/cargo-update.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ cargo-update --- Update dependencies as recorded in the local lock file

## SYNOPSIS

`cargo update` [_options_]
`cargo update` [_options_] _spec_

## DESCRIPTION

Expand All @@ -20,25 +20,24 @@ latest available versions.

<dl>

<dt class="option-term" id="option-cargo-update--p"><a class="option-anchor" href="#option-cargo-update--p"></a><code>-p</code> <em>spec</em>…</dt>
<dt class="option-term" id="option-cargo-update---package"><a class="option-anchor" href="#option-cargo-update---package"></a><code>--package</code> <em>spec</em>…</dt>
<dt class="option-term" id="option-cargo-update-spec…"><a class="option-anchor" href="#option-cargo-update-spec…"></a><em>spec</em>…</dt>
<dd class="option-desc">Update only the specified packages. This flag may be specified
multiple times. See <a href="cargo-pkgid.html">cargo-pkgid(1)</a> for the SPEC format.</p>
<p>If packages are specified with the <code>-p</code> flag, then a conservative update of
<p>If packages are specified with <em>spec</em>, then a conservative update of
the lockfile will be performed. This means that only the dependency specified
by SPEC will be updated. Its transitive dependencies will be updated only if
SPEC cannot be updated without updating dependencies. All other dependencies
will remain locked at their currently recorded versions.</p>
<p>If <code>-p</code> is not specified, all dependencies are updated.</dd>
<p>If <em>spec</em> is not specified, all dependencies are updated.</dd>


<dt class="option-term" id="option-cargo-update---aggressive"><a class="option-anchor" href="#option-cargo-update---aggressive"></a><code>--aggressive</code></dt>
<dd class="option-desc">When used with <code>-p</code>, dependencies of <em>spec</em> are forced to update as well.
<dd class="option-desc">When used with <em>spec</em>, dependencies of <em>spec</em> are forced to update as well.
Cannot be used with <code>--precise</code>.</dd>


<dt class="option-term" id="option-cargo-update---precise"><a class="option-anchor" href="#option-cargo-update---precise"></a><code>--precise</code> <em>precise</em></dt>
<dd class="option-desc">When used with <code>-p</code>, allows you to specify a specific version number to set
<dd class="option-desc">When used with <em>spec</em>, allows you to specify a specific version number to set
the package to. If the package comes from a git repository, this can be a git
revision (such as a SHA hash or tag).</dd>

Expand Down Expand Up @@ -187,11 +186,11 @@ details on environment variables that Cargo reads.

2. Update only specific dependencies:

cargo update -p foo -p bar
cargo update foo bar

3. Set a specific dependency to a specific version:

cargo update -p foo --precise 1.2.3
cargo update foo --precise 1.2.3

## SEE ALSO
[cargo(1)](cargo.html), [cargo-generate-lockfile(1)](cargo-generate-lockfile.html)
4 changes: 2 additions & 2 deletions src/doc/src/guide/cargo-toml-vs-cargo-lock.md
Original file line number Diff line number Diff line change
Expand Up @@ -91,8 +91,8 @@ When we’re ready to opt in to a new version of the library, Cargo can
re-calculate the dependencies and update things for us:

```console
$ cargo update # updates all dependencies
$ cargo update -p regex # updates just “regex”
$ cargo update # updates all dependencies
$ cargo update regex # updates just “regex”
```

This will write out a new `Cargo.lock` with the new version information. Note
Expand Down
2 changes: 1 addition & 1 deletion src/doc/src/reference/overriding-dependencies.md
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ $ cargo build

And that's it! You're now building with the local version of `uuid` (note the
path in parentheses in the build output). If you don't see the local path version getting
built then you may need to run `cargo update -p uuid --precise $version` where
built then you may need to run `cargo update uuid --precise $version` where
`$version` is the version of the locally checked out copy of `uuid`.

Once you've fixed the bug you originally found the next thing you'll want to do
Expand Down
4 changes: 2 additions & 2 deletions src/doc/src/reference/resolver.md
Original file line number Diff line number Diff line change
Expand Up @@ -464,10 +464,10 @@ situations may require specifying unusual requirements.
If you fail to do this, it may not be immediately obvious because Cargo can
opportunistically choose the newest version when you run a blanket `cargo
update`. However, if another user depends on your library, and runs `cargo
update -p your-library`, it will *not* automatically update "bar" if it is
update your-library`, it will *not* automatically update "bar" if it is
locked in their `Cargo.lock`. It will only update "bar" in that situation if
the dependency declaration is also updated. Failure to do so can cause
confusing build errors for the user using `cargo update -p`.
confusing build errors for the user using `cargo update your-library`.
* If two packages are tightly coupled, then an `=` dependency requirement may
help ensure that they stay in sync. For example, a library with a companion
proc-macro library will sometimes make assumptions between the two libraries
Expand Down
2 changes: 1 addition & 1 deletion src/doc/src/reference/specifying-dependencies.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ The string `"0.1.12"` is a version requirement. Although it looks like a
specific *version* of the `time` crate, it actually specifies a *range* of
versions and allows [SemVer] compatible updates. An update is allowed if the new
version number does not modify the left-most non-zero number in the major, minor,
patch grouping. In this case, if we ran `cargo update -p time`, cargo should
patch grouping. In this case, if we ran `cargo update time`, cargo should
update us to version `0.1.13` if it is the latest `0.1.z` release, but would not
update us to `0.2.0`. If instead we had specified the version string as `1.0`,
cargo should update to `1.1` if it is the latest `1.y` release, but not `2.0`.
Expand Down
3 changes: 2 additions & 1 deletion src/etc/_cargo
Original file line number Diff line number Diff line change
Expand Up @@ -344,7 +344,8 @@ _cargo() {
'--aggressive=[force dependency update]' \
"--dry-run[don't actually write the lockfile]" \
'(-p --package)'{-p+,--package=}'[specify package to update]:package:_cargo_package_names' \
'--precise=[update single dependency to precise release]:release'
'--precise=[update single dependency to precise release]:release' \
'*:package:_cargo_package_names'
;;

verify-project)
Expand Down
17 changes: 8 additions & 9 deletions src/etc/man/cargo-update.1
Original file line number Diff line number Diff line change
Expand Up @@ -6,38 +6,37 @@
.SH "NAME"
cargo\-update \[em] Update dependencies as recorded in the local lock file
.SH "SYNOPSIS"
\fBcargo update\fR [\fIoptions\fR]
\fBcargo update\fR [\fIoptions\fR] \fIspec\fR
.SH "DESCRIPTION"
This command will update dependencies in the \fBCargo.lock\fR file to the latest
version. If the \fBCargo.lock\fR file does not exist, it will be created with the
latest available versions.
.SH "OPTIONS"
.SS "Update Options"
.sp
\fB\-p\fR \fIspec\fR\[u2026],
\fB\-\-package\fR \fIspec\fR\[u2026]
\fIspec\fR\[u2026]
.RS 4
Update only the specified packages. This flag may be specified
multiple times. See \fBcargo\-pkgid\fR(1) for the SPEC format.
.sp
If packages are specified with the \fB\-p\fR flag, then a conservative update of
If packages are specified with \fIspec\fR, then a conservative update of
the lockfile will be performed. This means that only the dependency specified
by SPEC will be updated. Its transitive dependencies will be updated only if
SPEC cannot be updated without updating dependencies. All other dependencies
will remain locked at their currently recorded versions.
.sp
If \fB\-p\fR is not specified, all dependencies are updated.
If \fIspec\fR is not specified, all dependencies are updated.
.RE
.sp
\fB\-\-aggressive\fR
.RS 4
When used with \fB\-p\fR, dependencies of \fIspec\fR are forced to update as well.
When used with \fIspec\fR, dependencies of \fIspec\fR are forced to update as well.
Cannot be used with \fB\-\-precise\fR\&.
.RE
.sp
\fB\-\-precise\fR \fIprecise\fR
.RS 4
When used with \fB\-p\fR, allows you to specify a specific version number to set
When used with \fIspec\fR, allows you to specify a specific version number to set
the package to. If the package comes from a git repository, this can be a git
revision (such as a SHA hash or tag).
.RE
Expand Down Expand Up @@ -200,7 +199,7 @@ cargo update
.sp
.RS 4
.nf
cargo update \-p foo \-p bar
cargo update foo bar
.fi
.RE
.RE
Expand All @@ -210,7 +209,7 @@ cargo update \-p foo \-p bar
.sp
.RS 4
.nf
cargo update \-p foo \-\-precise 1.2.3
cargo update foo \-\-precise 1.2.3
.fi
.RE
.RE
Expand Down
Loading

0 comments on commit 94770a5

Please sign in to comment.