Add --include flag to unpack for partial unpacking

This commit is contained in:
Truman Kilen 2023-02-15 20:05:40 -06:00
parent a899b86afe
commit de1b23a4c4

View file

@ -51,6 +51,10 @@ struct ActionUnpack {
/// Verbose /// Verbose
#[arg(short, long, default_value = "false")] #[arg(short, long, default_value = "false")]
verbose: bool, verbose: bool,
/// Files or directories to include. Can be specified multiple times. If not specified, everything is extracted.
#[arg(action = clap::ArgAction::Append, short, long)]
include: Vec<String>,
} }
#[derive(Parser, Debug)] #[derive(Parser, Debug)]
@ -169,15 +173,26 @@ fn unpack(args: ActionUnpack) -> Result<(), repak::Error> {
} }
let mount_point = PathBuf::from(pak.mount_point()); let mount_point = PathBuf::from(pak.mount_point());
let prefix = Path::new(&args.strip_prefix); let prefix = Path::new(&args.strip_prefix);
let includes = args
.include
.iter()
.map(|i| prefix.join(Path::new(i)))
.collect::<Vec<_>>();
pak.files().into_par_iter().try_for_each_init( pak.files().into_par_iter().try_for_each_init(
|| File::open(&args.input), || (File::open(&args.input), includes.clone()),
|file, path| -> Result<(), repak::Error> { |(file, includes), path| -> Result<(), repak::Error> {
let full_path = mount_point.join(&path);
if !includes.is_empty() && includes.iter().find(|i| full_path.starts_with(i)).is_none()
{
return Ok(());
}
if args.verbose { if args.verbose {
println!("extracting {path}"); println!("extracting {path}");
} }
let file_path = output.join( let file_path = output.join(
mount_point full_path
.join(&path)
.strip_prefix(prefix) .strip_prefix(prefix)
.map_err(|_| repak::Error::Other("prefix does not match"))?, .map_err(|_| repak::Error::Other("prefix does not match"))?,
); );