Implement --ignore-file

This commit is contained in:
sharkdp 2018-03-26 00:15:01 +02:00 committed by David Peter
parent 8c1b037279
commit 37483036e0
5 changed files with 58 additions and 3 deletions

View File

@ -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 \

View File

@ -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<String>,
/// A list of custom ignore files.
pub ignore_files: Vec<PathBuf>,
}
/// Print error message to stderr and exit with status `1`.

View File

@ -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)

View File

@ -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<Regex>, config: Arc<FdOptions>) {
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());
}

View File

@ -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() {