Linting
Lūn
GREASE employs a variety of linting tools, which can optionally be coordinated
via Lūn. We do our best to keep lun.toml up to date, but the ground truth of
which linters are run on what files and in what configuration is always supplied
by the CI system. To run them all:
lun run
Lūn can run just the formatters, or run the linters in "fix" mode where
applicable. See the --help output for more information.
We recommend using this as a pre-commit hook:
cat <<'EOF' > .git/hooks/pre-commit
#!/usr/bin/env bash
lun run --check --staged
EOF
chmod +x .git/hooks/pre-commit
Generic scripts
We have a few Python scripts in scripts/lint/ that perform one-off
checks. They generally take some number of paths as arguments, check
.github/workflows/lint.yml to see how they are invoked in CI.
Fourmolu
This repo enforces Fourmolu formatting based on the committed configuration in fourmolu.yaml. Installation and usage directions are available
here. In short:
cabal install fourmolu-0.19.0.0
fourmolu --mode inplace $(git ls-files '*.hs')
One can configure auto-format on save to avoid formatting issues. The repo is already formatted with fourmolu so new formatting changes should be localized to behavioral changes. Further discussion of the rationale for the enforcement of a fourmolu style and commit hygiene is available in this formatting discussion.
hlint
We treat a small number of hlint warnings as errors in CI. To run hlint locally, try:
hlint grease{,-aarch32,-llvm,-ppc,-x86}/src grease-cli/src grease-exe/{main,src,tests}
mdlynx
We run mdlynx on our Markdown files to check for broken links. To run it locally, try:
git ls-files -z --exclude-standard '*.md' | xargs -0 mdlynx
ruff
We lint and format the Python linting scripts and Ghidra plug-in with ruff.
git ls-files -z --exclude-standard '*.py' | xargs -0 ruff format
git ls-files -z --exclude-standard '*.py' | xargs -0 ruff check
spotless
See the Ghidra batch plugin docs.
tagref
We lint cross-references in code with tagref.
tagref
tagref verifies that every reference refers to an existing tag, and that there are no duplicate tags. The following is the syntax of tags and references:
- Tags:
[tag:snake_case_tag_name] - References:
[ref:snake_case_tag_name]
tagref can also verify file and directory references (file: and dir:).
We often tag: the documentation for a feature, and then use ref:erences in
places in the code that have behavior described in the documentation. This helps
us remember to update documentation when we update code, and signals to readers
of the code that higher-level documentation that can provide valuable context is
available elsewhere.
We highly encourage extensive cross-referencing. It helps us keep documentation and code in sync, and reminds us what needs to be updated in other parts of the codebase when making changes.
ttlint
We lint text files with ttlint.
git ls-files -z --exclude-standard '*.cabal' '*.hs' '*.md' '*.py' '*.scala' | xargs -0 ttlint
typos
We run typos on doc/ to spell-check the documentation. To run it locally,
try:
typos doc/