[FEATURE] Opt-in documentation lint (PoC for #1157) - #1295
Conversation
2d1828c to
bcb8e94
Compare
|
Ready for feedback |
633a0bf to
501eb13
Compare
|
This is really good. Thank you! I fully agree it must be opt-in, good you thought of that too. For the TYPO3 core documentation manuals we'll likely enforce this in the I think it might be helpful if we encapsulate this inside either a subtree split sub-package inside this monorepo, but probably even better to outsource this, so we can better iterate on rules - and then require it as a package? On the rules themselves, they sound a very good first approach. Most pressing things are the missing headlines to me, so that's very helpful to have those included already. I think the whole body though should be checked for "forbidden" words, not just headlines. And one would include it inside a baseline entry (or ignore the whole rule) if not needed. It might also be helpful if we could disable rules inside a ReST file with some directive, what do you think? Not trying to pile on too much on this PR here, I do think we could do it iteratively. That's why a "custom package" sounds helpful to me? |
1b7f0b7 to
a12fb52
Compare
…1157) Adds a proof-of-concept documentation linter that hooks into the compiler pipeline as a node transformer. As a first rule it warns when a section heading contains a discouraged phrase (e.g. "Non-Composer mode"). The linter is opt-in (the `lint` theme setting, default off) and emits warnings only, so it never breaks or rejects third-party extension documentation unless a caller explicitly enables it and opts into --fail-on-log. This is deliberate: there is no reliable back-channel to third-party extension authors to tell them their docs started failing a newly added rule. Matching is case-insensitive and word-bounded so a short phrase does not match inside a larger word. The configurable phrase list is trimmed and de-duplicated. Tests: - Unit tests for the opt-in toggle, phrase parsing (trim/empty/dedup), case-insensitivity and word-boundary matching (no false positives). - Integration tests for the enabled (warning emitted) and disabled (no warning, opt-in respected) cases. Refs TYPO3-Documentation#1157 Signed-off-by: Sebastian Mendel <github@sebastianmendel.de>
Builds on the lint PoC with the LintRule seam the reviewers anticipated, now that rules have multiplied. AST heading rules (extend the new AbstractHeadingLintTransformer, which owns the opt-in gate and warning channel): - sentence-case: warns on Title Case headings via a conservative heuristic (ignores the first word, ALL-CAPS acronyms, CamelCase identifiers and a configurable proper-noun allow list; fires only on two or more Title Case words). - missing-anchor: warns when a sub-heading has no explicit `.. _label:` anchor (the document title is exempt). Source-level rule (runs on the raw reStructuredText via a PreParseDocument listener, for a concern the parsed AST cannot see): - skipped heading levels: the parser normalises heading levels, so a skip is only detectable from the authored adornment sequence in the source. Detection is limited to column 0, so adornments inside code/literal blocks are never misread as headings. Pure source-hygiene checks (tabs, trailing whitespace, line length) are deliberately NOT done here: the repo's own .editorconfig already declares them for *.rst, so they belong to editorconfig-checker, not the renderer. The shared truthy-flag parsing lives in Typo3DocsThemeSettings::isEnabled(). All rules remain opt-in (the `lint` setting, default off) and warning-only, so third-party extension documentation is never broken by default. Adds unit tests for every rule and the source-lint listener, plus integration tests exercising the AST and source rules through the real render pipeline. Refs TYPO3-Documentation#1157 Signed-off-by: Sebastian Mendel <github@sebastianmendel.de>
a12fb52 to
3f48ba9
Compare
What #1157 is asking for
#1157 lists documentation-content quality rules. render-guides renders all TYPO3 docs — including third-party extension docs — so these checks apply to extension docs too.
Baked into every rule: opt-in (nothing runs unless the
lintsetting is truthy, default off) and warning severity (advisory; only aborts a render with an explicit--fail-on-log).Open question for maintainers: where should results surface so extension authors actually see them (render report, dashboard, annotation, pipeline notification)? That should precede making any rule fatal by default.
Scope: three kinds of rule, only two belong here
A core outcome of the discussion on #1157 — the candidate rules split into three buckets, and not all belong in the renderer:
.editorconfig+editorconfig-checker+ IDE — NOT the rendererThe repo's own
.editorconfigalready declaresindent_style,trim_trailing_whitespace,insert_final_newlineandmax_line_length = 80for*.rst. So source-hygiene rules in the renderer would just reimplement it against bytes that don't affect output. This PR therefore does not lint whitespace or line length. Recommended follow-up: wireeditorconfig-checkerinto CI (it currently isn't).Rules implemented
AST heading rules (extend
AbstractHeadingLintTransformer):lint_discouraged_phrases.TYPO3,API), CamelCase (ViewHelper) and a proper-noun allow list (lint_heading_allowed_words); fires only on ≥2 Title Case words... _label:(document title exempt).Source-level rule (
PreParseDocumentlistener — for what the AST can't see):<h2>), so a skip is invisible in the AST and must be read from the raw adornment sequence. Detection is limited to column 0, so===/---inside code/literal blocks are never misread as headings.A note on a subtlety verified during review:
missing-anchorworks because the upstreamMoveAnchorTransformer(priority 30000) relocates each.. _label:anchor into its section before this rule (priority 1000) runs — confirmed end-to-end (an anchored heading is not flagged).Settings
Tests
Unit tests for every rule and the source-lint listener (the opt-in gate), incl. false-positive guards (acronyms/CamelCase/allow-list; code-block adornments not misread as headings). Integration tests drive the AST rules and the source rule through the real render pipeline (incl. the negative: an anchored heading is not flagged).
Verified via the project's
make(Docker/PHP 8.2): unit 120, integration 118,make code-styleclean, PHPStan clean, guides.xml validates.Next steps (RFC discussion, not in this PR)
lintswitch).editorconfig-checkerinto CI to cover the source-hygiene bucket.Refs #1157