From 076b41c749f4065aa3c71597bc0481456e52d410 Mon Sep 17 00:00:00 2001 From: Mike Garde Date: Sun, 26 Jul 2026 20:11:22 -0400 Subject: [PATCH 1/2] Fix newline handling when appending to .env - Ensure appending a new entry inserts a leading newline if the existing content lacks a trailing one, so the new key starts on its own line. - Extend tests/set_and_delete.rs to cover the newline-edge case: when the file has no trailing newline, adding a new key appends on its own line and the final content ends with a newline; verify both keys are readable via --file. --- src/handlers/set_value.rs | 6 ++++++ tests/set_and_delete.rs | 36 ++++++++++++++++++++++++++++++++++++ 2 files changed, 42 insertions(+) diff --git a/src/handlers/set_value.rs b/src/handlers/set_value.rs index 6223af2..c406bdd 100644 --- a/src/handlers/set_value.rs +++ b/src/handlers/set_value.rs @@ -34,10 +34,16 @@ pub fn set_value(options: &Options) { fs::write(&options.full_env_path, lines.join("\n")).expect("Failed to write .env file"); } else { // Append new key to end of file + let existing = fs::read(&options.full_env_path).expect("Failed to read .env file"); + let needs_leading_newline = !existing.is_empty() && existing.last() != Some(&b'\n'); + let mut file = fs::OpenOptions::new() .append(true) .open(&options.full_env_path) .expect("Failed to open .env file for appending"); + if needs_leading_newline { + write!(file, "\n").expect("Failed to append to .env file"); + } writeln!(file, "{}", new_line).expect("Failed to append to .env file"); } } diff --git a/tests/set_and_delete.rs b/tests/set_and_delete.rs index 6d3a917..5deb1d1 100644 --- a/tests/set_and_delete.rs +++ b/tests/set_and_delete.rs @@ -464,3 +464,39 @@ fn add_and_delete_single_key_preserves_file() { hash2 ); } + +#[test] +fn add_key_to_file_without_trailing_newline() { + use std::io::Write; + let mut tmp = NamedTempFile::new().unwrap(); + tmp.write_all(b"FOO=bar").unwrap(); // deliberately no trailing newline + tmp.flush().unwrap(); + + bin() + .arg("BAZ") + .arg("--set") + .arg("qux") + .arg("--file") + .arg(tmp.path()) + .assert() + .success(); + + // Both keys must be readable and intact. + bin() + .arg("FOO") + .arg("--file") + .arg(tmp.path()) + .assert() + .success() + .stdout("bar\n"); + bin() + .arg("BAZ") + .arg("--file") + .arg(tmp.path()) + .assert() + .success() + .stdout("qux\n"); + + let content = fs::read_to_string(tmp.path()).unwrap(); + assert_eq!(content, "FOO=bar\nBAZ=qux\n"); +} From f0d688432ec0a97dcf1e3e08aa718b940c543698 Mon Sep 17 00:00:00 2001 From: Mike Garde Date: Sun, 26 Jul 2026 20:17:06 -0400 Subject: [PATCH 2/2] lint fix --- Taskfile.yaml | 5 +++++ src/handlers/set_value.rs | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/Taskfile.yaml b/Taskfile.yaml index d57fc08..46705f3 100644 --- a/Taskfile.yaml +++ b/Taskfile.yaml @@ -22,6 +22,11 @@ tasks: - cargo clippy --all-targets --all-features -- -D warnings - cargo test --all-features + lint:fix: + desc: "Auto-fix clippy lints where possible (same scope as `task test`)" + cmds: + - cargo clippy --fix --all-targets --all-features --allow-dirty --allow-staged + build: desc: "Build debug binary for the host" silent: true diff --git a/src/handlers/set_value.rs b/src/handlers/set_value.rs index c406bdd..d689d80 100644 --- a/src/handlers/set_value.rs +++ b/src/handlers/set_value.rs @@ -42,7 +42,7 @@ pub fn set_value(options: &Options) { .open(&options.full_env_path) .expect("Failed to open .env file for appending"); if needs_leading_newline { - write!(file, "\n").expect("Failed to append to .env file"); + writeln!(file).expect("Failed to append to .env file"); } writeln!(file, "{}", new_line).expect("Failed to append to .env file"); }