46 lines
1.3 KiB
Rust
46 lines
1.3 KiB
Rust
![]() |
use eyre::Result;
|
||
|
use log::info;
|
||
|
use std::path::Path;
|
||
|
use tokio::fs;
|
||
|
|
||
|
pub async fn files(files: &[crate::File], root: &str) -> Result<()> {
|
||
|
for file in files {
|
||
|
let path = chroot(root, &file.path);
|
||
|
let path = Path::new(&path);
|
||
|
|
||
|
if let Some(parent) = path.parent() {
|
||
|
fs::create_dir_all(parent).await?;
|
||
|
}
|
||
|
|
||
|
use crate::FileKind as K;
|
||
|
match &file.kind {
|
||
|
K::Content(content) => fs::write(path, content.as_bytes()).await?,
|
||
|
K::Dir(true) => fs::create_dir(path).await?,
|
||
|
K::Dir(false) => {} // shouldn't happen, but semantic is to ignore
|
||
|
K::Symlink(tgt) => fs::symlink(tgt, path).await?,
|
||
|
}
|
||
|
|
||
|
match file.kind {
|
||
|
K::Symlink(_) => {}
|
||
|
_ => set_perms(path, file.mode).await?,
|
||
|
}
|
||
|
|
||
|
info!("created {}", file.path);
|
||
|
}
|
||
|
|
||
|
Ok(())
|
||
|
}
|
||
|
|
||
|
pub async fn set_perms(path: impl AsRef<Path>, mode: Option<u32>) -> std::io::Result<()> {
|
||
|
if let Some(mode) = mode.filter(|m| *m != 0) {
|
||
|
use std::os::unix::fs::PermissionsExt;
|
||
|
let mode = std::fs::Permissions::from_mode(mode);
|
||
|
fs::set_permissions(path, mode).await?;
|
||
|
}
|
||
|
Ok(())
|
||
|
}
|
||
|
|
||
|
pub fn chroot(root: &str, path: &str) -> String {
|
||
|
format!("{root}/{}", path.trim_start_matches(|c| c == '/'))
|
||
|
}
|