diff --git a/crates/nu-command/src/filesystem/save.rs b/crates/nu-command/src/filesystem/save.rs index f8c8a46a1b..48d1074873 100644 --- a/crates/nu-command/src/filesystem/save.rs +++ b/crates/nu-command/src/filesystem/save.rs @@ -24,6 +24,7 @@ impl Command for Save { Signature::build("save") .required("filename", SyntaxShape::Filepath, "the filename to use") .switch("raw", "save file as raw binary", Some('r')) + .switch("append", "append input to the end of the file", None) .category(Category::FileSystem) } @@ -35,6 +36,7 @@ impl Command for Save { input: PipelineData, ) -> Result { let raw = call.has_flag("raw"); + let append = call.has_flag("append"); let span = call.head; @@ -42,7 +44,15 @@ impl Command for Save { let arg_span = path.span; let path = Path::new(&path.item); - let mut file = match std::fs::File::create(path) { + let file = match (append, path.exists()) { + (true, true) => std::fs::OpenOptions::new() + .write(true) + .append(true) + .open(path), + _ => std::fs::File::create(path), + }; + + let mut file = match file { Ok(file) => file, Err(err) => { return Ok(PipelineData::Value( diff --git a/crates/nu-command/tests/commands/save.rs b/crates/nu-command/tests/commands/save.rs index 7a82867ad9..95f82c31c6 100644 --- a/crates/nu-command/tests/commands/save.rs +++ b/crates/nu-command/tests/commands/save.rs @@ -1,6 +1,7 @@ use nu_test_support::fs::{file_contents, Stub::FileWithContent}; use nu_test_support::nu; use nu_test_support::playground::Playground; +use std::io::Write; #[test] fn figures_out_intelligently_where_to_write_out_with_metadata() { @@ -48,8 +49,6 @@ fn writes_out_csv() { }) } -// FIXME: jt: needs more work -#[ignore] #[test] fn save_append_will_create_file_if_not_exists() { Playground::setup("save_test_3", |dirs, sandbox| { @@ -64,6 +63,31 @@ fn save_append_will_create_file_if_not_exists() { let actual = file_contents(expected_file); println!("{}", actual); - assert!(actual == "hello"); + assert_eq!(actual, "hello"); + }) +} + +#[test] +fn save_append_will_not_overwrite_content() { + Playground::setup("save_test_4", |dirs, sandbox| { + sandbox.with_files(vec![]); + + let expected_file = dirs.test().join("new-file.txt"); + + { + let mut file = + std::fs::File::create(&expected_file).expect("Failed to create test file"); + file.write_all("hello ".as_bytes()) + .expect("Failed to write to test file") + } + + nu!( + cwd: dirs.root(), + r#"echo world | save --append save_test_4/new-file.txt"#, + ); + + let actual = file_contents(expected_file); + println!("{}", actual); + assert_eq!(actual, "hello world"); }) }