From e43d55d462675b66c1bc5286bc544264c0590839 Mon Sep 17 00:00:00 2001 From: Phil de Joux Date: Wed, 20 May 2026 14:16:19 -0400 Subject: [PATCH] Add a section on linting to CONTRIBUTING - Don't repeat "in the CI process" - Configuration in one place - Move .../ explanation - Use footnote for .../ explanation - Show how to install apply-refact - Refactor gotchas - Grammar, not with --- CONTRIBUTING.md | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 6ce38f23080..f07aa80f273 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -249,6 +249,36 @@ formatting: [issue-9230]: https://github.com/haskell/cabal/issues/9230 +## Code Linting + +We check for HLint warnings and suggestions in CI. Where possible, configuration +is all kept in one place, in [.hlint.yaml](/.hlint.yaml). + +The `make lint` recipe is `hlint -j .` but if checking a single file, it is +quicker to `hlint <.../filename.hs>`. It is possible to have HLint do the +refactoring itself with: + +[^rel-path-file]: Where `.../` is the elided path to the file. + +``` +$ hlint --refactor --refactor-options=--inplace <.../filename.hs> +``` + +> [!NOTE] +> We use `hlint-3.10` for linting. As of writing, this compiles with `ghc-9.12` +> but not with `ghc-9.14`. +> +> ``` +> $ cabal install hlint-3.10 --overwrite-policy=always --ignore-project --with-compiler=ghc-9.12 +> $ cabal install apply-refact --overwrite-policy=always --ignore-project +> ``` +> +> Use of `hlint --refactor` has some gotchas. It obliterates `-XCPP` +> conditionals, duplicates comments and sometimes does nothing. Its refactoring is +> not recursive. Any linting failures it introduces will not be fixed until it +> is run again. + + ## Whitespace Conventions We use automated whitespace convention checking. Violations can be fixed by