157 lines
4.9 KiB
Rust
157 lines
4.9 KiB
Rust
|
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()))
|
||
|
}
|