Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file added exampledir/test/test.xlsx
Binary file not shown.
11 changes: 8 additions & 3 deletions src/adapters.rs
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,10 @@ pub struct AdaptInfo {
/// (enabledAdapters, disabledAdapters)
type AdaptersTuple = (Vec<Arc<dyn FileAdapter>>, Vec<Arc<dyn FileAdapter>>);

pub fn get_all_adapters(custom_adapters: Option<Vec<CustomAdapterConfig>>) -> AdaptersTuple {
pub fn get_all_adapters(
custom_adapters: Option<Vec<CustomAdapterConfig>>,
additional_extensions_zip: Option<Vec<String>>,
) -> AdaptersTuple {
// order in descending priority
let mut adapters: Vec<Arc<dyn FileAdapter>> = vec![];
if let Some(custom_adapters) = custom_adapters {
Expand All @@ -121,7 +124,7 @@ pub fn get_all_adapters(custom_adapters: Option<Vec<CustomAdapterConfig>>) -> Ad
let internal_adapters: Vec<Arc<dyn FileAdapter>> = vec![
Arc::new(PostprocPageBreaks::default()),
Arc::new(ffmpeg::FFmpegAdapter::new()),
Arc::new(zip::ZipAdapter::new()),
Arc::new(zip::ZipAdapter::new(additional_extensions_zip)),
Arc::new(decompress::DecompressAdapter::new()),
Arc::new(mbox::MboxAdapter::new()),
Arc::new(tar::TarAdapter::new()),
Expand Down Expand Up @@ -150,8 +153,10 @@ pub fn get_all_adapters(custom_adapters: Option<Vec<CustomAdapterConfig>>) -> Ad
pub fn get_adapters_filtered<T: AsRef<str>>(
custom_adapters: Option<Vec<CustomAdapterConfig>>,
adapter_names: &[T],
additional_extensions_zip: Option<Vec<String>>,
) -> Result<Vec<Arc<dyn FileAdapter>>> {
let (def_enabled_adapters, def_disabled_adapters) = get_all_adapters(custom_adapters);
let (def_enabled_adapters, def_disabled_adapters) =
get_all_adapters(custom_adapters, additional_extensions_zip);
let adapters = if !adapter_names.is_empty() {
let adapters_map: HashMap<_, _> = def_enabled_adapters
.iter()
Expand Down
65 changes: 41 additions & 24 deletions src/adapters/zip.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,39 +2,44 @@ use super::*;
use crate::print_bytes;
use anyhow::*;
use async_stream::stream;
use lazy_static::lazy_static;
// use lazy_static::lazy_static;
use log::*;

// TODO: allow users to configure file extensions instead of hard coding the list
// https://github.com/phiresky/ripgrep-all/pull/208#issuecomment-2173241243
static EXTENSIONS: &[&str] = &["zip", "jar", "xpi", "kra", "snagx"];

lazy_static! {
static ref METADATA: AdapterMeta = AdapterMeta {
name: "zip".to_owned(),
version: 1,
description: "Reads a zip file as a stream and recurses down into its contents".to_owned(),
recurses: true,
fast_matchers: EXTENSIONS
.iter()
.map(|s| FastFileMatcher::FileExtension(s.to_string()))
.collect(),
slow_matchers: Some(vec![FileMatcher::MimeType("application/zip".to_owned())]),
keep_fast_matchers_if_accurate: false,
disabled_by_default: false
};
// #[derive(Default, Clone)]
pub struct ZipAdapter {
metadata: AdapterMeta,
}
#[derive(Default, Clone)]
pub struct ZipAdapter;

impl ZipAdapter {
pub fn new() -> ZipAdapter {
ZipAdapter
pub fn new(additional_extensions_zip: Option<Vec<String>>) -> ZipAdapter {
let mut extensions: Vec<String> = EXTENSIONS.iter().map(|&s| s.to_string()).collect();
if let Some(additional_extensions) = additional_extensions_zip {
extensions.extend(additional_extensions);
}

let metadata = AdapterMeta {
name: "zip".to_owned(),
version: 1,
description: "Reads a zip file as a stream and recurses down into its contents"
.to_owned(),
recurses: true,
fast_matchers: extensions
.iter()
.map(|s| FastFileMatcher::FileExtension(s.to_string()))
.collect(),
slow_matchers: Some(vec![FileMatcher::MimeType("application/zip".to_owned())]),
keep_fast_matchers_if_accurate: false,
disabled_by_default: false,
};

ZipAdapter { metadata }
}
}
impl GetMetadata for ZipAdapter {
fn metadata(&self) -> &AdapterMeta {
&METADATA
&self.metadata
}
}

Expand Down Expand Up @@ -225,7 +230,7 @@ mod test {
async fn only_seek_zip_fs() -> Result<()> {
let zip = test_data_dir().join("only-seek-zip.zip");
let (a, d) = simple_fs_adapt_info(&zip).await?;
let _v = adapted_to_vec(loop_adapt(&ZipAdapter::new(), d, a).await?).await?;
let _v = adapted_to_vec(loop_adapt(&ZipAdapter::new(None), d, a).await?).await?;
// assert_eq!(String::from_utf8(v)?, "");

Ok(())
Expand All @@ -242,7 +247,7 @@ mod test {
#[tokio::test]
async fn recurse() -> Result<()> {
let zipfile = create_zip("outer.txt", "outer text file", true).await?;
let adapter = ZipAdapter::new();
let adapter = ZipAdapter::new(None);

let (a, d) = simple_adapt_info(
&PathBuf::from("outer.zip"),
Expand All @@ -255,6 +260,18 @@ mod test {
"PREFIX:outer.txt: outer text file\nPREFIX:inner.zip: inner.txt: inner text file\n",
);

Ok(())
}
#[tokio::test]
async fn search_xlsx_with_extension_config() -> Result<()> {
let zip = test_data_dir().join("test.xlsx");
let (a, d) = simple_fs_adapt_info(&zip).await?;
let v = adapted_to_vec(
loop_adapt(&ZipAdapter::new(Some(vec![String::from("xlsx")])), d, a).await?,
)
.await?;
assert_eq!(String::from_utf8(v[..18].to_vec())?, "PREFIX:_rels/.rels"); // first filename in the spreadsheet archive

Ok(())
}
}
9 changes: 7 additions & 2 deletions src/bin/rga.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,8 @@ use std::process::Command;
use std::time::Instant;

fn list_adapters(args: RgaConfig) -> Result<()> {
let (enabled_adapters, disabled_adapters) = get_all_adapters(args.custom_adapters);
let (enabled_adapters, disabled_adapters) =
get_all_adapters(args.custom_adapters, args.additional_extensions_zip);

println!("Adapters:\n");
let print = |adapter: std::sync::Arc<dyn FileAdapter>| {
Expand Down Expand Up @@ -92,7 +93,11 @@ fn main() -> anyhow::Result<()> {
return Ok(());
}

let adapters = get_adapters_filtered(config.custom_adapters.clone(), &config.adapters)?;
let adapters = get_adapters_filtered(
config.custom_adapters.clone(),
&config.adapters,
config.additional_extensions_zip,
)?;

let pre_glob = if !config.accurate {
let extensions = adapters
Expand Down
5 changes: 5 additions & 0 deletions src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,11 @@ pub struct RgaConfig {
#[serde(default, skip_serializing_if = "is_default")]
#[structopt(skip)]
pub custom_adapters: Option<Vec<CustomAdapterConfig>>,

/// List of additional extensions to be treated as zip archives
#[serde(default, skip_serializing_if = "is_default")]
#[structopt(skip)]
pub additional_extensions_zip: Option<Vec<String>>,
//////////////////////////////////////////
//////////////////////////// CMD line only
//////////////////////////////////////////
Expand Down
6 changes: 5 additions & 1 deletion src/preproc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,11 @@ async fn choose_adapter(
archive_recursion_depth: i32,
inp: &mut (impl AsyncBufRead + Unpin),
) -> Result<Option<(Arc<dyn FileAdapter>, FileMatcher, ActiveAdapters)>> {
let active_adapters = get_adapters_filtered(config.custom_adapters.clone(), &config.adapters)?;
let active_adapters = get_adapters_filtered(
config.custom_adapters.clone(),
&config.adapters,
config.additional_extensions_zip.clone(),
)?;
let adapters = adapter_matcher(&active_adapters, config.accurate)?;
let filename = filepath_hint
.file_name()
Expand Down