From de1b23a4c4ad186cbc39920d8191848fa6ec67ed Mon Sep 17 00:00:00 2001 From: Truman Kilen Date: Wed, 15 Feb 2023 20:05:40 -0600 Subject: [PATCH] Add --include flag to unpack for partial unpacking --- repak_cli/src/main.rs | 23 +++++++++++++++++++---- 1 file changed, 19 insertions(+), 4 deletions(-) diff --git a/repak_cli/src/main.rs b/repak_cli/src/main.rs index a4d5c27..36537b7 100644 --- a/repak_cli/src/main.rs +++ b/repak_cli/src/main.rs @@ -51,6 +51,10 @@ struct ActionUnpack { /// Verbose #[arg(short, long, default_value = "false")] 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, } #[derive(Parser, Debug)] @@ -169,15 +173,26 @@ fn unpack(args: ActionUnpack) -> Result<(), repak::Error> { } let mount_point = PathBuf::from(pak.mount_point()); let prefix = Path::new(&args.strip_prefix); + + let includes = args + .include + .iter() + .map(|i| prefix.join(Path::new(i))) + .collect::>(); + pak.files().into_par_iter().try_for_each_init( - || File::open(&args.input), - |file, path| -> Result<(), repak::Error> { + || (File::open(&args.input), includes.clone()), + |(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 { println!("extracting {path}"); } let file_path = output.join( - mount_point - .join(&path) + full_path .strip_prefix(prefix) .map_err(|_| repak::Error::Other("prefix does not match"))?, );