Skip to content

Commit 4e56aea

Browse files
committed
Handle modifying rc files that don't have a trailing newline
1 parent 31ebf26 commit 4e56aea

File tree

2 files changed

+54
-7
lines changed

2 files changed

+54
-7
lines changed

src/cli/self_update/unix.rs

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -83,14 +83,20 @@ pub fn do_remove_from_path() -> Result<()> {
8383
pub fn do_add_to_path() -> Result<()> {
8484
for sh in shell::get_available_shells() {
8585
let source_cmd = sh.source_string()?;
86+
let source_cmd_with_newline = format!("\n{}", &source_cmd);
87+
8688
for rc in sh.update_rcs() {
87-
if !rc.is_file() || !utils::read_file("rcfile", &rc)?.contains(&source_cmd) {
88-
utils::append_file("rcfile", &rc, &source_cmd).chain_err(|| {
89-
ErrorKind::WritingShellProfile {
90-
path: rc.to_path_buf(),
91-
}
92-
})?;
93-
}
89+
let cmd_to_write = match utils::read_file("rcfile", &rc) {
90+
Ok(contents) if contents.contains(&source_cmd) => continue,
91+
Ok(contents) if !contents.ends_with('\n') => &source_cmd_with_newline,
92+
_ => &source_cmd,
93+
};
94+
95+
utils::append_file("rcfile", &rc, &cmd_to_write).chain_err(|| {
96+
ErrorKind::WritingShellProfile {
97+
path: rc.to_path_buf(),
98+
}
99+
})?;
94100
}
95101
}
96102

tests/cli-paths.rs

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -157,6 +157,47 @@ export PATH="$HOME/apple/bin"
157157
});
158158
}
159159

160+
#[test]
161+
fn install_adds_path_to_rc_handling_no_newline() {
162+
clitools::setup(Scenario::Empty, &|config| {
163+
let profile = config.homedir.join(".profile");
164+
let fake_rc_modified = FAKE_RC.strip_suffix('\n').expect("Should end in a newline");
165+
raw::write_file(&profile, fake_rc_modified).unwrap();
166+
// Run once to to add the configuration
167+
expect_ok(config, &INIT_NONE);
168+
// Run twice to test that the process is idempotent
169+
expect_ok(config, &INIT_NONE);
170+
171+
let new_profile = fs::read_to_string(&profile).unwrap();
172+
let expected = FAKE_RC.to_owned() + &source(config.cargodir.display(), POSIX_SH);
173+
assert_eq!(new_profile, expected);
174+
});
175+
}
176+
177+
#[test]
178+
fn install_adds_path_to_multiple_rc_files() {
179+
clitools::setup(Scenario::Empty, &|config| {
180+
// Two RC files that are both from the same shell
181+
let bash_profile = config.homedir.join(".bash_profile");
182+
let bashrc = config.homedir.join(".bashrc");
183+
184+
let expected = FAKE_RC.to_owned() + &source(config.cargodir.display(), POSIX_SH);
185+
186+
// The order that the two files are processed isn't known, so test both orders
187+
for [path1, path2] in &[[&bash_profile, &bashrc], [&bashrc, &bash_profile]] {
188+
raw::write_file(&path1, &expected).unwrap();
189+
raw::write_file(&path2, FAKE_RC).unwrap();
190+
191+
expect_ok(config, &INIT_NONE);
192+
193+
let new1 = fs::read_to_string(&path1).unwrap();
194+
assert_eq!(new1, expected);
195+
let new2 = fs::read_to_string(&path2).unwrap();
196+
assert_eq!(new2, expected);
197+
}
198+
});
199+
}
200+
160201
#[test]
161202
fn uninstall_removes_source_from_rcs() {
162203
clitools::setup(Scenario::Empty, &|config| {

0 commit comments

Comments
 (0)