unnest archives with only one dir in it
This commit is contained in:
@@ -1,6 +1,9 @@
|
||||
use std::{fs, path::Path};
|
||||
use std::{
|
||||
fs,
|
||||
path::{Path, PathBuf},
|
||||
};
|
||||
|
||||
use anyhow::anyhow;
|
||||
use anyhow::{Ok, anyhow};
|
||||
use log::error;
|
||||
use zip::ZipArchive;
|
||||
|
||||
@@ -29,6 +32,8 @@ pub fn unpack(archive_path: impl AsRef<Path>, extract_to: impl AsRef<Path>) -> a
|
||||
}
|
||||
}?;
|
||||
|
||||
unnest_dir(extract_to)?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@@ -53,3 +58,47 @@ fn unpack_rar(path: impl AsRef<Path>, to: impl AsRef<Path>) -> anyhow::Result<()
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Moves a directorys content into the parent if it is the only dir
|
||||
fn unnest_dir(path: impl AsRef<Path>) -> anyhow::Result<()> {
|
||||
let path = path.as_ref();
|
||||
|
||||
let Some(nested_dir) = check_nested_dir(path) else {
|
||||
return Ok(());
|
||||
};
|
||||
|
||||
for entry in fs::read_dir(&nested_dir)? {
|
||||
let entry = entry?;
|
||||
let src = entry.path();
|
||||
let dest = path.join(entry.file_name());
|
||||
fs::rename(&src, &dest)?;
|
||||
}
|
||||
|
||||
fs::remove_dir(&nested_dir)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Check if the extracted archive has a single directory in it which contains the mod files
|
||||
fn check_nested_dir(path: impl AsRef<Path>) -> Option<PathBuf> {
|
||||
let path = path.as_ref();
|
||||
|
||||
let entries: Vec<_> = fs::read_dir(path).ok()?.filter_map(|e| e.ok()).collect();
|
||||
|
||||
if entries.len() == 1 {
|
||||
let entry = &entries[0];
|
||||
let entry_path = entry.path();
|
||||
|
||||
if entry_path
|
||||
.file_name()
|
||||
.is_some_and(|e| e == "Data" || e == "data")
|
||||
{
|
||||
return None;
|
||||
}
|
||||
|
||||
if entry_path.is_dir() {
|
||||
return Some(entry_path);
|
||||
}
|
||||
}
|
||||
|
||||
None
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user