feat(fs): add tracing
This commit is contained in:
parent
c6f167dc16
commit
6e5ea556a9
9 changed files with 127 additions and 20 deletions
|
@ -27,9 +27,11 @@ reqwest = { version = "0.12", features = [ "json" ] }
|
||||||
url = "2.5"
|
url = "2.5"
|
||||||
tempfile = "3.10"
|
tempfile = "3.10"
|
||||||
tokio = { version = "1.41", features = [ "sync" ] }
|
tokio = { version = "1.41", features = [ "sync" ] }
|
||||||
|
tracing = "0.1"
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
assert2 = "0.3"
|
assert2 = "0.3"
|
||||||
|
mutants = "0.0"
|
||||||
pretty_assertions = "1.4"
|
pretty_assertions = "1.4"
|
||||||
test-log = "0.2"
|
test-log = "0.2"
|
||||||
tokio = { version = "1.41", features = [
|
tokio = { version = "1.41", features = [
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
|
//
|
||||||
use std::fmt::Display;
|
use std::fmt::Display;
|
||||||
|
|
||||||
//
|
|
||||||
use crate::fs::{DirItem, DirItemIterator, Result};
|
use crate::fs::{DirItem, DirItemIterator, Result};
|
||||||
|
|
||||||
use super::{DirHandle, Error, PathHandle, PathMarker};
|
use super::{DirHandle, Error, PathHandle, PathMarker};
|
||||||
|
@ -19,8 +19,10 @@ impl DirHandle {
|
||||||
/// # Ok(())
|
/// # Ok(())
|
||||||
/// # }
|
/// # }
|
||||||
/// ```
|
/// ```
|
||||||
|
#[tracing::instrument]
|
||||||
pub fn create(&self) -> Result<()> {
|
pub fn create(&self) -> Result<()> {
|
||||||
self.check_error()?;
|
self.check_error()?;
|
||||||
|
tracing::debug!("std::fs::create_dir");
|
||||||
std::fs::create_dir(self.as_pathbuf()).map_err(Error::Io)
|
std::fs::create_dir(self.as_pathbuf()).map_err(Error::Io)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -37,8 +39,10 @@ impl DirHandle {
|
||||||
/// # Ok(())
|
/// # Ok(())
|
||||||
/// # }
|
/// # }
|
||||||
/// ```
|
/// ```
|
||||||
|
#[tracing::instrument]
|
||||||
pub fn create_all(&self) -> Result<()> {
|
pub fn create_all(&self) -> Result<()> {
|
||||||
self.check_error()?;
|
self.check_error()?;
|
||||||
|
tracing::debug!("std::fs::create_dir_all");
|
||||||
std::fs::create_dir_all(self.as_pathbuf()).map_err(Error::Io)
|
std::fs::create_dir_all(self.as_pathbuf()).map_err(Error::Io)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -55,8 +59,10 @@ impl DirHandle {
|
||||||
/// # Ok(())
|
/// # Ok(())
|
||||||
/// # }
|
/// # }
|
||||||
/// ```
|
/// ```
|
||||||
|
#[tracing::instrument]
|
||||||
pub fn read(&self) -> Result<Box<dyn Iterator<Item = Result<DirItem>>>> {
|
pub fn read(&self) -> Result<Box<dyn Iterator<Item = Result<DirItem>>>> {
|
||||||
self.check_error()?;
|
self.check_error()?;
|
||||||
|
tracing::debug!("std::fs::read_dir");
|
||||||
let read_dir = std::fs::read_dir(self.as_pathbuf()).map_err(Error::Io)?;
|
let read_dir = std::fs::read_dir(self.as_pathbuf()).map_err(Error::Io)?;
|
||||||
Ok(Box::new(DirItemIterator::new(read_dir)))
|
Ok(Box::new(DirItemIterator::new(read_dir)))
|
||||||
}
|
}
|
||||||
|
@ -73,8 +79,10 @@ impl DirHandle {
|
||||||
/// dir.remove()?;
|
/// dir.remove()?;
|
||||||
/// # Ok(())
|
/// # Ok(())
|
||||||
/// }
|
/// }
|
||||||
|
#[tracing::instrument]
|
||||||
pub fn remove(&self) -> Result<()> {
|
pub fn remove(&self) -> Result<()> {
|
||||||
self.check_error()?;
|
self.check_error()?;
|
||||||
|
tracing::debug!("std::fs::remove");
|
||||||
std::fs::remove_dir(self.as_pathbuf()).map_err(Error::Io)
|
std::fs::remove_dir(self.as_pathbuf()).map_err(Error::Io)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -90,8 +98,10 @@ impl DirHandle {
|
||||||
/// dir.remove_all()?;
|
/// dir.remove_all()?;
|
||||||
/// # Ok(())
|
/// # Ok(())
|
||||||
/// }
|
/// }
|
||||||
|
#[tracing::instrument]
|
||||||
pub fn remove_all(&self) -> Result<()> {
|
pub fn remove_all(&self) -> Result<()> {
|
||||||
self.check_error()?;
|
self.check_error()?;
|
||||||
|
tracing::debug!("std::fs::remove_all");
|
||||||
std::fs::remove_dir_all(self.as_pathbuf()).map_err(Error::Io)
|
std::fs::remove_dir_all(self.as_pathbuf()).map_err(Error::Io)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,8 +28,11 @@ impl Iterator for DirItemIterator {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn map_dir_item(item: std::io::Result<DirEntry>) -> super::Result<DirItem> {
|
fn map_dir_item(item: std::io::Result<DirEntry>) -> super::Result<DirItem> {
|
||||||
|
tracing::trace!("map_dir_item");
|
||||||
let item = item.map_err(Error::Io)?;
|
let item = item.map_err(Error::Io)?;
|
||||||
|
tracing::trace!(?item, "map_dir_item");
|
||||||
let file_type = item.file_type().map_err(Error::Io)?;
|
let file_type = item.file_type().map_err(Error::Io)?;
|
||||||
|
tracing::trace!(?file_type, "map_dir_item");
|
||||||
if file_type.is_dir() {
|
if file_type.is_dir() {
|
||||||
Ok(DirItem::Dir(item.path()))
|
Ok(DirItem::Dir(item.path()))
|
||||||
} else if file_type.is_file() {
|
} else if file_type.is_file() {
|
||||||
|
|
|
@ -17,6 +17,7 @@ impl FileHandle {
|
||||||
/// # Ok(())
|
/// # Ok(())
|
||||||
/// # }
|
/// # }
|
||||||
/// ```
|
/// ```
|
||||||
|
#[tracing::instrument]
|
||||||
pub fn reader(&self) -> Result<Reader> {
|
pub fn reader(&self) -> Result<Reader> {
|
||||||
self.check_error()?;
|
self.check_error()?;
|
||||||
Reader::new(&self.as_pathbuf())
|
Reader::new(&self.as_pathbuf())
|
||||||
|
@ -35,9 +36,12 @@ impl FileHandle {
|
||||||
/// # Ok(())
|
/// # Ok(())
|
||||||
/// # }
|
/// # }
|
||||||
/// ```
|
/// ```
|
||||||
|
#[tracing::instrument(skip_all)]
|
||||||
pub fn write<C: AsRef<[u8]>>(&self, contents: C) -> Result<()> {
|
pub fn write<C: AsRef<[u8]>>(&self, contents: C) -> Result<()> {
|
||||||
self.check_error()?;
|
self.check_error()?;
|
||||||
std::fs::write(self.as_pathbuf(), contents).map_err(Error::Io)
|
let file = self.as_pathbuf();
|
||||||
|
tracing::debug!(?file, "std::fs::write");
|
||||||
|
std::fs::write(file, contents).map_err(Error::Io)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Copies the contents of a file to another file.
|
/// Copies the contents of a file to another file.
|
||||||
|
@ -56,9 +60,13 @@ impl FileHandle {
|
||||||
/// # Ok(())
|
/// # Ok(())
|
||||||
/// # }
|
/// # }
|
||||||
/// ```
|
/// ```
|
||||||
|
#[tracing::instrument]
|
||||||
pub fn copy(&self, dest: &FileHandle) -> Result<u64> {
|
pub fn copy(&self, dest: &FileHandle) -> Result<u64> {
|
||||||
self.check_error()?;
|
self.check_error()?;
|
||||||
std::fs::copy(self.as_pathbuf(), dest.as_pathbuf()).map_err(Error::Io)
|
let from = self.as_pathbuf();
|
||||||
|
let to = dest.as_pathbuf();
|
||||||
|
tracing::debug!(?from, ?to, "std::fs::copy");
|
||||||
|
std::fs::copy(from, to).map_err(Error::Io)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Removes a file.
|
/// Removes a file.
|
||||||
|
@ -74,9 +82,12 @@ impl FileHandle {
|
||||||
/// # Ok(())
|
/// # Ok(())
|
||||||
/// # }
|
/// # }
|
||||||
/// ```
|
/// ```
|
||||||
|
#[tracing::instrument]
|
||||||
pub fn remove(&self) -> Result<()> {
|
pub fn remove(&self) -> Result<()> {
|
||||||
self.check_error()?;
|
self.check_error()?;
|
||||||
std::fs::remove_file(self.as_pathbuf()).map_err(Error::Io)
|
let file = self.as_pathbuf();
|
||||||
|
tracing::debug!(?file, "std::fs::remove_file");
|
||||||
|
std::fs::remove_file(file).map_err(Error::Io)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Creates a hard link on the filesystem.
|
/// Creates a hard link on the filesystem.
|
||||||
|
@ -96,9 +107,13 @@ impl FileHandle {
|
||||||
/// # Ok(())
|
/// # Ok(())
|
||||||
/// # }
|
/// # }
|
||||||
/// ```
|
/// ```
|
||||||
|
#[tracing::instrument]
|
||||||
pub fn hard_link(&self, dest: &FileHandle) -> Result<()> {
|
pub fn hard_link(&self, dest: &FileHandle) -> Result<()> {
|
||||||
self.check_error()?;
|
self.check_error()?;
|
||||||
std::fs::hard_link(self.as_pathbuf(), dest.as_pathbuf()).map_err(Error::Io)
|
let original = self.as_pathbuf();
|
||||||
|
let link = dest.as_pathbuf();
|
||||||
|
tracing::debug!(?original, ?link, "std::fs::hard_link");
|
||||||
|
std::fs::hard_link(original, link).map_err(Error::Io)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
impl TryFrom<PathHandle<PathMarker>> for FileHandle {
|
impl TryFrom<PathHandle<PathMarker>> for FileHandle {
|
||||||
|
|
|
@ -83,7 +83,9 @@ pub use temp::TempFileSystem;
|
||||||
/// `error::Error::PathTraversal` error when attempting the
|
/// `error::Error::PathTraversal` error when attempting the
|
||||||
/// opertation.
|
/// opertation.
|
||||||
pub fn new(base: impl Into<PathBuf>) -> FileSystem {
|
pub fn new(base: impl Into<PathBuf>) -> FileSystem {
|
||||||
FileSystem::new(base.into())
|
let base = base.into();
|
||||||
|
tracing::debug!(?base, "new");
|
||||||
|
FileSystem::new(base)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Creates a new `TempFileSystem` for a temporary directory.
|
/// Creates a new `TempFileSystem` for a temporary directory.
|
||||||
|
|
|
@ -38,10 +38,12 @@ pub struct PathReal<T: PathType> {
|
||||||
pub(super) error: Option<Error>,
|
pub(super) error: Option<Error>,
|
||||||
}
|
}
|
||||||
impl<T: PathType> PathReal<T> {
|
impl<T: PathType> PathReal<T> {
|
||||||
|
#[tracing::instrument(skip_all)]
|
||||||
pub(super) fn new(base: impl Into<PathBuf>, path: impl Into<PathBuf>) -> Self {
|
pub(super) fn new(base: impl Into<PathBuf>, path: impl Into<PathBuf>) -> Self {
|
||||||
let base: PathBuf = base.into();
|
let base: PathBuf = base.into();
|
||||||
let path: PathBuf = path.into();
|
let path: PathBuf = path.into();
|
||||||
let error = PathReal::<T>::validate(&base, &path);
|
let error = PathReal::<T>::validate(&base, &path);
|
||||||
|
tracing::debug!(?base, ?path, ?error, "new");
|
||||||
Self {
|
Self {
|
||||||
base,
|
base,
|
||||||
path,
|
path,
|
||||||
|
@ -66,6 +68,7 @@ impl<T: PathType> PathReal<T> {
|
||||||
self.base.join(&self.path)
|
self.base.join(&self.path)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// only stores the first error, subsequent errors are dropped
|
||||||
pub(super) fn put(&mut self, error: Error) {
|
pub(super) fn put(&mut self, error: Error) {
|
||||||
if self.error.is_none() {
|
if self.error.is_none() {
|
||||||
self.error.replace(error);
|
self.error.replace(error);
|
||||||
|
@ -87,20 +90,25 @@ impl<T: PathType> PathReal<T> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[tracing::instrument]
|
||||||
fn clean_path(path: &Path) -> Result<PathBuf> {
|
fn clean_path(path: &Path) -> Result<PathBuf> {
|
||||||
// let path = path.as_ref();
|
|
||||||
use path_clean::PathClean;
|
use path_clean::PathClean;
|
||||||
let abs_path = if path.is_absolute() {
|
let abs_path = if path.is_absolute() {
|
||||||
|
tracing::debug!("is absolute");
|
||||||
path.to_path_buf()
|
path.to_path_buf()
|
||||||
} else {
|
} else {
|
||||||
|
tracing::debug!("std::env::current_dir");
|
||||||
std::env::current_dir().expect("current_dir").join(path)
|
std::env::current_dir().expect("current_dir").join(path)
|
||||||
}
|
}
|
||||||
.clean();
|
.clean();
|
||||||
|
tracing::debug!(?abs_path);
|
||||||
Ok(abs_path)
|
Ok(abs_path)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[tracing::instrument(skip_all)]
|
||||||
pub(super) fn check_error(&self) -> Result<()> {
|
pub(super) fn check_error(&self) -> Result<()> {
|
||||||
if let Some(error) = &self.error {
|
if let Some(error) = &self.error {
|
||||||
|
tracing::warn!(?error, "error");
|
||||||
Err(error.clone())
|
Err(error.clone())
|
||||||
} else {
|
} else {
|
||||||
Ok(())
|
Ok(())
|
||||||
|
@ -123,9 +131,12 @@ impl<T: PathType> PathReal<T> {
|
||||||
/// # Ok(())
|
/// # Ok(())
|
||||||
/// # }
|
/// # }
|
||||||
/// ```
|
/// ```
|
||||||
|
#[tracing::instrument(skip_all)]
|
||||||
pub fn exists(&self) -> Result<bool> {
|
pub fn exists(&self) -> Result<bool> {
|
||||||
self.check_error()?;
|
self.check_error()?;
|
||||||
Ok(self.as_pathbuf().exists())
|
let path = self.as_pathbuf();
|
||||||
|
tracing::debug!(?path, "PathBuf::exists");
|
||||||
|
Ok(path.exists())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns true if the path is a directory.
|
/// Returns true if the path is a directory.
|
||||||
|
@ -140,9 +151,12 @@ impl<T: PathType> PathReal<T> {
|
||||||
/// # Ok(())
|
/// # Ok(())
|
||||||
/// # }
|
/// # }
|
||||||
/// ```
|
/// ```
|
||||||
|
#[tracing::instrument(skip_all)]
|
||||||
pub fn is_dir(&self) -> Result<bool> {
|
pub fn is_dir(&self) -> Result<bool> {
|
||||||
self.check_error()?;
|
self.check_error()?;
|
||||||
Ok(self.as_pathbuf().is_dir())
|
let path = self.as_pathbuf();
|
||||||
|
tracing::debug!(?path, "PathBuf::is_dir");
|
||||||
|
Ok(path.is_dir())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns true if the path is a file.
|
/// Returns true if the path is a file.
|
||||||
|
@ -157,9 +171,12 @@ impl<T: PathType> PathReal<T> {
|
||||||
/// # Ok(())
|
/// # Ok(())
|
||||||
/// # }
|
/// # }
|
||||||
/// ```
|
/// ```
|
||||||
|
#[tracing::instrument(skip_all)]
|
||||||
pub fn is_file(&self) -> Result<bool> {
|
pub fn is_file(&self) -> Result<bool> {
|
||||||
self.check_error()?;
|
self.check_error()?;
|
||||||
Ok(self.as_pathbuf().is_file())
|
let path = self.as_pathbuf();
|
||||||
|
tracing::debug!(?path, "PathBuf::is_file");
|
||||||
|
Ok(path.is_file())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the path as a directory if it exists and is a directory, otherwise
|
/// Returns the path as a directory if it exists and is a directory, otherwise
|
||||||
|
@ -176,9 +193,13 @@ impl<T: PathType> PathReal<T> {
|
||||||
/// # Ok(())
|
/// # Ok(())
|
||||||
/// # }
|
/// # }
|
||||||
/// ```
|
/// ```
|
||||||
|
#[tracing::instrument(skip_all)]
|
||||||
pub fn as_dir(&self) -> Result<Option<DirHandle>> {
|
pub fn as_dir(&self) -> Result<Option<DirHandle>> {
|
||||||
self.check_error()?;
|
self.check_error()?;
|
||||||
if self.as_pathbuf().is_dir() {
|
let path = self.as_pathbuf();
|
||||||
|
let is_dir = path.is_dir();
|
||||||
|
tracing::debug!(?path, ?is_dir, "PathBuf::is_dir");
|
||||||
|
if is_dir {
|
||||||
Ok(Some(PathReal::new(&self.base, &self.path)))
|
Ok(Some(PathReal::new(&self.base, &self.path)))
|
||||||
} else {
|
} else {
|
||||||
Ok(None)
|
Ok(None)
|
||||||
|
@ -199,9 +220,13 @@ impl<T: PathType> PathReal<T> {
|
||||||
/// # Ok(())
|
/// # Ok(())
|
||||||
/// # }
|
/// # }
|
||||||
/// ```
|
/// ```
|
||||||
|
#[tracing::instrument(skip_all)]
|
||||||
pub fn as_file(&self) -> Result<Option<FileHandle>> {
|
pub fn as_file(&self) -> Result<Option<FileHandle>> {
|
||||||
self.check_error()?;
|
self.check_error()?;
|
||||||
if self.as_pathbuf().is_file() {
|
let path = self.as_pathbuf();
|
||||||
|
let is_file = path.is_file();
|
||||||
|
tracing::debug!(?path, ?is_file, "PathBuf::is_file");
|
||||||
|
if is_file {
|
||||||
Ok(Some(PathReal::new(&self.base, &self.path)))
|
Ok(Some(PathReal::new(&self.base, &self.path)))
|
||||||
} else {
|
} else {
|
||||||
Ok(None)
|
Ok(None)
|
||||||
|
@ -225,9 +250,13 @@ impl<T: PathType> PathReal<T> {
|
||||||
/// # Ok(())
|
/// # Ok(())
|
||||||
/// # }
|
/// # }
|
||||||
/// ```
|
/// ```
|
||||||
|
#[tracing::instrument(skip_all)]
|
||||||
pub fn rename(&self, dest: &PathHandle<T>) -> Result<()> {
|
pub fn rename(&self, dest: &PathHandle<T>) -> Result<()> {
|
||||||
self.check_error()?;
|
self.check_error()?;
|
||||||
std::fs::rename(self.as_pathbuf(), dest.as_pathbuf()).map_err(Error::Io)
|
let from = self.as_pathbuf();
|
||||||
|
let to = dest.as_pathbuf();
|
||||||
|
tracing::debug!(?from, ?to, "std::fs::rename");
|
||||||
|
std::fs::rename(from, to).map_err(Error::Io)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the metadata for a path.
|
/// Returns the metadata for a path.
|
||||||
|
@ -243,9 +272,12 @@ impl<T: PathType> PathReal<T> {
|
||||||
/// # Ok(())
|
/// # Ok(())
|
||||||
/// # }
|
/// # }
|
||||||
/// ```
|
/// ```
|
||||||
|
#[tracing::instrument(skip_all)]
|
||||||
pub fn metadata(&self) -> Result<std::fs::Metadata> {
|
pub fn metadata(&self) -> Result<std::fs::Metadata> {
|
||||||
self.check_error()?;
|
self.check_error()?;
|
||||||
std::fs::metadata(self.as_pathbuf()).map_err(Error::Io)
|
let path = self.as_pathbuf();
|
||||||
|
tracing::debug!(?path, "std::fs::metadata");
|
||||||
|
std::fs::metadata(path).map_err(Error::Io)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Creates a symbolic link to a path.
|
/// Creates a symbolic link to a path.
|
||||||
|
@ -265,9 +297,13 @@ impl<T: PathType> PathReal<T> {
|
||||||
/// # Ok(())
|
/// # Ok(())
|
||||||
/// # }
|
/// # }
|
||||||
/// ```
|
/// ```
|
||||||
|
#[tracing::instrument(skip_all)]
|
||||||
pub fn soft_link(&self, link: &PathReal<PathMarker>) -> Result<()> {
|
pub fn soft_link(&self, link: &PathReal<PathMarker>) -> Result<()> {
|
||||||
self.check_error()?;
|
self.check_error()?;
|
||||||
std::os::unix::fs::symlink(self.as_pathbuf(), link.as_pathbuf()).map_err(Error::Io)
|
let original = self.as_pathbuf();
|
||||||
|
let link = link.as_pathbuf();
|
||||||
|
tracing::debug!(?original, ?link, "std::os::unix::fs::symlink");
|
||||||
|
std::os::unix::fs::symlink(original, link).map_err(Error::Io)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns true if the path is a symbolic link.
|
/// Returns true if the path is a symbolic link.
|
||||||
|
@ -283,9 +319,12 @@ impl<T: PathType> PathReal<T> {
|
||||||
/// # Ok(())
|
/// # Ok(())
|
||||||
/// # }
|
/// # }
|
||||||
/// ```
|
/// ```
|
||||||
|
#[tracing::instrument(skip_all)]
|
||||||
pub fn is_link(&self) -> Result<bool> {
|
pub fn is_link(&self) -> Result<bool> {
|
||||||
self.check_error()?;
|
self.check_error()?;
|
||||||
Ok(self.as_pathbuf().is_symlink())
|
let path = self.as_pathbuf();
|
||||||
|
tracing::debug!(?path, "PathBuf::is_symlink");
|
||||||
|
Ok(path.is_symlink())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the canonical, absolute form of the path with all intermediate
|
/// Returns the canonical, absolute form of the path with all intermediate
|
||||||
|
@ -302,9 +341,12 @@ impl<T: PathType> PathReal<T> {
|
||||||
/// # Ok(())
|
/// # Ok(())
|
||||||
/// # }
|
/// # }
|
||||||
/// ```
|
/// ```
|
||||||
|
#[tracing::instrument(skip_all)]
|
||||||
pub fn canonicalize(&self) -> Result<PathBuf> {
|
pub fn canonicalize(&self) -> Result<PathBuf> {
|
||||||
self.check_error()?;
|
self.check_error()?;
|
||||||
self.as_pathbuf().canonicalize().map_err(Error::Io)
|
let path = self.as_pathbuf();
|
||||||
|
tracing::debug!(?path, "PathBuf::canonicalize");
|
||||||
|
path.canonicalize().map_err(Error::Io)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the metadata for a path without following symlinks.
|
/// Returns the metadata for a path without following symlinks.
|
||||||
|
@ -320,9 +362,12 @@ impl<T: PathType> PathReal<T> {
|
||||||
/// # Ok(())
|
/// # Ok(())
|
||||||
/// # }
|
/// # }
|
||||||
/// ```
|
/// ```
|
||||||
|
#[tracing::instrument(skip_all)]
|
||||||
pub fn symlink_metadata(&self) -> Result<std::fs::Metadata> {
|
pub fn symlink_metadata(&self) -> Result<std::fs::Metadata> {
|
||||||
self.check_error()?;
|
self.check_error()?;
|
||||||
std::fs::symlink_metadata(self.as_pathbuf()).map_err(Error::Io)
|
let path = self.as_pathbuf();
|
||||||
|
tracing::debug!(?path, "std::fs::symlink_metadata");
|
||||||
|
std::fs::symlink_metadata(path).map_err(Error::Io)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Sets the permissions of a file or directory.
|
/// Sets the permissions of a file or directory.
|
||||||
|
@ -341,14 +386,20 @@ impl<T: PathType> PathReal<T> {
|
||||||
/// # Ok(())
|
/// # Ok(())
|
||||||
/// # }
|
/// # }
|
||||||
/// ```
|
/// ```
|
||||||
|
#[tracing::instrument(skip_all)]
|
||||||
pub fn set_permissions(&self, perms: std::fs::Permissions) -> Result<()> {
|
pub fn set_permissions(&self, perms: std::fs::Permissions) -> Result<()> {
|
||||||
self.check_error()?;
|
self.check_error()?;
|
||||||
std::fs::set_permissions(self.as_pathbuf(), perms).map_err(Error::Io)
|
let path = self.as_pathbuf();
|
||||||
|
tracing::debug!(?path, ?perms, "std::fs::set_permissions");
|
||||||
|
std::fs::set_permissions(path, perms).map_err(Error::Io)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[tracing::instrument(skip_all)]
|
||||||
pub fn read_link(&self) -> Result<PathReal<PathMarker>> {
|
pub fn read_link(&self) -> Result<PathReal<PathMarker>> {
|
||||||
self.check_error()?;
|
self.check_error()?;
|
||||||
let read_path = std::fs::read_link(self.as_pathbuf()).map_err(Error::Io)?;
|
let path = self.as_pathbuf();
|
||||||
|
tracing::debug!(?path, "std::fs::read_link");
|
||||||
|
let read_path = std::fs::read_link(path).map_err(Error::Io)?;
|
||||||
let path = read_path.strip_prefix(&self.base).unwrap().to_path_buf();
|
let path = read_path.strip_prefix(&self.base).unwrap().to_path_buf();
|
||||||
Ok(PathReal::new(&self.base, &path))
|
Ok(PathReal::new(&self.base, &path))
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,8 +11,11 @@ pub struct Reader {
|
||||||
contents: String,
|
contents: String,
|
||||||
}
|
}
|
||||||
impl Reader {
|
impl Reader {
|
||||||
|
#[tracing::instrument]
|
||||||
pub(super) fn new(path: &Path) -> Result<Self> {
|
pub(super) fn new(path: &Path) -> Result<Self> {
|
||||||
|
tracing::debug!("std::fs::read_to_string");
|
||||||
let contents = std::fs::read_to_string(path).map_err(Error::Io)?;
|
let contents = std::fs::read_to_string(path).map_err(Error::Io)?;
|
||||||
|
tracing::debug!(len = contents.len(), "contents");
|
||||||
Ok(Self { contents })
|
Ok(Self { contents })
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -34,6 +34,7 @@ impl FileSystem {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns a [PathBuf] for the path.
|
/// Returns a [PathBuf] for the path.
|
||||||
|
#[tracing::instrument]
|
||||||
pub fn path_of(&self, path: PathBuf) -> Result<PathBuf> {
|
pub fn path_of(&self, path: PathBuf) -> Result<PathBuf> {
|
||||||
let path_of = self.base.as_path().join(path);
|
let path_of = self.base.as_path().join(path);
|
||||||
self.validate(&path_of)?;
|
self.validate(&path_of)?;
|
||||||
|
@ -55,13 +56,16 @@ impl FileSystem {
|
||||||
/// # Ok(())
|
/// # Ok(())
|
||||||
/// # }
|
/// # }
|
||||||
/// ```
|
/// ```
|
||||||
|
#[tracing::instrument]
|
||||||
pub fn dir(&self, path: &Path) -> DirHandle {
|
pub fn dir(&self, path: &Path) -> DirHandle {
|
||||||
let mut dir = PathReal::new(&self.base, path);
|
let mut dir = PathReal::new(&self.base, path);
|
||||||
|
|
||||||
if dir.error.is_none() {
|
if dir.error.is_none() {
|
||||||
if let Ok(exists) = dir.exists() {
|
if let Ok(exists) = dir.exists() {
|
||||||
|
tracing::debug!(?exists);
|
||||||
if exists {
|
if exists {
|
||||||
if let Ok(is_dir) = dir.is_dir() {
|
if let Ok(is_dir) = dir.is_dir() {
|
||||||
|
tracing::debug!(?is_dir);
|
||||||
if !is_dir {
|
if !is_dir {
|
||||||
dir.put(Error::NotADirectory {
|
dir.put(Error::NotADirectory {
|
||||||
path: dir.as_pathbuf(),
|
path: dir.as_pathbuf(),
|
||||||
|
@ -90,13 +94,16 @@ impl FileSystem {
|
||||||
/// # Ok(())
|
/// # Ok(())
|
||||||
/// # }
|
/// # }
|
||||||
/// ```
|
/// ```
|
||||||
|
#[tracing::instrument]
|
||||||
pub fn file(&self, path: &Path) -> FileHandle {
|
pub fn file(&self, path: &Path) -> FileHandle {
|
||||||
let mut file = PathReal::new(&self.base, path);
|
let mut file = PathReal::new(&self.base, path);
|
||||||
|
|
||||||
if file.error.is_none() {
|
if file.error.is_none() {
|
||||||
if let Ok(exists) = file.exists() {
|
if let Ok(exists) = file.exists() {
|
||||||
|
tracing::debug!(?exists);
|
||||||
if exists {
|
if exists {
|
||||||
if let Ok(is_file) = file.is_file() {
|
if let Ok(is_file) = file.is_file() {
|
||||||
|
tracing::debug!(?is_file);
|
||||||
if !is_file {
|
if !is_file {
|
||||||
file.put(Error::NotAFile {
|
file.put(Error::NotAFile {
|
||||||
path: file.as_pathbuf(),
|
path: file.as_pathbuf(),
|
||||||
|
@ -124,10 +131,12 @@ impl FileSystem {
|
||||||
/// # Ok(())
|
/// # Ok(())
|
||||||
/// # }
|
/// # }
|
||||||
/// ```
|
/// ```
|
||||||
|
#[tracing::instrument]
|
||||||
pub fn path(&self, path: &Path) -> PathHandle<PathMarker> {
|
pub fn path(&self, path: &Path) -> PathHandle<PathMarker> {
|
||||||
PathReal::new(&self.base, path)
|
PathReal::new(&self.base, path)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[tracing::instrument]
|
||||||
fn validate(&self, path: &Path) -> Result<()> {
|
fn validate(&self, path: &Path) -> Result<()> {
|
||||||
let path = self.clean_path(path)?;
|
let path = self.clean_path(path)?;
|
||||||
if !path.starts_with(&self.base) {
|
if !path.starts_with(&self.base) {
|
||||||
|
@ -139,15 +148,19 @@ impl FileSystem {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[tracing::instrument]
|
||||||
fn clean_path(&self, path: &Path) -> Result<PathBuf> {
|
fn clean_path(&self, path: &Path) -> Result<PathBuf> {
|
||||||
// let path = path.as_ref();
|
// let path = path.as_ref();
|
||||||
use path_clean::PathClean;
|
use path_clean::PathClean;
|
||||||
let abs_path = if path.is_absolute() {
|
let abs_path = if path.is_absolute() {
|
||||||
|
tracing::debug!("is_absolute");
|
||||||
path.to_path_buf()
|
path.to_path_buf()
|
||||||
} else {
|
} else {
|
||||||
|
tracing::debug!("std::env::current_dir");
|
||||||
std::env::current_dir().map_err(Error::Io)?.join(path)
|
std::env::current_dir().map_err(Error::Io)?.join(path)
|
||||||
}
|
}
|
||||||
.clean();
|
.clean();
|
||||||
|
tracing::debug!(?abs_path);
|
||||||
Ok(abs_path)
|
Ok(abs_path)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,6 +10,7 @@ pub struct TempFileSystem {
|
||||||
_temp_dir: Arc<Mutex<TempDir>>,
|
_temp_dir: Arc<Mutex<TempDir>>,
|
||||||
}
|
}
|
||||||
impl TempFileSystem {
|
impl TempFileSystem {
|
||||||
|
#[tracing::instrument]
|
||||||
pub fn new() -> super::Result<Self> {
|
pub fn new() -> super::Result<Self> {
|
||||||
let temp_dir = tempfile::tempdir().map_err(Error::Io)?;
|
let temp_dir = tempfile::tempdir().map_err(Error::Io)?;
|
||||||
let base = temp_dir.path().to_path_buf();
|
let base = temp_dir.path().to_path_buf();
|
||||||
|
@ -34,3 +35,10 @@ impl std::ops::Deref for TempFileSystem {
|
||||||
&self.real
|
&self.real
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
impl Drop for TempFileSystem {
|
||||||
|
#[cfg_attr(test, mutants::skip)]
|
||||||
|
#[tracing::instrument]
|
||||||
|
fn drop(&mut self) {
|
||||||
|
tracing::debug!("drop");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in a new issue