Repository navigation
Count only the exact .lean suffix as Lean source - #232
Conversation
The Lean source index treated Proj/Y.LEAN and Proj/W.Lean as Lean sources:
it read and indexed them, so `check --lean-root` resolved declarations from
files that Lake and `autoform skeleton` never see. A symbolic link, special
file or unreadable file with such a name failed the whole index ("unsafe Lean
source Proj/W.Lean: symbolic links are not supported"). (C4, blockers note 3,
r2-g2-exact-lean-suffix, NEW-SKELETON-SUFFIX)
Root cause: six sites in lean.py compared the suffix after case folding
(capture selection for links and other entries, the tolerated editor-lock
links, the unsupported-entry filter, the indexed-file loop and the
generation revision), while Lake's module globs (Lean.forEachModuleInDir),
skeleton.module_of and path_of, and the servers' file check all require the
exact ".lean" suffix.
Fix: one helper, _has_lean_suffix, compares the suffix exactly and is used at
all six sites. A case variant of any entry kind is now not captured, not
indexed, does not fail the index and does not change the source digest or
generation revision. Symbolic links and special files named exactly *.lean
are still refused. On a case-insensitive volume Lean can open Y.LEAN for
`import Y`; the index follows Lake's globs and skeleton instead, so it is the
same on every host. The README states the rule where it describes source-aware
`--lean-root` inspection, since it applies to every command that reads the
sources, not only check.
The _has_lean_suffix helper wrapped a single comparison that skeleton and the servers already write inline as suffix != ".lean". Each of the six sites in lean.py now writes the exact comparison directly, and one comment at the capture filter says why the suffix is not case folded. The README sentence covered an edge case that main's README never described, and it was a second place stating the rule. The open docs PR that lists what Lean indexing reads is where the rule belongs, so this branch no longer touches the README and no longer conflicts with the render branch's sentences in that paragraph. The four parametrized cases become one test that puts a regular file, an unreadable file, a symbolic link and a named pipe with case-variant suffixes next to Basic.lean. Descriptor capture is POSIX only, so the symlink and mkfifo skips could not trigger, and as root the unreadable file is simply read, which the exact suffix still ignores. Each entry kind alone fails at main, and the unreadable one still kills the mutant that keeps case folding only in the capture filter.
Since #165, render passes a publication.json marker to Lean indexing: a folder holding a complete publication manifest is skipped, and an unreadable publication.json below the root stops render's indexing like an unreadable manifest.json does. The stop list predated #165 and named neither, so a render user with an unreadable site manifest had no documented cause or remedy. Name both, and state the letter-case rule once at the end instead of per entry, so the exact-suffix change in #232 narrows one clause. The sentence promising root-relative error paths is dropped; it is not part of what stops indexing, and #237 changes which path errors name.
The stop-list paragraph said the `.lean` suffix matches in any letter case. That holds on main, but #232 makes the suffix match exactly, so whichever of the two landed second would have left the README wrong. Drop the suffix from the sentence; the file and folder names it lists still match in any letter case except `build`, on main and with #232.
Review at 060d3ccVerdict: Merge-ready. This PR replaces the six Optional
Landing
Decision for the maintainer
This was a static review: no tests were run locally. CI at this head: all 9 checks pass. Posted by PR swarm: PR Swarm Lead |
The closing sentence of the Lean stop list said file and folder names match in any letter case except build. Read next to the .lean entries the paragraph lists, it claimed A.LEAN is indexed. Since #232 the walk compares the .lean suffix exactly, so the sentence misled. Name the names that fold (the skipped folder names, manifest.json, publication.json and .git), keep build as the lowercase-only exception, and state that the .lean suffix must match exactly.
#232 made the .lean suffix exact. The four conflicting lean.py hunks keep this branch's lines (no in_ignored_root, ignored_roots or manifest.json clause, since selected mode already leaves marker-hidden and excluded folders out) with the exact suffix, relative.suffix == ".lean". The index digest loop, which merged cleanly, gets the same exact comparison, so no casefolded .lean suffix check remains.
…ock-link-check Conflict in autoform_cli/lean.py with facebookresearch#232: keep main's exact .lean suffix comparison and this branch's removal of tolerated_links.
Summary
autoform_cli/lean.pymatched the.leansuffix after case folding, soProj/Y.LEANandProj/W.Leanwere captured and indexed. Lake's module globs (extension == some "lean"),skeleton.module_of/path_ofandservers/__init__.pyall use the exact suffix.check --lean-rootresolved declarations from files Lake and skeleton never see, and a symlink, special or unreadable file with such a name stopped indexing ("unsafe Lean source Proj/W.Lean: symbolic links are not supported").relative.suffix.casefold() == ".lean"checks becomerelative.suffix == ".lean", with one comment at the capture filter. No new helper, no README change.import Proj.Ycan openY.LEAN, but such a project builds only there and Lake's globs never list it. One rule on every host, matching Lake and skeleton.Behavior changes
*.LEANor*.Lean(any non-exact casing) is not captured or indexed, does not stop indexing, and does not change the source digest or generation revision.lean:name defined only in such a file is reported as not found, as skeleton and Lake already treat it.*.leanare still refused;.#*.leaneditor lock links are still skipped.Tests
tests/test_lean_sources.py::test_case_variants_of_the_lean_suffix_are_ignoredputsY.LEAN(file),L.Lean(symlink),P.LEAN(named pipe) andU.Lean(mode 0) next toProject/Basic.leanand asserts the index, line counts,revisionandgeneration_revisionequal those ofBasic.leanalone.variantY, the link and pipe stop indexing, the unreadable file gives "permission denied: Project/U.Lean"._lean_snapshot_includesfails viaU.Lean, because capture still opens it. The other five sites only see entries that filter kept; they change so lean.py states one rule.Overlap with open PRs
MAIN_REF=upstream/main pr_conflicts.shon this branch merged with main ae2db51, conflicts it adds:_lean_snapshot_includesand three suffix filters but keepscasefold(). Take Prove Lean capture stability only for Lean inputs, and name what changed #257's lines with the exact suffix.tolerated_linksand keepscasefold(). Use the exact suffix.Validation
tests/test_lean_sources.pyat 060d3cc: 141 passed, 3 skipped, 1 xfailed on Python 3.13, on 3.10.20 and with real Lean on PATH. The skips are case-colliding-name tests on a case-insensitive volume.ruff check autoform_cli servers tests: clean.