From 2565d63acf13f4c658c569293fcf525cd08fbe8d Mon Sep 17 00:00:00 2001 From: Hulto Date: Fri, 18 Mar 2022 22:07:53 +0000 Subject: [PATCH] File.Moveto method implemented, tested, and doc'd --- docs/_docs/user-guide/eldritch.md | 6 +- implants/eldritch/src/file.rs | 4 +- implants/eldritch/src/file/moveto_impl.rs | 102 ++++++++++++++++++++++ implants/eldritch/src/file/rename_impl.rs | 5 -- 4 files changed, 107 insertions(+), 10 deletions(-) create mode 100644 implants/eldritch/src/file/moveto_impl.rs delete mode 100644 implants/eldritch/src/file/rename_impl.rs diff --git a/docs/_docs/user-guide/eldritch.md b/docs/_docs/user-guide/eldritch.md index 2a22115ee..4e15a1c27 100644 --- a/docs/_docs/user-guide/eldritch.md +++ b/docs/_docs/user-guide/eldritch.md @@ -59,10 +59,10 @@ The file.read method is very cool, and will be even cooler when Nick docu The file.remove method is very cool, and will be even cooler when Nick documents it. -### file.rename -`file.rename(src: str, dst: str) -> None` +### file.moveto +`file.moveto(src: str, dst: str) -> None` -The file.rename method is very cool, and will be even cooler when Nick documents it. +The file.moveto method will move a file or directory from src to dst. If the dst directory or file exists it will be deleted before being replaced. To ensure consistency across systems. ### file.replace `file.replace(path: str, pattern: str, value: str) -> diff --git a/implants/eldritch/src/file.rs b/implants/eldritch/src/file.rs index 305ed0a96..10c98f133 100644 --- a/implants/eldritch/src/file.rs +++ b/implants/eldritch/src/file.rs @@ -7,7 +7,7 @@ mod is_dir_impl; mod mkdir_impl; mod read_impl; mod remove_impl; -mod rename_impl; +mod moveto_impl; mod replace_all_impl; mod replace_impl; mod timestomp_impl; @@ -80,7 +80,7 @@ fn methods(builder: &mut MethodsBuilder) { Ok(NoneType{}) } fn rename(_this: FileLibrary, old: String, new: String) -> NoneType { - rename_impl::rename(old, new)?; + moveto_impl::moveto(old, new)?; Ok(NoneType{}) } fn replace_all(_this: FileLibrary, path: String, pattern: String, value: String) -> NoneType { diff --git a/implants/eldritch/src/file/moveto_impl.rs b/implants/eldritch/src/file/moveto_impl.rs new file mode 100644 index 000000000..5c0d1dd0e --- /dev/null +++ b/implants/eldritch/src/file/moveto_impl.rs @@ -0,0 +1,102 @@ +use anyhow::Result; +use std::fs; +use std::path::Path; + +pub fn moveto(old: String, new: String) -> Result<()> { + // If path is a dir delete it. + // This will help unify behavior across systems. + // https://doc.rust-lang.org/std/fs/fn.rename.html#platform-specific-behavior + if Path::new(&new.clone()).is_dir() { + fs::remove_dir_all(new.clone())?; + } else if Path::new(&new.clone()).is_file() { + fs::remove_file(new.clone())?; + } + + fs::rename(old, new)?; + Ok(()) +} + + +#[cfg(test)] +mod tests { + use super::*; + use tempfile::{NamedTempFile,tempdir}; + use std::path::Path; + use std::fs::File; + + #[test] + fn test_moveto_dir() -> anyhow::Result<()>{ + let tmp_dir = tempdir()?; + let path_old = String::from(tmp_dir.path().to_str().unwrap()).clone(); + let tmp_dir_new = tempdir()?; + let path_new = String::from(tmp_dir_new.path().to_str().unwrap()).clone(); + tmp_dir_new.close()?; + + + moveto(path_old.clone(), path_new.clone())?; + + assert_eq!(Path::new(&path_old).is_dir(), false); + assert_eq!(Path::new(&path_new).is_dir(), true); + Ok(()) + } + #[test] + fn test_moveto_file() -> anyhow::Result<()>{ + let tmp_file = NamedTempFile::new()?; + let path_old = String::from(tmp_file.path().to_str().unwrap()).clone(); + let tmp_file_new = NamedTempFile::new()?; + let path_new = String::from(tmp_file_new.path().to_str().unwrap()).clone(); + tmp_file_new.close()?; + // Run our code + + moveto(path_old.clone(), path_new.clone())?; + + assert_eq!(Path::new(&path_old).is_file(), false); + assert_eq!(Path::new(&path_new).is_file(), true); + Ok(()) + } + #[test] + fn test_moveto_file_overwrites() -> anyhow::Result<()>{ + let tmp_file = NamedTempFile::new()?; + let path_old = String::from(tmp_file.path().to_str().unwrap()).clone(); + let tmp_file_new = NamedTempFile::new()?; + let path_new = String::from(tmp_file_new.path().to_str().unwrap()).clone(); + // Run our code + + moveto(path_old.clone(), path_new.clone())?; + + assert_eq!(Path::new(&path_old).is_file(), false); + assert_eq!(Path::new(&path_new).is_file(), true); + Ok(()) + } + #[test] + fn test_moveto_dir_overwrites() -> anyhow::Result<()>{ + // Create initial directory and file. + let tmp_dir = tempdir()?; + let tmp_dir_path = tmp_dir.path(); + + let path_old = String::from(tmp_dir_path.to_str().unwrap()).clone(); + let path_old_file = String::from(tmp_dir_path.join("myfile2").to_str().unwrap()).clone(); + let _ = File::create(path_old_file.clone())?; + let _ = fs::write(path_old_file.clone(),"Hello"); + + // Create destination directory and the file path we expect after moveto "win" + let tmp_dir_new = tempdir()?; + let path_new = String::from(tmp_dir_new.path().to_str().unwrap()).clone(); + let path_new_file = String::from(tmp_dir_new.path().join("myfile").to_str().unwrap()).clone(); + let path_new_file_win = String::from(tmp_dir_new.path().join("myfile2").to_str().unwrap()).clone(); + + let _ = File::create(path_new_file.clone())?; + + + // Run our code + moveto(path_old.clone(), path_new.clone())?; + + // Assert + assert_eq!(Path::new(&path_old).is_dir(), false); + assert_eq!(Path::new(&path_new_file_win).is_file(), true); + assert_eq!(Path::new(&path_new_file).is_file(), false); + assert_eq!(Path::new(&path_new).is_dir(), true); + Ok(()) + } + +} diff --git a/implants/eldritch/src/file/rename_impl.rs b/implants/eldritch/src/file/rename_impl.rs deleted file mode 100644 index 4aca5e54b..000000000 --- a/implants/eldritch/src/file/rename_impl.rs +++ /dev/null @@ -1,5 +0,0 @@ -use anyhow::Result; - -pub fn rename(_old: String, _new: String) -> Result<()> { - unimplemented!("Method unimplemented") -} \ No newline at end of file