machines/rust/lib/common/src/fs.rs

157 lines
4.9 KiB
Rust
Raw Normal View History

use std::{
fs::{Permissions, ReadDir},
io::{ErrorKind, Write},
path::Path,
};
use anyhow::Context;
use crate::proc;
pub fn is_dir(p: &Path) -> anyhow::Result<bool> {
log::trace!("is_dir: {}", p.display());
Ok(match std::fs::metadata(p) {
Ok(m) if m.is_dir() => true,
Ok(_) => false,
Err(e) if e.kind() == ErrorKind::NotFound => false,
Err(e) => return Err(e).with_context(|| format!("Could not stat {p:?}")),
})
}
pub fn is_file(p: &Path) -> anyhow::Result<bool> {
log::trace!("is_file: {}", p.display());
Ok(match std::fs::metadata(p) {
Ok(m) if m.is_file() => true,
Ok(_) => false,
Err(e) if e.kind() == ErrorKind::NotFound => false,
Err(e) => return Err(e).with_context(|| format!("Could not stat {p:?}")),
})
}
pub fn is_file_with_permissions(p: &Path, permissions: Permissions) -> anyhow::Result<bool> {
log::trace!("is_file_with_permissions: {}", p.display());
Ok(match std::fs::metadata(p) {
Ok(m) if m.is_file() => {
log::trace!("Verifying {:?} == {:?}", m.permissions(), permissions);
m.permissions() == permissions
}
Ok(_) => false,
Err(e) if e.kind() == ErrorKind::NotFound => false,
Err(e) => return Err(e).with_context(|| format!("Could not stat {p:?}")),
})
}
pub fn create_dir(p: &Path) -> anyhow::Result<()> {
log::info!("Creating directory : {}", p.display());
std::fs::create_dir(p).with_context(|| format!("Could not create directory {p:?}"))
}
pub fn write_file_string(p: &Path, contents: &str, permissions: Permissions) -> anyhow::Result<()> {
log::info!("Writing contents to {}", p.display());
let mut file = std::fs::File::create(p).with_context(|| {
format!(
"Could not create (or open existing) file at {}",
p.display()
)
})?;
file.set_permissions(permissions)
.with_context(|| format!("Could not set permissions on file {}", p.display()))?;
file.write_all(contents.as_bytes())
.with_context(|| format!("Could not write to file {}", p.display()))?;
Ok(())
}
pub fn root_create_dir(p: &Path) -> anyhow::Result<()> {
let mut cmd = proc::Command::new("mkdir");
cmd.arg(p.display().to_string());
let _ = cmd.sudo().try_spawn_to_string()?;
Ok(())
}
pub fn remove_file(path: &Path) -> anyhow::Result<()> {
log::info!("Deleting file {}", path.display());
std::fs::remove_file(path).with_context(|| format!("Could not delete file {}", path.display()))
}
pub fn root_create_dir_recursive(p: &Path) -> anyhow::Result<()> {
let mut cmd = proc::Command::new("mkdir");
cmd.arg("-p");
cmd.arg(p.display().to_string());
let _ = cmd.sudo().try_spawn_to_string()?;
Ok(())
}
pub fn create_dir_recursive(p: &Path) -> anyhow::Result<()> {
let mut cmd = proc::Command::new("mkdir");
cmd.arg("-p");
cmd.arg(p.display().to_string());
let _ = cmd.try_spawn_to_string()?;
Ok(())
}
pub fn remove_dir_recursive(p: &Path) -> anyhow::Result<()> {
std::fs::remove_dir_all(p)
.with_context(|| format!("Could not remove directory {}", p.display()))
}
pub fn list_dir(p: &Path) -> anyhow::Result<ReadDir> {
std::fs::read_dir(p).with_context(|| format!("Could not read directory {}", p.display()))
}
pub fn set_permissions(p: &Path, permissions: Permissions) -> anyhow::Result<()> {
log::trace!("set_permissions: {}", p.display());
std::fs::set_permissions(p, permissions.clone()).with_context(|| {
format!(
"Could not set permissions on {} to {permissions:?}",
p.display()
)
})
}
pub fn metadata(p: &Path) -> anyhow::Result<std::fs::Metadata> {
log::trace!("get_metadata: {}", p.display());
std::fs::metadata(p).with_context(|| format!("Could not get metadata for {}", p.display()))
}
#[cfg(target_family = "unix")]
pub fn user_only_dir_permissions() -> Permissions {
use std::os::unix::fs::PermissionsExt;
PermissionsExt::from_mode(0o040700)
}
#[cfg(target_family = "unix")]
pub fn user_only_file_permissions() -> Permissions {
use std::os::unix::fs::PermissionsExt;
PermissionsExt::from_mode(0o100600)
}
pub fn read_to_string(path: &Path) -> anyhow::Result<String> {
log::trace!("read_file: {}", path.display());
std::fs::read_to_string(path)
.with_context(|| format!("Could not read file: {}", path.display()))
}
#[cfg(target_family = "unix")]
pub fn create_link(from: &Path, to: &Path) -> anyhow::Result<()> {
std::os::unix::fs::symlink(to, from).with_context(|| {
format!(
"Could not create symbolic link from {from} to {to}",
from = from.display(),
to = to.display()
)
})
}
pub fn rename(from: &Path, to: &Path) -> anyhow::Result<()> {
std::fs::rename(from, to)
.with_context(|| format!("Could not rename {} to {}", from.display(), to.display()))
}