docs/developer-guides/docs/03-code-internals/02-lint-and-format.md
Discourse uses lefthook for git hooks, and bin/lint as the main CLI entry point for running the same checks manually.
If you are working in a local clone, install the hooks once:
pnpm install
pnpm lefthook install
After that, staged files will be checked automatically on git commit.
bin/lintUse bin/lint when you want to run the repo's configured linters yourself instead of waiting for the pre-commit hook.
Common examples:
bin/lint
bin/lint path/to/file.rb path/to/file.gjs
bin/lint --recent
bin/lint --staged
bin/lint --unstaged
bin/lint --wip
bin/lint --fix path/to/file.rb
bin/lint --fix --recent
bin/lint --fix
bin/lint: lint all supported files in the repositorybin/lint path/to/file ...: lint only the given filesbin/lint --recent: lint files changed in the last 50 commits, plus untracked filesbin/lint --staged: lint only staged filesbin/lint --unstaged: lint only unstaged filesbin/lint --wip: lint staged files, unstaged files, and files changed since mainbin/lint --fix ...: run the auto-fixers for the selected filesbin/lint --fix: run all available auto-fixers across the repositorybin/lint --verbose: print the underlying lefthook commandsWhen you pass explicit files, bin/lint filters them to supported lintable file types before invoking lefthook.
:information_source: Markdown documentation files are not currently part of
bin/lint, so runningbin/lint path/to/doc.mdwill report that there are no matching files to lint.
The exact configuration lives in lefthook.yml. At the time of writing, bin/lint covers:
**/*.{rb,rake,thor}bin/**/*GemfileChecks:
rubocopsyntax_tree (stree check)app/assets/stylesheets/**/*.{css,scss}frontend/**/*.{js,gjs,scss,css,cjs,mjs}Checks:
prettier/pprettierfrontend/**/*.{js,gjs}Checks:
eslintfrontend/**/*.gjs.gjs filesChecks:
ember-template-lintapp/assets/stylesheets/**/*.scssChecks:
stylelint**/*.{yaml,yml} except config/database.yml**/{client,server}.en.ymlChecks:
yaml-lintscript/i18n_lint.rbWhen you run bin/lint with no file arguments, the full-repo lint also runs:
pnpm lint:typesThis is the Glint/TypeScript-style check for Discourse's JavaScript type information.
:information_source:
bin/lint path/to/fileand the pre-commit hook do not run the full type check. Use plainbin/lintwhen you want the complete repo-wide lint pass.
bin/lint --fix can automatically fix a lot of issues, but not all of them.
Auto-fix is configured for:
prettier --writeeslint --fixember-template-lint --fixstylelint --fixrubocop -Asyntax_tree (stree write)In practice, that means --fix can reformat and rewrite:
These checks are not auto-fixed by bin/lint --fix:
client.en.yml / server.en.ymlThe pre-commit hook uses the same lefthook configuration as bin/lint, but it runs only against staged files.
That means:
bin/lint --staged is the closest manual equivalent to the pre-commit hookbin/lint --fix --staged is a good way to repair exactly what you are about to commitFor day-to-day development, these are the most useful commands:
# Before committing a couple of changed files
bin/lint --fix path/to/file1.rb path/to/file2.gjs
# Check exactly what the pre-commit hook will check
bin/lint --staged
# Clean up all current in-progress work
bin/lint --fix --wip
# Run the full repo lint suite, including type checks
bin/lint