Skip to content

Commit 1708e12

Browse files
fix: Preserve symlinks when running cargo add
When Cargo.toml is a symlink, cargo add was overwriting it with a regular file. This change follows the symlink and writes to the target file instead, preserving the symlink structure. Fixes rust-lang#15241
1 parent b5147ac commit 1708e12

File tree

2 files changed

+11
-4
lines changed

2 files changed

+11
-4
lines changed

src/cargo/util/toml_mut/manifest.rs

+10-2
Original file line numberDiff line numberDiff line change
@@ -297,6 +297,7 @@ impl LocalManifest {
297297
})
298298
}
299299

300+
/// Write changes back to the file.
300301
/// Write changes back to the file.
301302
pub fn write(&self) -> CargoResult<()> {
302303
let mut manifest = self.manifest.data.to_string();
@@ -323,9 +324,16 @@ impl LocalManifest {
323324
};
324325
let new_contents_bytes = raw.as_bytes();
325326

326-
cargo_util::paths::write_atomic(&self.path, new_contents_bytes)
327-
}
327+
// Check if the path is a symlink and follow it if it is
328+
let actual_path = if self.path.is_symlink() {
329+
std::fs::read_link(&self.path)?
330+
} else {
331+
self.path.clone()
332+
};
328333

334+
// Write to the actual target path instead of the symlink
335+
cargo_util::paths::write_atomic(&actual_path, new_contents_bytes)
336+
}
329337
/// Lookup a dependency.
330338
pub fn get_dependency_versions<'s>(
331339
&'s self,

tests/testsuite/cargo_add/symlink.rs

+1-2
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,5 @@ fn symlink_case() {
4747

4848
project.cargo("add test-dep").run();
4949

50-
// The bug: symlink is replaced by a regular file
51-
assert!(!project.root().join("Cargo.toml").is_symlink());
50+
assert!(project.root().join("Cargo.toml").is_symlink());
5251
}

0 commit comments

Comments
 (0)