Skip to content

Commit

Permalink
Added logic to preserve carriage returns when updating the manifest file
Browse files Browse the repository at this point in the history
  • Loading branch information
ranger-ross committed Dec 26, 2024
1 parent 0276088 commit 791460f
Show file tree
Hide file tree
Showing 13 changed files with 194 additions and 1 deletion.
33 changes: 32 additions & 1 deletion src/cargo/util/toml_mut/manifest.rs
Original file line number Diff line number Diff line change
Expand Up @@ -300,7 +300,7 @@ impl LocalManifest {
/// Write changes back to the file.
pub fn write(&self) -> CargoResult<()> {
let mut manifest = self.manifest.data.to_string();
let raw = match self.embedded.as_ref() {
let mut raw = match self.embedded.as_ref() {
Some(Embedded::Implicit(start)) => {
if !manifest.ends_with("\n") {
manifest.push_str("\n");
Expand All @@ -321,6 +321,11 @@ impl LocalManifest {
}
None => manifest,
};

if self.is_crlf() {
raw = to_crlf_line_ending(&raw);
}

let new_contents_bytes = raw.as_bytes();

cargo_util::paths::write_atomic(&self.path, new_contents_bytes)
Expand Down Expand Up @@ -566,6 +571,10 @@ impl LocalManifest {
}
status
}

fn is_crlf(&self) -> bool {
return self.raw.contains("\r\n");
}
}

impl std::fmt::Display for LocalManifest {
Expand Down Expand Up @@ -753,3 +762,25 @@ fn remove_array_index(array: &mut toml_edit::Array, index: usize) {
array.set_trailing(merged_lines);
}
}

fn to_crlf_line_ending(input: &str) -> String {
let mut result = String::with_capacity(input.len());
let mut chars = input.chars().peekable();

while let Some(c) = chars.next() {
match c {
'\r' if chars.peek() == Some(&'\n') => {
chars.next();
result.push('\r');
result.push('\n');
}
'\n' => {
result.push('\r');
result.push('\n');
}
_ => result.push(c),
}
}

result
}
1 change: 1 addition & 0 deletions tests/testsuite/cargo_add/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,7 @@ mod path_base_unstable;
mod path_dev;
mod path_inferred_name;
mod path_inferred_name_conflicts_full_feature;
mod preserve_carriage_returns;
mod preserve_dep_std_table;
mod preserve_features_sorted;
mod preserve_features_table;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
[workspace]

[package]
name = "cargo-list-test-fixture"
version = "0.0.0"
edition = "2015"
Empty file.
36 changes: 36 additions & 0 deletions tests/testsuite/cargo_add/preserve_carriage_returns/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
use cargo_test_support::compare::assert_ui;
use cargo_test_support::current_dir;
use cargo_test_support::file;
use cargo_test_support::prelude::*;
use cargo_test_support::str;
use cargo_test_support::Project;

#[cargo_test]
fn case() {
cargo_test_support::registry::init();
cargo_test_support::registry::Package::new("my-package", "0.1.0").publish();

let project = Project::from_template(current_dir!().join("in"));
let project_root = project.root();
let cwd = &project_root;

snapbox::cmd::Command::cargo_ui()
.arg("add")
.arg_line("my-package")
.current_dir(cwd)
.assert()
.success()
.stdout_eq(str![""])
.stderr_eq(file!["stderr.term.svg"]);

// Verify the content matches first (for nicer error output)
assert_ui().subset_matches(current_dir!().join("out"), &project_root);

// Snapbox normalizes lines so we also need to do a string comparision to verify line endings
let expected = current_dir!().join("out/Cargo.toml");
let actual = project_root.join("Cargo.toml");
assert_eq!(
std::fs::read_to_string(expected).unwrap(),
std::fs::read_to_string(actual).unwrap()
);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
[workspace]

[package]
name = "cargo-list-test-fixture"
version = "0.0.0"
edition = "2015"

[dependencies]
my-package = "0.1.0"
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions tests/testsuite/cargo_remove/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ mod optional_dep_feature;
mod optional_dep_feature_formatting;
mod optional_feature;
mod package;
mod preserve_carriage_returns;
mod remove_basic;
mod script;
mod script_last;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
[workspace]

[package]
name = "cargo-list-test-fixture"
version = "0.0.0"
edition = "2015"

[dependencies]
my-package = "0.1.0"
Empty file.
36 changes: 36 additions & 0 deletions tests/testsuite/cargo_remove/preserve_carriage_returns/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
use cargo_test_support::compare::assert_ui;
use cargo_test_support::current_dir;
use cargo_test_support::file;
use cargo_test_support::prelude::*;
use cargo_test_support::str;
use cargo_test_support::Project;

#[cargo_test]
fn case() {
cargo_test_support::registry::init();
cargo_test_support::registry::Package::new("my-package", "0.1.0").publish();

let project = Project::from_template(current_dir!().join("in"));
let project_root = project.root();
let cwd = &project_root;

snapbox::cmd::Command::cargo_ui()
.arg("remove")
.arg_line("my-package")
.current_dir(cwd)
.assert()
.success()
.stdout_eq(str![""])
.stderr_eq(file!["stderr.term.svg"]);

// Verify the content matches first (for nicer error output)
assert_ui().subset_matches(current_dir!().join("out"), &project_root);

// Snapbox normalizes lines so we also need to do a string comparision to verify line endings
let expected = current_dir!().join("out/Cargo.toml");
let actual = project_root.join("Cargo.toml");
assert_eq!(
std::fs::read_to_string(expected).unwrap(),
std::fs::read_to_string(actual).unwrap()
);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
[workspace]

[package]
name = "cargo-list-test-fixture"
version = "0.0.0"
edition = "2015"
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.

0 comments on commit 791460f

Please sign in to comment.