Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Custom ignore files can not be used exclusively #800

Closed
sharkdp opened this issue Feb 13, 2018 · 3 comments
Closed

Custom ignore files can not be used exclusively #800

sharkdp opened this issue Feb 13, 2018 · 3 comments
Labels
bug A bug.

Comments

@sharkdp
Copy link
Sponsor Contributor

sharkdp commented Feb 13, 2018

What version of the ignore crate are you using?

ignore-0.4.0

Describe your question, feature request, or bug.

It would be great if the custom ignore files (that are available since ignore-0.4.0) could be used exclusively without having to enable .ignore or .gitignore files as well.

If this is a bug, what are the steps to reproduce the behavior?

Run the following test case:

#[test]
fn custom_ignore() {
    let td = TempDir::new("walk-test-").unwrap();
    let custom_ignore = ".customignore";
    mkdirp(td.path().join("a"));
    wfile(td.path().join(custom_ignore), "foo");
    wfile(td.path().join("foo"), "");
    wfile(td.path().join("a/foo"), "");
    wfile(td.path().join("bar"), "");
    wfile(td.path().join("a/bar"), "");

    let mut builder = WalkBuilder::new(td.path());

    // THE FOLLOWING FOUR LINES HAVE BEEN
    // ADDED W.R.T. AN EXISTING TEST CASE
    builder.ignore(false);
    builder.git_ignore(false);
    builder.git_global(false);
    builder.git_exclude(false);

    builder.add_custom_ignore_filename(&custom_ignore);
    assert_paths(td.path(), &builder, &["bar", "a", "a/bar"]);
}

If this is a bug, what is the actual behavior?

The test case fails because the foo files are not ignored:

---- walk::tests::custom_ignore stdout ----
	thread 'walk::tests::custom_ignore' panicked at 'assertion failed: `(left == right)`
  left: `["a", "a/bar", "a/foo", "bar", "foo"]`,
 right: `["a", "a/bar", "bar"]`', src/walk.rs:1554:8

If this is a bug, what is the expected behavior?

The test case succeeds.

Analysis

The cause for this behavior is the following function in ignore/src/dir.rs:

    fn has_any_ignore_options(&self) -> bool {
        self.ignore || self.git_global || self.git_ignore || self.git_exclude
    }

.. which returns false if all of these are disabled. This, in turn, causes Ignore::matched to skip ignore files alltogether:

        if self.0.opts.has_any_ignore_options() {
            let mat = self.matched_ignore(path, is_dir);
            if mat.is_ignore() {
                return mat;
            } else if mat.is_whitelist() {
                whitelisted = mat;
            }
        }

If the above behavior is actually intended, a simple bugfix would be to add the following:

        if self.0.opts.has_any_ignore_options() || !self.0.custom_ignore_filenames.is_empty() {
            // ...
        }
@BurntSushi
Copy link
Owner

Thanks for the clear bug report! This definitely sounds like a bug, and has_any_ignore_options should probably be removed in favor of a predicate that covers all of the cases.

@sharkdp
Copy link
Sponsor Contributor Author

sharkdp commented Feb 13, 2018

By the way, ripgrep itself is not "affected" (I think) because the custom ignore file (.rgignore) is always enabled together with .ignore. Therefore, IgnoreOptions::ignore will be enabled if .rgignore files should be used and has_any_ignore_options() returns true.

@BurntSushi
Copy link
Owner

@sharkdp Yup I believe you're right. Thanks for noticing this and filing a bug. :)

phiresky added a commit to phiresky/ripgrep that referenced this issue Jul 21, 2018
When building a ignore::WalkBuilder by disabling all standard filters
and adding a custom global ignore file, the ignore file is not used. Example:

    let mut walker = ignore::WalkBuilder::new(dir);
    walker.standard_filters(false);
    walker.add_ignore(myfile);

This makes it impossible to use the ignore crate to walk a directory
with only custom ignore files. Very similar to issue BurntSushi#800 (fixed in
b71a110).
BurntSushi pushed a commit that referenced this issue Jul 21, 2018
When building a ignore::WalkBuilder by disabling all standard filters
and adding a custom global ignore file, the ignore file is not used. Example:

    let mut walker = ignore::WalkBuilder::new(dir);
    walker.standard_filters(false);
    walker.add_ignore(myfile);

This makes it impossible to use the ignore crate to walk a directory
with only custom ignore files. Very similar to issue #800 (fixed in
b71a110).

PR #988
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug A bug.
Projects
None yet
Development

No branches or pull requests

2 participants