Skip to content

Commit

Permalink
make glob and rx optional dependencies
Browse files Browse the repository at this point in the history
  • Loading branch information
cosmicexplorer committed Aug 27, 2024
1 parent 0dc57d2 commit b4914b7
Show file tree
Hide file tree
Showing 4 changed files with 68 additions and 9 deletions.
10 changes: 7 additions & 3 deletions cli/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,8 @@ members = ["."]
name = "zip-cli"

[dependencies]
# TODO: make these optional deps?
glob = "0.3"
regex = "1"
glob = { version = "0.3", optional = true }
regex = { version = "1", optional = true }

[dependencies.zip]
path = ".."
Expand All @@ -47,6 +46,9 @@ time = ["zip/time"]
xz = ["zip/xz"]
zstd = ["zip/zstd"]

glob = ["dep:glob"]
rx = ["dep:regex"]

default = [
"aes-crypto",
"bzip2",
Expand All @@ -56,6 +58,8 @@ default = [
"time",
"xz",
"zstd",
"glob",
"rx",
]


Expand Down
20 changes: 17 additions & 3 deletions cli/src/args/extract.rs
Original file line number Diff line number Diff line change
Expand Up @@ -48,11 +48,19 @@ impl PatternSelectorType {
}

pub const fn default_for_match() -> Self {
Self::Glob
if cfg!(feature = "glob") {
Self::Glob
} else {
Self::Literal
}
}

pub const fn default_for_replacement() -> Self {
Self::Regexp
if cfg!(feature = "rx") {
Self::Regexp
} else {
Self::Literal
}
}
}

Expand Down Expand Up @@ -1303,7 +1311,7 @@ entry itself.
*Note:* when multiple entry specs are provided on the command line, a single
entry may be matched more than once. In this case, the entry's content will be
extracted more than once over the execution of this command.
teed to all the specified outputs.
-x, --extract[=<name>]
Decompress the entry's contents (if necessary) before writing it to
Expand Down Expand Up @@ -1344,6 +1352,12 @@ pat-sel = glob [DEFAULT for matching] (interpret as a shell glob)
*Note:* glob patterns are not supported for replacement, and attempting to use
them with e.g '--transform:glob' will produce an error.
Also note that glob and regex patterns require building this binary with the
"glob" and "rx" cargo features respectively. Specifying ':glob' or ':rx' without
the requisite feature support will produce an error. If the requisite feature is
not provided, the default is to use literal matching, which is supported in
all cases.
#### Pattern modifiers (pat-mod):
pat-mod = :i (use case-insensitive matching for the given pattern)
= :g (use multi-match behavior for string replacements)
Expand Down
33 changes: 31 additions & 2 deletions cli/src/extract/matcher.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
use std::borrow::Cow;

#[cfg(feature = "glob")]
use glob;
#[cfg(feature = "rx")]
use regex;

use zip::CompressionMethod;
Expand Down Expand Up @@ -146,11 +148,13 @@ impl NameMatcher for LiteralMatcher {
}
}

#[cfg(feature = "glob")]
struct GlobMatcher {
pat: glob::Pattern,
glob_opts: glob::MatchOptions,
}

#[cfg(feature = "glob")]
impl NameMatcher for GlobMatcher {
fn create(pattern: String, opts: MatchModifiers) -> Result<Self, CommandError>
where
Expand Down Expand Up @@ -182,10 +186,12 @@ impl NameMatcher for GlobMatcher {
}
}

#[cfg(feature = "rx")]
struct RegexMatcher {
pat: regex::Regex,
}

#[cfg(feature = "rx")]
impl NameMatcher for RegexMatcher {
fn create(pattern: String, opts: MatchModifiers) -> Result<Self, CommandError>
where
Expand Down Expand Up @@ -407,9 +413,32 @@ impl EntryMatcher for PatternMatcher {

let opts = MatchModifiers::from_flags(modifiers)?;
let matcher: Box<dyn NameMatcher> = match pat_sel {
PatternSelectorType::Glob => Box::new(GlobMatcher::create(pattern, opts)?),
PatternSelectorType::Glob => {
#[cfg(feature = "glob")]
{
Box::new(GlobMatcher::create(pattern, opts)?)
}
#[cfg(not(feature = "glob"))]
{
return Err(CommandError::InvalidArg(format!(
"glob patterns were requested, but this binary was built without the \"glob\" feature: {pattern:?}"
)));
}
}

PatternSelectorType::Literal => Box::new(LiteralMatcher::create(pattern, opts)?),
PatternSelectorType::Regexp => Box::new(RegexMatcher::create(pattern, opts)?),
PatternSelectorType::Regexp => {
#[cfg(feature = "rx")]
{
Box::new(RegexMatcher::create(pattern, opts)?)
}
#[cfg(not(feature = "rx"))]
{
return Err(CommandError::InvalidArg(format!(
"regexp patterns were requested, but this binary was built without the \"rx\" feature: {pattern:?}"
)));
}
}
};

Ok(Self { matcher, comp_sel })
Expand Down
14 changes: 13 additions & 1 deletion cli/src/extract/transform.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use std::{borrow::Cow, collections::VecDeque, ops, path::Path, slice, str};

#[cfg(feature = "rx")]
use regex;

use super::matcher::{CaseSensitivity, SearchAnchoring};
Expand Down Expand Up @@ -353,12 +354,14 @@ impl PatternTransformer for LiteralTransformer {
}
}

#[cfg(feature = "rx")]
struct RegexpTransformer {
pat: regex::Regex,
multi: Multiplicity,
rep: String,
}

#[cfg(feature = "rx")]
impl PatternTransformer for RegexpTransformer {
type Replacement = String where Self: Sized;
fn create(
Expand Down Expand Up @@ -580,7 +583,16 @@ impl NameTransformer for ComponentTransformer {
Box::new(LiteralTransformer::create(pattern, opts, replacement_spec)?)
}
PatternSelectorType::Regexp => {
Box::new(RegexpTransformer::create(pattern, opts, replacement_spec)?)
#[cfg(feature = "rx")]
{
Box::new(RegexpTransformer::create(pattern, opts, replacement_spec)?)
}
#[cfg(not(feature = "rx"))]
{
return Err(CommandError::InvalidArg(format!(
"regexp patterns were requested, but this binary was built without the \"rx\" feature: {pattern:?}"
)));
}
}
};

Expand Down

0 comments on commit b4914b7

Please sign in to comment.