diff --git a/src/replacer.rs b/src/replacer.rs index 3e30bd9..fa3f6c2 100644 --- a/src/replacer.rs +++ b/src/replacer.rs @@ -1,6 +1,6 @@ use crate::{utils, Error, Result}; use regex::bytes::Regex; -use std::{fs::File, io::prelude::*, path::Path}; +use std::{fs, fs::File, io::prelude::*, path::Path}; pub(crate) struct Replacer { regex: Regex, @@ -132,7 +132,7 @@ impl Replacer { } let source = File::open(path)?; - let meta = source.metadata()?; + let meta = fs::metadata(path)?; let mmap_source = unsafe { Mmap::map(&source)? }; let replaced = self.replace(&mmap_source); @@ -153,7 +153,7 @@ impl Replacer { drop(mmap_source); drop(source); - target.persist(path)?; + target.persist(fs::canonicalize(path)?)?; Ok(()) } } diff --git a/tests/cli.rs b/tests/cli.rs index 7e34861..fb50e7b 100644 --- a/tests/cli.rs +++ b/tests/cli.rs @@ -13,6 +13,18 @@ mod cli { assert_eq!(content, std::fs::read_to_string(path).unwrap()); } + fn create_soft_link>( + src: &P, + dst: &P, + ) -> Result<()> { + #[cfg(target_family = "unix")] + std::os::unix::fs::symlink(src, dst)?; + #[cfg(target_family = "windows")] + std::os::windows::fs::symlink_file(src, dst)?; + + Ok(()) + } + #[test] fn in_place() -> Result<()> { let mut file = tempfile::NamedTempFile::new()?; @@ -41,6 +53,26 @@ mod cli { Ok(()) } + #[test] + fn in_place_following_symlink() -> Result<()> { + let dir = tempfile::tempdir()?; + let path = dir.path(); + let file = path.join("file"); + let link = path.join("link"); + + create_soft_link(&file, &link)?; + std::fs::write(&file, "abc123def")?; + + sd().args(&["abc\\d+", "", link.to_str().unwrap()]) + .assert() + .success(); + + assert_file(&file.to_path_buf(), "def"); + assert!(std::fs::symlink_metadata(link)?.file_type().is_symlink()); + + Ok(()) + } + #[test] fn replace_into_stdout() -> Result<()> { let mut file = tempfile::NamedTempFile::new()?;