Honor Projectile's ignore rules under alien indexing#2104
Conversation
Alien indexing delegated the walk to an external tool and then did nothing else, so none of Projectile's ignore configuration applied: not the globally-ignored files/directories/suffixes, and not the `-' entries of a project's .projectile. This was a long-standing source of confusion - enough that we shipped a warning whose only job was to tell people their .projectile was being bypassed. Rather than post-filtering the output (which is what hybrid does, and would collapse the two methods into one), push the rules down into the tool itself: git ls-files takes `:(exclude,glob)' pathspecs and fd takes repeated `-E' globs, so the filtering still happens outside Emacs and alien stays fast. The few tools that can't express exclusions at all (svn, fossil, bzr, darcs, pijul and the plain find fallback) fall back to filtering the output in Lisp, so behaviour is uniform either way. Git submodule listings run their own ls-files that never saw our exclusions, so those get the Lisp pass too. The new `projectile-alien-honors-ignores' opts out and restores the 3.2 behaviour. The exclusions also ride on the command published by projectile-project-files-producer, so external finders built on the seam show the same file set projectile-find-file does. Dirconfig `+' keep and `!' unignore entries can't be expressed as tool exclusions and remain hybrid/native only. The acceptance test builds a real git repo and asserts alien and hybrid produce the same file set. The warning and its option are gone.
The manual's indexing comparison table said alien honored none of them, and ignoring.adoc opened with a warning that .projectile is ignored under alien. Both are now wrong. Split the dirconfig row in two, since `-` entries apply everywhere but `+`/`!` are still hybrid/native only.
Found by differentially testing alien against native - which is the real oracle here, since native applies the rules directly in Lisp. Comparing alien to hybrid (as the acceptance test did) can't catch a mistranslation, because both start from the same external listing. - Don't push the rules down under hybrid. Both methods share projectile-dir-files-alien, so hybrid was getting the exclusions on the command *and* running its own filter afterwards, which silently gave it alien's semantics wherever the two differ: a bare projectile-globally-ignored-directories entry is top-level-only under hybrid but any-depth under alien, so hybrid quietly started dropping nested matches. Hybrid filters its own output and needs no push-down. - Strip the `*' marker from globally ignored directory names. A leading `*' there means "at any depth", it is not a wildcard, so passing it to a glob matcher made `*.osc' also match `foo.osc'. This also fixes the same latent bug in the globs handed to project.el's project-ignores and to the ripgrep search path, which shared the translation. Adds a native/alien parity spec covering globs, directory patterns and `?' wildcards, plus regressions for both fixes. Documents which tools push the rules down and which get their output filtered, and the any-depth difference from hybrid.
ENSIME was archived in 2018 and .eunit is a rebar2 artifact, so both were pure noise - and now that the ignore rules are handed to the external indexing tool, every stale entry is an argument on every indexing command. The rest of the list earns its place: the VCS metadata directories all correspond to a VCS Projectile supports, and .idea/.vscode/.tox/.stack-work/.ccls-cache/.clangd are all current.
|
Trimmed Comparing alien against Separately: |
native and hybrid fold case (string-suffix-p's IGNORE-CASE argument, and case-fold-search defaulting to t for the dirconfig regexps); git pathspecs and fd --exclude do not. Worth stating plainly until we decide which of the two behaviours is the one we actually want.
native and hybrid folded case: string-suffix-p was called with its IGNORE-CASE argument for the ignored suffixes, and the pattern matching went through string-match-p, which honours case-fold-search - t by default. So `.elc' also hid BUILD.ELC. git pathspecs and fd --exclude have no equivalent (fd can't be made case-insensitive per-exclude at all), which left the three methods disagreeing once alien started honouring the rules. Rather than reproduce the folding in the tools, drop it: pin case-fold-search off around the ignore matchers and stop passing IGNORE-CASE to string-suffix-p. Case-sensitive is also the less surprising reading on a case-sensitive filesystem. The one spec that pinned the old behaviour (foo.tar.GZ removed by a `.tar.gz' entry) dates to 2017 and looks incidental to the change it rode in on - that commit was about treating the entries as suffixes at all, not about case. Updated, with explicit specs for both matchers.
|
Made ignore matching case-sensitive everywhere instead of teaching the tools to fold case. The folding was incidental anyway: |
One sentence per entry, with bullets for the two that genuinely need them, instead of a paragraph each.
alienis the default indexing method and it applied none of Projectile's ignore rules - not the globally-ignored files/dirs/suffixes, not the-entries of a.projectile. We even shipped a warning whose only job was to say the dirconfig was being bypassed.Post-filtering the output is what
hybridalready does, so instead the rules are handed to the tool: exclude pathspecs forgit ls-files,-Eglobs forfd. Tools that can't express exclusions (svn, fossil, bzr, darcs, pijul, plainfind) get their output filtered in Lisp.projectile-alien-honors-ignoresturns it all off.Two follow-on changes fell out of testing it against
native:+keep and!unignore entries stay hybrid/native only (no tool equivalent), and ignore matching is now case-sensitive everywhere -native/hybridused to fold case, whichfdcan't reproduce at all.Alien projects will list fewer files after this. That's the point, but it's the kind of change worth knowing about.