Skip to content

Commit b5c4a76

Browse files
committed
fix(add): Respect --locked
This is prep for #10901 to avoid the most common failure case for the lock file. We are assuming if the users action caused a change in the manifes, then it will cause a change in the lock file. This isn't entirely true but close enough and I think these semantics can make sense.
1 parent 85b500c commit b5c4a76

File tree

14 files changed

+97
-2
lines changed

14 files changed

+97
-2
lines changed

src/cargo/ops/cargo_add/manifest.rs

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -238,8 +238,7 @@ impl str::FromStr for Manifest {
238238

239239
impl std::fmt::Display for Manifest {
240240
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
241-
let s = self.data.to_string();
242-
s.fmt(f)
241+
self.data.fmt(f)
243242
}
244243
}
245244

@@ -433,6 +432,12 @@ impl LocalManifest {
433432
}
434433
}
435434

435+
impl std::fmt::Display for LocalManifest {
436+
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
437+
self.manifest.fmt(f)
438+
}
439+
}
440+
436441
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord)]
437442
enum DependencyStatus {
438443
None,

src/cargo/ops/cargo_add/mod.rs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@ pub fn add(workspace: &Workspace<'_>, options: &AddOptions<'_>) -> CargoResult<(
6262

6363
let manifest_path = options.spec.manifest_path().to_path_buf();
6464
let mut manifest = LocalManifest::try_new(&manifest_path)?;
65+
let original_raw_manifest = manifest.to_string();
6566
let legacy = manifest.get_legacy_sections();
6667
if !legacy.is_empty() {
6768
anyhow::bail!(
@@ -142,6 +143,16 @@ pub fn add(workspace: &Workspace<'_>, options: &AddOptions<'_>) -> CargoResult<(
142143
}
143144
}
144145

146+
if options.config.locked() {
147+
let new_raw_manifest = manifest.to_string();
148+
if original_raw_manifest != new_raw_manifest {
149+
anyhow::bail!(
150+
"the manifest file {} needs to be updated but --locked was passed to prevent this",
151+
manifest.path.display()
152+
);
153+
}
154+
}
155+
145156
if options.dry_run {
146157
options.config.shell().warn("aborting add due to dry run")?;
147158
} else {
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
../add-basic.in
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
use cargo_test_support::compare::assert_ui;
2+
use cargo_test_support::prelude::*;
3+
use cargo_test_support::Project;
4+
5+
use crate::cargo_add::init_registry;
6+
use cargo_test_support::curr_dir;
7+
8+
#[cargo_test]
9+
fn locked_changed() {
10+
init_registry();
11+
let project = Project::from_template(curr_dir!().join("in"));
12+
let project_root = project.root();
13+
let cwd = &project_root;
14+
15+
snapbox::cmd::Command::cargo_ui()
16+
.arg("add")
17+
.arg_line("my-package --locked")
18+
.current_dir(cwd)
19+
.assert()
20+
.failure()
21+
.stdout_matches_path(curr_dir!().join("stdout.log"))
22+
.stderr_matches_path(curr_dir!().join("stderr.log"));
23+
24+
assert_ui().subset_matches(curr_dir!().join("out"), &project_root);
25+
}
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
[workspace]
2+
3+
[package]
4+
name = "cargo-list-test-fixture"
5+
version = "0.0.0"
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
Updating `dummy-registry` index
2+
Adding my-package v99999.0.0 to dependencies.
3+
error: the manifest file [ROOT]/case/Cargo.toml needs to be updated but --locked was passed to prevent this

tests/testsuite/cargo_add/locked_changed/stdout.log

Whitespace-only changes.
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
[workspace]
2+
3+
[package]
4+
name = "cargo-list-test-fixture"
5+
version = "0.0.0"
6+
7+
[dependencies]
8+
my-package = "99999.0.0"

tests/testsuite/cargo_add/locked_unchanged/in/src/lib.rs

Whitespace-only changes.
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
use cargo_test_support::compare::assert_ui;
2+
use cargo_test_support::prelude::*;
3+
use cargo_test_support::Project;
4+
5+
use crate::cargo_add::init_registry;
6+
use cargo_test_support::curr_dir;
7+
8+
#[cargo_test]
9+
fn locked_unchanged() {
10+
init_registry();
11+
let project = Project::from_template(curr_dir!().join("in"));
12+
let project_root = project.root();
13+
let cwd = &project_root;
14+
15+
snapbox::cmd::Command::cargo_ui()
16+
.arg("add")
17+
.arg_line("my-package --locked")
18+
.current_dir(cwd)
19+
.assert()
20+
.success()
21+
.stdout_matches_path(curr_dir!().join("stdout.log"))
22+
.stderr_matches_path(curr_dir!().join("stderr.log"));
23+
24+
assert_ui().subset_matches(curr_dir!().join("out"), &project_root);
25+
}

0 commit comments

Comments
 (0)