mirror of
https://github.com/xavo95/repak.git
synced 2025-01-18 10:54:38 +00:00
Support --include globbing
This commit is contained in:
parent
f277c25b3c
commit
55d419df74
4 changed files with 51 additions and 9 deletions
7
Cargo.lock
generated
7
Cargo.lock
generated
|
@ -380,6 +380,12 @@ dependencies = [
|
|||
"wasi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "glob"
|
||||
version = "0.3.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b"
|
||||
|
||||
[[package]]
|
||||
name = "heck"
|
||||
version = "0.4.1"
|
||||
|
@ -704,6 +710,7 @@ dependencies = [
|
|||
"base64",
|
||||
"clap",
|
||||
"dir-diff",
|
||||
"glob",
|
||||
"hex",
|
||||
"indicatif",
|
||||
"indoc",
|
||||
|
|
|
@ -34,6 +34,7 @@ rayon = "1.10.0"
|
|||
sha2 = "0.10.8"
|
||||
strum = { workspace = true }
|
||||
itertools = "0.13.0"
|
||||
glob = "0.3.1"
|
||||
|
||||
[dev-dependencies]
|
||||
assert_cmd = "2.0.14"
|
||||
|
|
|
@ -67,7 +67,7 @@ struct ActionUnpack {
|
|||
|
||||
/// 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>,
|
||||
include: Vec<glob::Pattern>,
|
||||
}
|
||||
|
||||
#[derive(Parser, Debug)]
|
||||
|
@ -339,12 +339,6 @@ fn unpack(aes_key: Option<aes::Aes256>, action: ActionUnpack) -> Result<(), repa
|
|||
let mount_point = PathBuf::from(pak.mount_point());
|
||||
let prefix = Path::new(&action.strip_prefix);
|
||||
|
||||
let includes = action
|
||||
.include
|
||||
.iter()
|
||||
.map(|i| prefix.join(Path::new(i)))
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
struct UnpackEntry {
|
||||
entry_path: String,
|
||||
out_path: PathBuf,
|
||||
|
@ -356,8 +350,28 @@ fn unpack(aes_key: Option<aes::Aes256>, action: ActionUnpack) -> Result<(), repa
|
|||
.into_iter()
|
||||
.map(|entry_path| {
|
||||
let full_path = mount_point.join(&entry_path);
|
||||
if !includes.is_empty() && !includes.iter().any(|i| full_path.starts_with(i)) {
|
||||
return Ok(None);
|
||||
if !action.include.is_empty() {
|
||||
if let Ok(stripped) = full_path.strip_prefix(prefix) {
|
||||
let options = glob::MatchOptions {
|
||||
case_sensitive: true,
|
||||
require_literal_separator: true,
|
||||
require_literal_leading_dot: false,
|
||||
};
|
||||
if !action.include.iter().any(|i| {
|
||||
// check full file path
|
||||
i.matches_path_with(stripped, options)
|
||||
// check ancestor directories
|
||||
|| stripped.ancestors().skip(1).any(|a| {
|
||||
i.matches_path_with(a, options)
|
||||
// hack to check ancestor directories with trailing slash
|
||||
|| i.matches_path_with(&a.join(""), options)
|
||||
})
|
||||
}) {
|
||||
return Ok(None);
|
||||
}
|
||||
} else {
|
||||
return Ok(None);
|
||||
}
|
||||
}
|
||||
let out_path = output
|
||||
.join(full_path.strip_prefix(prefix).map_err(|_| {
|
||||
|
|
|
@ -148,6 +148,26 @@ fn test_cli_unpack() {
|
|||
// TODO test unpacking to non-empty directory
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_cli_unpack_include() {
|
||||
let dir = tempfile::tempdir().unwrap();
|
||||
|
||||
let assert = Command::cargo_bin("repak")
|
||||
.unwrap()
|
||||
.arg("unpack")
|
||||
.arg(PAK)
|
||||
.arg("-s")
|
||||
.arg("../mount")
|
||||
.arg("-i")
|
||||
.arg("point/**/*.txt")
|
||||
.arg("-o")
|
||||
.arg(dir.path())
|
||||
.assert();
|
||||
assert.success().stdout(formatdoc! {r#"
|
||||
Unpacked 2 files to {} from ../repak/tests/packs/pack_v11.pak
|
||||
"#, &dir.path().to_string_lossy()});
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_cli_hashlist() {
|
||||
let assert = Command::cargo_bin("repak")
|
||||
|
|
Loading…
Reference in a new issue