bbatsov / projectile

Project Interaction Library for Emacs
https://docs.projectile.mx
GNU General Public License v3.0
3.97k stars 584 forks source link

`projectile-globally-ignored-directories` not working for `projectile-ripgrep` #1811

Open TheJJ opened 1 year ago

TheJJ commented 1 year ago

Expected behavior

Directories and pattterns from projectile-globally-ignored-directories should correctly be used by projectile-ripgrep.

Actual behavior

The patterns are regexes, but ripgrep expects globs. ripgrep is invoked with --hidden --glob ! ^\.git$, and .git is not a valid glob pattern.

Steps to reproduce the problem

Possible fix

The regexes have to be converted to globs so ripgrep will like them. Alternatively ripgrep must gain a new regex-file-filter option.

Environment & Version information

Projectile version information

Projectile version: 20221101.848

Emacs version

GNU Emacs 29.0.50

Heviwulansari commented 1 year ago

Expected behavior

Directories and pattterns from projectile-globally-ignored-directories should correctly be used by projectile-ripgrep.

Actual behavior

The patterns are regexes, but ripgrep expects globs. ripgrep is invoked with --hidden --glob ! ^\.git$, and .git is not a valid glob pattern.

Steps to reproduce the problem

  • be in a git project
  • echo rolf > .git/lolfile
  • projectile-ripgrep for rolf
  • see that there's a result in .git/lolfile even though .git should have been ignored.
  • a simpler test: rg --hidden --glob '! ^\.git$' rolf yields the same result, since that is how the ignorepatterns are passed.

Possible fix

The regexes have to be converted to globs so ripgrep will like them. Alternatively ripgrep must gain a new regex-file-filter option.

Environment & Version information

Projectile version information

Projectile version: 20221101.848

Emacs version

GNU Emacs 29.0.50

kisp commented 1 year ago

It would be nice if this could be fixed. :slightly_smiling_face:

I guess - as a workaround - the easiest thing would be to redefine projectile-ripgrep as my/projectile-ripgrep.

But for a real fix, probably the main question is how it should be done...

Looking at projectile-globally-ignored-directories, the regexes basically all have the same structure (^xxxxx$). Well, of course they could be different...

Would it be too much of a hacky approach to rely on that structure to translate them to glob syntax within projectile-ripgrep?

iarenaza commented 5 months ago

I have hit this same issue, and I have dug a bit into it. Pull request #1762 introduced the changes that, if I am not mistaken, are at the root of this issue.

Which, by the way, also broke the same functionality for projectile-grep (and maybe others?). Although projectile-grep still mostly works, because it uses grep-find-ignored-directories inside projectile-rgrep-default-command. And that variable is initialized with vc-directory-exclusion-list. Which contains most of the usual VCS directories.

The way I see it, the root of the problem is that we are using projectile-globally-ignored-directories for different use cases, with different types of consumers. And various of those consumers expect (need) a different "syntax" (actually, "semantics", see below). The docstring for projectile-globally-ignored-directories says (emphasis mine):

A list of directories globally ignored by projectile. Regular expressions can be used.

Which seems to suggest that the entries in that list can be either:

Which means that we have the same syntactic representation (a string value) for two totally different "semantics" (plain, fixed values vs. elisp regular expressions). And there is no way to tell which one of the two semantics applies to a particular entry.

And then each consumer of those entries (e.g., projectile-ripgrep, projectile-grep, projectile-ignored-directory-p, etc.) assumes that the entries have the right semantics for its own use, with the right kind of values. Which is not true in several cases. E.g., projectile-ripgrep assumes that the entries contain plain, fixed values, and then blindly converts them into the "gitignore glob patterns" that it needs. Which does not work at all, if the entries have elisp regular expressions in the first place (like they now have in the default defcustom value).

A similar thing happens with projectile-grep, that again assumes plain, fixed values and then blindly converts them into the "shell patterns" it uses. Which obviously produces incorrect "shell patterns".

projectile-ag is the exception here, because it uses regular expressions to ignore files and directories. So it still works as expected with the values introduced in pull request #1762.

So I guess any potential solution to this issue would need to consider the "two possible semantics" of the entries in projectile-globally-ignored-directories. Or, if that is not possible or too cumbersome to implement for the different consumers of those entries, we may have to split the list of entries into two different set of entries. One of them having all of the entries for one of the semantics (e.g., plain, fixed values), and the other having all of the entries for the other semantics (e.g., regular expression). And then the different consumers, knowing exactly which kind of semantics they need or want, would use one list, the other or even both.