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",
|
"wasi",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "glob"
|
||||||
|
version = "0.3.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "heck"
|
name = "heck"
|
||||||
version = "0.4.1"
|
version = "0.4.1"
|
||||||
|
@ -704,6 +710,7 @@ dependencies = [
|
||||||
"base64",
|
"base64",
|
||||||
"clap",
|
"clap",
|
||||||
"dir-diff",
|
"dir-diff",
|
||||||
|
"glob",
|
||||||
"hex",
|
"hex",
|
||||||
"indicatif",
|
"indicatif",
|
||||||
"indoc",
|
"indoc",
|
||||||
|
|
|
@ -34,6 +34,7 @@ rayon = "1.10.0"
|
||||||
sha2 = "0.10.8"
|
sha2 = "0.10.8"
|
||||||
strum = { workspace = true }
|
strum = { workspace = true }
|
||||||
itertools = "0.13.0"
|
itertools = "0.13.0"
|
||||||
|
glob = "0.3.1"
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
assert_cmd = "2.0.14"
|
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.
|
/// Files or directories to include. Can be specified multiple times. If not specified, everything is extracted.
|
||||||
#[arg(action = clap::ArgAction::Append, short, long)]
|
#[arg(action = clap::ArgAction::Append, short, long)]
|
||||||
include: Vec<String>,
|
include: Vec<glob::Pattern>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Parser, Debug)]
|
#[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 mount_point = PathBuf::from(pak.mount_point());
|
||||||
let prefix = Path::new(&action.strip_prefix);
|
let prefix = Path::new(&action.strip_prefix);
|
||||||
|
|
||||||
let includes = action
|
|
||||||
.include
|
|
||||||
.iter()
|
|
||||||
.map(|i| prefix.join(Path::new(i)))
|
|
||||||
.collect::<Vec<_>>();
|
|
||||||
|
|
||||||
struct UnpackEntry {
|
struct UnpackEntry {
|
||||||
entry_path: String,
|
entry_path: String,
|
||||||
out_path: PathBuf,
|
out_path: PathBuf,
|
||||||
|
@ -356,8 +350,28 @@ fn unpack(aes_key: Option<aes::Aes256>, action: ActionUnpack) -> Result<(), repa
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.map(|entry_path| {
|
.map(|entry_path| {
|
||||||
let full_path = mount_point.join(&entry_path);
|
let full_path = mount_point.join(&entry_path);
|
||||||
if !includes.is_empty() && !includes.iter().any(|i| full_path.starts_with(i)) {
|
if !action.include.is_empty() {
|
||||||
return Ok(None);
|
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
|
let out_path = output
|
||||||
.join(full_path.strip_prefix(prefix).map_err(|_| {
|
.join(full_path.strip_prefix(prefix).map_err(|_| {
|
||||||
|
|
|
@ -148,6 +148,26 @@ fn test_cli_unpack() {
|
||||||
// TODO test unpacking to non-empty directory
|
// 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]
|
#[test]
|
||||||
fn test_cli_hashlist() {
|
fn test_cli_hashlist() {
|
||||||
let assert = Command::cargo_bin("repak")
|
let assert = Command::cargo_bin("repak")
|
||||||
|
|
Loading…
Reference in a new issue