blob: b97e9924732c032411a2b0a6ed056054dace38d3 [file] [log] [blame]
use crate::error::{Error, Result};
use crate::gen::fs;
use crate::paths;
use std::path::Path;
pub(crate) fn write(path: impl AsRef<Path>, content: &[u8]) -> Result<()> {
let path = path.as_ref();
let mut create_dir_error = None;
if path.exists() {
if let Ok(existing) = fs::read(path) {
if existing == content {
// Avoid bumping modified time with unchanged contents.
return Ok(());
}
}
let _ = fs::remove_file(path);
} else {
let parent = path.parent().unwrap();
create_dir_error = fs::create_dir_all(parent).err();
}
match fs::write(path, content) {
// As long as write succeeded, ignore any create_dir_all error.
Ok(()) => Ok(()),
// If create_dir_all and write both failed, prefer the first error.
Err(err) => Err(Error::Fs(create_dir_error.unwrap_or(err))),
}
}
pub(crate) fn symlink_file(src: impl AsRef<Path>, dst: impl AsRef<Path>) -> Result<()> {
let src = src.as_ref();
let dst = dst.as_ref();
let mut create_dir_error = None;
if dst.exists() {
let _ = fs::remove_file(dst).unwrap();
} else {
let parent = dst.parent().unwrap();
create_dir_error = fs::create_dir_all(parent).err();
}
match paths::symlink_or_copy(src, dst) {
// As long as symlink_or_copy succeeded, ignore any create_dir_all error.
Ok(()) => Ok(()),
// If create_dir_all and symlink_or_copy both failed, prefer the first error.
Err(err) => Err(Error::Fs(create_dir_error.unwrap_or(err))),
}
}
pub(crate) fn symlink_dir(src: impl AsRef<Path>, dst: impl AsRef<Path>) -> Result<()> {
let src = src.as_ref();
let dst = dst.as_ref();
let mut create_dir_error = None;
if dst.exists() {
let _ = paths::remove_symlink_dir(dst).unwrap();
} else {
let parent = dst.parent().unwrap();
create_dir_error = fs::create_dir_all(parent).err();
}
match paths::symlink_dir(src, dst) {
// As long as symlink_dir succeeded, ignore any create_dir_all error.
Ok(()) => Ok(()),
// If create_dir_all and symlink_dir both failed, prefer the first error.
Err(err) => Err(Error::Fs(create_dir_error.unwrap_or(err))),
}
}