From 37483036e0d9fc0a13abb8326c97e903c6893dca Mon Sep 17 00:00:00 2001 From: sharkdp Date: Mon, 26 Mar 2018 00:15:01 +0200 Subject: [PATCH] Implement --ignore-file --- src/app.rs | 11 +++++++++++ src/internal.rs | 4 ++++ src/main.rs | 4 ++++ src/walk.rs | 17 +++++++++++++++++ tests/tests.rs | 25 ++++++++++++++++++++++--- 5 files changed, 58 insertions(+), 3 deletions(-) diff --git a/src/app.rs b/src/app.rs index 1f823db..14291a3 100644 --- a/src/app.rs +++ b/src/app.rs @@ -122,6 +122,14 @@ pub fn build_app() -> App<'static, 'static> { .number_of_values(1) .multiple(true), ) + .arg( + arg("ignore-file") + .long("ignore-file") + .takes_value(true) + .value_name("path") + .number_of_values(1) + .multiple(true), + ) .arg( arg("color") .long("color") @@ -220,6 +228,9 @@ fn usage() -> HashMap<&'static str, Help> { , "Exclude entries that match the given glob pattern" , "Exclude files/directories that match the given glob pattern. This overrides any \ other ignore logic. Multiple exclude patterns can be specified."); + doc!(h, "ignore-file" + , "Add a custom ignore-file in .gitignore format" + , "Add a custom ignore-file in .gitignore format. These files have a low precedence."); doc!(h, "color" , "When to use colors: never, *auto*, always" , "Declare when to use color for the pattern match output:\n \ diff --git a/src/internal.rs b/src/internal.rs index 6b3a473..7b6ceeb 100644 --- a/src/internal.rs +++ b/src/internal.rs @@ -10,6 +10,7 @@ use std::ffi::OsString; use std::process; use std::time; use std::io::Write; +use std::path::PathBuf; use exec::CommandTemplate; use lscolors::LsColors; @@ -92,6 +93,9 @@ pub struct FdOptions { /// A list of glob patterns that should be excluded from the search. pub exclude_patterns: Vec, + + /// A list of custom ignore files. + pub ignore_files: Vec, } /// Print error message to stderr and exit with status `1`. diff --git a/src/main.rs b/src/main.rs index 65815d0..a57b6d5 100644 --- a/src/main.rs +++ b/src/main.rs @@ -191,6 +191,10 @@ fn main() { .values_of("exclude") .map(|v| v.map(|p| String::from("!") + p).collect()) .unwrap_or_else(|| vec![]), + ignore_files: matches + .values_of("ignore-file") + .map(|vs| vs.map(PathBuf::from).collect()) + .unwrap_or_else(|| vec![]), }; match RegexBuilder::new(&pattern_regex) diff --git a/src/walk.rs b/src/walk.rs index f151ea6..adf5bcd 100644 --- a/src/walk.rs +++ b/src/walk.rs @@ -14,6 +14,7 @@ use internal::{error, FdOptions, EXITCODE_SIGINT, MAX_BUFFER_LENGTH}; use output; use std::process; +use std::error::Error; use std::path::PathBuf; use std::sync::{Arc, Mutex}; use std::sync::atomic::{AtomicBool, Ordering}; @@ -76,6 +77,22 @@ pub fn scan(path_vec: &[PathBuf], pattern: Arc, config: Arc) { walker.add_custom_ignore_filename(".fdignore"); } + for ignore_file in &config.ignore_files { + let result = walker.add_ignore(ignore_file); + if let Some(err) = result { + match err { + ignore::Error::Partial(_) => (), + _ => { + error(&format!( + "Error while parsing custom ignore file '{}': {}.", + ignore_file.to_string_lossy(), + err.description() + )); + } + } + } + } + for path_entry in path_iter { walker.add(path_entry.as_path()); } diff --git a/tests/tests.rs b/tests/tests.rs index fc72080..a1790a2 100644 --- a/tests/tests.rs +++ b/tests/tests.rs @@ -297,9 +297,9 @@ fn test_no_ignore() { ); } -/// Custom ignore files +/// .gitignore and .fdignore #[test] -fn test_custom_ignore() { +fn test_gitignore_and_fdignore() { let files = &[ "ignored-by-nothing", "ignored-by-fdignore", @@ -335,7 +335,7 @@ fn test_custom_ignore() { ); } -/// Precedence of custom ignore files +/// Precedence of .fdignore files #[test] fn test_custom_ignore_precedence() { let dirs = &["inner"]; @@ -378,6 +378,25 @@ fn test_no_ignore_vcs() { ); } +/// Custom ignore files (--ignore-file) +#[test] +fn test_custom_ignore_files() { + let te = TestEnv::new(DEFAULT_DIRS, DEFAULT_FILES); + + // Ignore 'C.Foo2' and everything in 'three'. + fs::File::create(te.test_root().join("custom.ignore")) + .unwrap() + .write_all(b"C.Foo2\nthree") + .unwrap(); + + te.assert_output( + &["--ignore-file", "custom.ignore", "foo"], + "a.foo + one/b.foo + one/two/c.foo", + ); +} + /// Ignored files with ripgrep aliases (-u / -uu) #[test] fn test_no_ignore_aliases() {