diff --git a/src/bin/cargo/commands/update.rs b/src/bin/cargo/commands/update.rs index 34bab9f757e..771957169af 100644 --- a/src/bin/cargo/commands/update.rs +++ b/src/bin/cargo/commands/update.rs @@ -7,6 +7,7 @@ pub fn cli() -> App { subcommand("update") .about("Update dependencies as recorded in the local lock file") .arg(opt("quiet", "No output printed to stdout").short("q")) + .arg(opt("workspace", "Only update the workspace packages").short("w")) .arg_package_spec_simple("Package to update") .arg(opt( "aggressive", @@ -30,6 +31,7 @@ pub fn exec(config: &mut Config, args: &ArgMatches<'_>) -> CliResult { precise: args.value_of("precise"), to_update: values(args, "package"), dry_run: args.is_present("dry-run"), + workspace: args.is_present("workspace"), config, }; ops::update_lockfile(&ws, &update_opts)?; diff --git a/src/cargo/ops/cargo_generate_lockfile.rs b/src/cargo/ops/cargo_generate_lockfile.rs index a86b34e3ae0..0040bc9b0d6 100644 --- a/src/cargo/ops/cargo_generate_lockfile.rs +++ b/src/cargo/ops/cargo_generate_lockfile.rs @@ -17,6 +17,7 @@ pub struct UpdateOptions<'a> { pub precise: Option<&'a str>, pub aggressive: bool, pub dry_run: bool, + pub workspace: bool, } pub fn generate_lockfile(ws: &Workspace<'_>) -> CargoResult<()> { @@ -78,8 +79,10 @@ pub fn update_lockfile(ws: &Workspace<'_>, opts: &UpdateOptions<'_>) -> CargoRes let mut to_avoid = HashSet::new(); if opts.to_update.is_empty() { - to_avoid.extend(previous_resolve.iter()); - to_avoid.extend(previous_resolve.unused_patches()); + if !opts.workspace { + to_avoid.extend(previous_resolve.iter()); + to_avoid.extend(previous_resolve.unused_patches()); + } } else { let mut sources = Vec::new(); for name in opts.to_update.iter() { diff --git a/src/doc/man/cargo-update.md b/src/doc/man/cargo-update.md index 3bca1982c66..54aa90ae846 100644 --- a/src/doc/man/cargo-update.md +++ b/src/doc/man/cargo-update.md @@ -44,6 +44,13 @@ 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}} +{{#option "`-w`" "`--workspace`" }} +Attempt to update only packages defined in the workspace. Other packages +are updated only if they don't already exist in the lockfile. This +option is useful for updating `Cargo.lock` after you've changed version +numbers in `Cargo.toml`. +{{/option}} + {{#option "`--dry-run`" }} Displays what would be updated, but doesn't actually write the lockfile. {{/option}} diff --git a/src/doc/man/generated_txt/cargo-update.txt b/src/doc/man/generated_txt/cargo-update.txt index be3e8067962..b2232fd2fba 100644 --- a/src/doc/man/generated_txt/cargo-update.txt +++ b/src/doc/man/generated_txt/cargo-update.txt @@ -35,6 +35,12 @@ OPTIONS 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). + -w, --workspace + Attempt to update only packages defined in the workspace. Other + packages are updated only if they don't already exist in the + lockfile. This option is useful for updating Cargo.lock after you've + changed version numbers in Cargo.toml. + --dry-run Displays what would be updated, but doesn't actually write the lockfile. diff --git a/src/doc/src/commands/cargo-update.md b/src/doc/src/commands/cargo-update.md index ac2f7a36853..8b974d79381 100644 --- a/src/doc/src/commands/cargo-update.md +++ b/src/doc/src/commands/cargo-update.md @@ -43,6 +43,14 @@ the package to. If the package comes from a git repository, this can be a git revision (such as a SHA hash or tag). +
-w
+
--workspace
+
Attempt to update only packages defined in the workspace. Other packages +are updated only if they don't already exist in the lockfile. This +option is useful for updating Cargo.lock after you've changed version +numbers in Cargo.toml.
+ +
--dry-run
Displays what would be updated, but doesn't actually write the lockfile.
diff --git a/src/etc/man/cargo-update.1 b/src/etc/man/cargo-update.1 index 1d531394e2c..ee977985480 100644 --- a/src/etc/man/cargo-update.1 +++ b/src/etc/man/cargo-update.1 @@ -42,6 +42,15 @@ 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 .sp +\fB\-w\fR, +\fB\-\-workspace\fR +.RS 4 +Attempt to update only packages defined in the workspace. Other packages +are updated only if they don't already exist in the lockfile. This +option is useful for updating \fBCargo.lock\fR after you've changed version +numbers in \fBCargo.toml\fR\&. +.RE +.sp \fB\-\-dry\-run\fR .RS 4 Displays what would be updated, but doesn't actually write the lockfile. diff --git a/tests/testsuite/update.rs b/tests/testsuite/update.rs index dd5b3ff5afb..6148bd3d6f2 100644 --- a/tests/testsuite/update.rs +++ b/tests/testsuite/update.rs @@ -649,3 +649,28 @@ fn dry_run_update() { let new_lockfile = p.read_lockfile(); assert_eq!(old_lockfile, new_lockfile) } + +#[cargo_test] +fn workspace_only() { + let p = project().file("src/main.rs", "fn main() {}").build(); + p.cargo("generate-lockfile").run(); + let lock1 = p.read_lockfile(); + + p.change_file( + "Cargo.toml", + r#" + [package] + name = "foo" + authors = [] + version = "0.0.2" + "#, + ); + p.cargo("update --workspace").run(); + let lock2 = p.read_lockfile(); + + assert_ne!(lock1, lock2); + assert!(lock1.contains("0.0.1")); + assert!(lock2.contains("0.0.2")); + assert!(!lock1.contains("0.0.2")); + assert!(!lock2.contains("0.0.1")); +}