coliru

A minimal, flexible, dotfile installer
git clone https://git.ashermorgan.net/coliru/
Log | Files | Refs | README

commit ef67865a71a4d6d529eb0f63bbdf0dface3c7f6f
parent f6cb8657e72a42d520b1a132b521a3d2e6c6a118
Author: Asher Morgan <59518073+ashermorgan@users.noreply.github.com>
Date:   Fri, 28 Jun 2024 10:44:54 -0700

Prevent copy and link from overwriting source file

Diffstat:
Msrc/utils.rs | 33+++++++++++++++++++++++++++++++++
1 file changed, 33 insertions(+), 0 deletions(-)

diff --git a/src/utils.rs b/src/utils.rs @@ -11,6 +11,7 @@ use std::process::Command; /// Tildes are expanded if present and the destination file is overwritten if /// necessary. pub fn copy_file(src: &str, dst: &str) -> io::Result<()> { + if absolute(src)? == absolute(dst)? { return Ok(()); } let _dst = prepare_path(dst)?; fs::copy(src, _dst)?; Ok(()) @@ -22,12 +23,14 @@ pub fn copy_file(src: &str, dst: &str) -> io::Result<()> { /// necessary. On non-Unix platforms, a hard link will be created instead. #[cfg(target_family = "unix")] pub fn link_file(src: &str, dst: &str) -> io::Result<()> { + if absolute(src)? == absolute(dst)? { return Ok(()); } let _dst = prepare_path(dst)?; symlink(fs::canonicalize(src)?, _dst)?; Ok(()) } #[cfg(not(target_family = "unix"))] pub fn link_file(src: &str, dst: &str) -> io::Result<()> { + if absolute(src)? == absolute(dst)? { return Ok(()); } let _dst = prepare_path(dst)?; fs::hard_link(src, _dst)?; Ok(()) @@ -102,6 +105,21 @@ mod tests { } #[test] + fn test_copy_file_same_file() { + let tmp = setup_integration("test_copy_file_same_file"); + + let src = &tmp.dir.join("foo"); + let dst = &tmp.dir.join("foo"); + write_file(src, "contents of foo"); + + let result = copy_file(src.to_str().unwrap(), dst.to_str().unwrap()); + + let contents = fs::read_to_string(dst).unwrap(); + assert_eq!(result.is_ok(), true); + assert_eq!(contents, "contents of foo"); + } + + #[test] fn test_copy_file_existing_file() { let tmp = setup_integration("test_copy_file_existing_file"); @@ -171,6 +189,21 @@ mod tests { } #[test] + fn test_link_file_same_file() { + let tmp = setup_integration("test_link_file_same_file"); + + let src = &tmp.dir.join("foo"); + let dst = &tmp.dir.join("foo"); + write_file(src, "contents of foo"); + + let result = link_file(src.to_str().unwrap(), dst.to_str().unwrap()); + + let contents = fs::read_to_string(dst).unwrap(); + assert_eq!(result.is_ok(), true); + assert_eq!(contents, "contents of foo"); + } + + #[test] fn test_link_file_existing_file() { let tmp = setup_integration("test_link_file_existing_file");