Merge pull request #115 from SimplyDanny/follow-symlink-when-writing

Fix #94: Do not replace symlink with output file
This commit is contained in:
Gregory 2021-05-05 22:28:42 -04:00 committed by GitHub
commit f0e396157b
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 35 additions and 3 deletions

View file

@ -1,6 +1,6 @@
use crate::{utils, Error, Result}; use crate::{utils, Error, Result};
use regex::bytes::Regex; 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 { pub(crate) struct Replacer {
regex: Regex, regex: Regex,
@ -132,7 +132,7 @@ impl Replacer {
} }
let source = File::open(path)?; let source = File::open(path)?;
let meta = source.metadata()?; let meta = fs::metadata(path)?;
let mmap_source = unsafe { Mmap::map(&source)? }; let mmap_source = unsafe { Mmap::map(&source)? };
let replaced = self.replace(&mmap_source); let replaced = self.replace(&mmap_source);
@ -153,7 +153,7 @@ impl Replacer {
drop(mmap_source); drop(mmap_source);
drop(source); drop(source);
target.persist(path)?; target.persist(fs::canonicalize(path)?)?;
Ok(()) Ok(())
} }
} }

View file

@ -13,6 +13,18 @@ mod cli {
assert_eq!(content, std::fs::read_to_string(path).unwrap()); assert_eq!(content, std::fs::read_to_string(path).unwrap());
} }
fn create_soft_link<P: AsRef<std::path::Path>>(
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] #[test]
fn in_place() -> Result<()> { fn in_place() -> Result<()> {
let mut file = tempfile::NamedTempFile::new()?; let mut file = tempfile::NamedTempFile::new()?;
@ -41,6 +53,26 @@ mod cli {
Ok(()) 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] #[test]
fn replace_into_stdout() -> Result<()> { fn replace_into_stdout() -> Result<()> {
let mut file = tempfile::NamedTempFile::new()?; let mut file = tempfile::NamedTempFile::new()?;