Skip to content

Use walker from ignore crate - #2756

Open
luuumine wants to merge 2 commits into
molybdenumsoftware:masterfrom
luuumine:rewrite
Open

Use walker from ignore crate#2756
luuumine wants to merge 2 commits into
molybdenumsoftware:masterfrom
luuumine:rewrite

Conversation

@luuumine

Copy link
Copy Markdown

As discussed in #2751, this PR rewrites the walk_nix_files function to use WalkBuilder from the ignore crate directly.

This also adds support for nested gitignores and a new test for those.

@mightyiam mightyiam left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not a comprehensive review.

Comment thread bin/src/dirs.rs
Comment thread bin/src/dirs.rs Outdated
Comment thread bin/src/dirs.rs Outdated
Comment thread bin/src/dirs.rs Outdated
builder.standard_filters(false);
} else {
builder.require_git(false);
builder.add_custom_ignore_filename(".gitignore");

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this really necessary? Wouldn't this be one of the standard filters?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

true, just removed this and behavior stayed as expected with all tests passing

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🤔 but it's still here? Or is GitHub showing this on a line of code that is not the original of this comment?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

current code is rust if unrestricted { builder.standard_filters(false); } else { builder.add_custom_ignore_filename(".gitignore"); }
we cant remove any of those lines if we want the tests to pass

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hrm... I'm reading the library docs and it seems to me that the behavior would be the same without this else. Am I missing something?

Comment thread bin/src/dirs.rs
// Disables .gitignore parsing, global ignores, and .git/ exclusion natively.
builder.standard_filters(false);
} else {
builder.require_git(false);

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I find this actually interesting. I think we should have a test for current behavior in default branch prior to this PR.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i just checked this against the code present in master

  • in unrestricted: the walker does traverse .git. this seems expected to me. any user could probably just add .git to their ignore list manually
  • in "normal" mode, .git is not traversed

i can confirm this behavior is what we have in the new branch, and added 2 new tests to check both cases

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What about this part from the require_git docs

In particular, if this is false then .gitignore files will be read from parent directories above the git root directory containing .git, which is different from the git behavior.

Do you think we have a test for this in master?

@luuumine
luuumine requested a review from mightyiam August 30, 2026 09:28
@mightyiam

Copy link
Copy Markdown
Member

Would it be more prudent that tests that pass in the default branch be added in a prior PR?

@luuumine

luuumine commented Aug 30, 2026

Copy link
Copy Markdown
Author

I can add them in another PR if that's something you'd prefer

@mightyiam

Copy link
Copy Markdown
Member

Well, I think achieving the coverage that will give us (me as reviewer?) confidence with regards to suggested changes, as an independent step, with no implementation changes, on the default branch, would mean I don't have to take your word on it, nor do I have to test it myself.

@luuumine

Copy link
Copy Markdown
Author

fair enough! do you want me to add all the tests in a separate PR first (even the non-passing one with the nested gitignores) or only the ones that pass (hidden files, missing path, and the tests regarding .git and the unrestricted mode) ?

@mightyiam

Copy link
Copy Markdown
Member

Thank you for asking. I'd be most convenienced with a precursor PR that has all the passing tests.

@mightyiam

Copy link
Copy Markdown
Member

Oh, and that precursor PR would have no implementation changes.

@luuumine luuumine mentioned this pull request Aug 30, 2026
@luuumine

Copy link
Copy Markdown
Author

Thanks for your reply, i just created the new PR

@mightyiam

Copy link
Copy Markdown
Member

Brilliant, thank you! Would you mind rebasing?

@luuumine

Copy link
Copy Markdown
Author

that would be it. please tell me if anything else needs fixing. otherwise, i believe that you can squash merge that

@mightyiam mightyiam left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🤔 are we missing precursor test in the default branch for current behavior that has to do with the behavior that is described in WalkBuilder::require_git?

Comment thread bin/src/dirs.rs Outdated
Comment thread bin/src/dirs.rs Outdated
builder.standard_filters(false);
} else {
builder.require_git(false);
builder.add_custom_ignore_filename(".gitignore");

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🤔 but it's still here? Or is GitHub showing this on a line of code that is not the original of this comment?

Comment thread bin/src/dirs.rs Outdated
Comment thread bin/src/dirs.rs Outdated
Comment thread bin/src/dirs.rs Outdated

Ok(builder
.build()
.filter_map(Result::ok)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are we currently ignoring walk errors?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what do you mean buy walk errors? as talked in the previous PR and added in the new test, it exist with 0 (no error) on the missing_path error. this is current behavior and stays the case after this PR.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This filter_map seems to ignore walking errors.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For example, if the directory is removed during the walk 🤷, we'd probably get an error here and this would ignore that error. I don't think we should be ignoring such errors.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

But regardless of what we should be doing, it is more important that we don't change existing behavior. Perhaps a test that triggers a walk error. I think such a test can be achieved by removing the read permission bit of a file inside the target directory. It should be a precursor, existing behavior test, if I get to decide.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i believe it would be a good idea (in a later PR probably?) to change the some error behaviors, especially the fact that, on a missing path, the programs exits with status code 0 (no error).
i don't really know how we could test the removal of a directory during traversal or equivalent though.
adding more tests around error behaviors later could be a good idea though

Comment thread bin/src/dirs.rs Outdated
Comment thread bin/src/dirs.rs Outdated

@mightyiam mightyiam left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Getting closer

Comment thread bin/src/dirs.rs
Comment thread bin/src/dirs.rs Outdated
builder.standard_filters(false);
} else {
builder.require_git(false);
builder.add_custom_ignore_filename(".gitignore");

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hrm... I'm reading the library docs and it seems to me that the behavior would be the same without this else. Am I missing something?

Comment thread bin/src/dirs.rs Outdated
Comment thread bin/src/dirs.rs
});

Ok(builder.build().filter_map(|entry| {
let entry = entry.ok()?;

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To continue conversation about error handling of walk errors: this seems to just ignore these errors. As I wrote elsewhere, would you be happy adding a test in a precursor PR that confirms whateber the current behavior is?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Continuing from #2756 (comment)

i believe it would be a good idea (in a later PR probably?) to change the some error behaviors, especially the fact that, on a missing path, the programs exits with status code 0 (no error).

I don't have the confidence that that is the current behavior. That is why I am interested in having a test added in a precursor PR to confirm whatever the current bevahior is.

i don't really know how we could test the removal of a directory during traversal or equivalent though. adding more tests around error behaviors later could be a good idea though

I think this could be achieved by having a file with the read permission bit removed, within the target directory.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Made the PR for those 2 new tests in #2759

@luuumine

Copy link
Copy Markdown
Author

@mightyiam Continuing the conversation here because for some reason GitHub doesnt let me reply in the thread about the else block.
We either need a require_git(false) or a add_custom_ignore_filename(".gitignore") block. The ignore crate only reads gitignore files if we are in git repositories. During the tests, this is not the case as we are in a tempdir..
I changed it to keep the require_git(false) block instead of the add_custom_ignore_filename one because this makes its purpose clearer.

@luuumine

luuumine commented Sep 1, 2026

Copy link
Copy Markdown
Author

Just rebased the branch to includes tests from #2759
You can merge that

@mightyiam mightyiam left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry for not finding all my concerns in one go 😅

Comment thread bin/src/dirs.rs
// Disables .gitignore parsing, global ignores, and .git/ exclusion natively.
builder.standard_filters(false);
} else {
builder.require_git(false);

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What about this part from the require_git docs

In particular, if this is false then .gitignore files will be read from parent directories above the git root directory containing .git, which is different from the git behavior.

Do you think we have a test for this in master?

Comment thread bin/src/dirs.rs
for i in ignore {
gitignore.add_line(None, i.as_str())?;
for ignore_rule in extra_ignores {
gitignore.add_line(None, ignore_rule)?;

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🤔 I'm also concerned about not having a test with regards to --ignore not ignoring files it should not. And its behavior with regards to files inside directories. And its behavior with arguments that are paths, not only filenames.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants