Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add default pre-commit hooks #401

Merged
merged 10 commits into from
Apr 1, 2024
210 changes: 125 additions & 85 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,9 @@
- Run hooks **as part of development** and **on during CI**


# Getting started
## Getting started

## devenv.sh
### devenv.sh

https://devenv.sh/pre-commit-hooks/

Expand Down Expand Up @@ -67,14 +67,14 @@ nix develop

## Nix

1. (optional) Use binary caches to avoid compilation:
1. **Optionally** use binary caches to avoid compilation:

```bash
```sh
nix-env -iA cachix -f https://cachix.org/api/v1/install
cachix use pre-commit-hooks
```

2. Integrate hooks to be built as part of `default.nix`:
1. Integrate hooks to be built as part of `default.nix`:

```nix
let
Expand Down Expand Up @@ -106,7 +106,7 @@ nix develop

Run `$ nix-build -A pre-commit-check` to perform the checks as a Nix derivation.

3. Integrate hooks to prepare environment as part of `shell.nix`:
1. Integrate hooks to prepare environment as part of `shell.nix`:

```nix
let
Expand All @@ -133,203 +133,241 @@ nix develop

`.envrc`:

```
```conf
use nix
```

# Hooks
## Hooks

## Nix
### Nix

- [alejandra](https://github.com/kamadorueda/alejandra)
- [deadnix](https://github.com/astro/deadnix)
- [nil](https://github.com/oxalica/nil)
- [nixpkgs-fmt](https://github.com/nix-community/nixpkgs-fmt)
- [nixfmt](https://github.com/serokell/nixfmt/)
- [nixpkgs-fmt](https://github.com/nix-community/nixpkgs-fmt)
- [statix](https://github.com/nerdypepper/statix)

## Haskell
### Haskell

- [ormolu](https://github.com/tweag/ormolu)
- [cabal-fmt](https://github.com/phadej/cabal-fmt)
- [fourmolu](https://github.com/parsonsmatt/fourmolu)
- [hindent](https://github.com/chrisdone/hindent)
- [stylish-haskell](https://github.com/jaspervdj/stylish-haskell)
- [hlint](https://github.com/ndmitchell/hlint)
- [cabal-fmt](https://github.com/phadej/cabal-fmt)
- [hpack](https://github.com/sol/hpack)
- [ormolu](https://github.com/tweag/ormolu)
- [stylish-haskell](https://github.com/jaspervdj/stylish-haskell)

# C/C++/C#/ObjC
### C/C++/C#/ObjC

- [clang-format](https://clang.llvm.org/docs/ClangFormat.html)
- [clang-tidy](https://clang.llvm.org/extra/clang-tidy/)

## Clojure
You may restrict which languages should be formatted by `clang-format` using
`clang-format.types_or`. For example to check only C and C++ files:

```nix
clang-format = {
enable = true;
types_or = lib.mkForce [ "c" "c++" ];
};
```

Otherwise, the default internal list is used which includes everything that
clang-format supports.

### Clojure

- [cljfmt](https://github.com/weavejester/cljfmt)
- [zprint](https://github.com/kkinnear/zprint)

## Elm
### Elm

- [elm-format](https://github.com/avh4/elm-format)
- [elm-review](https://github.com/jfmengels/elm-review)
- [elm-test](https://github.com/rtfeldman/node-test-runner)

## Elixir
### Elixir

- [mix-format](https://hexdocs.pm/mix/main/Mix.Tasks.Format.html)
- [mix-test](https://hexdocs.pm/mix/1.13/Mix.Tasks.Test.html)
- [credo](https://github.com/rrrene/credo)
- [dialyzer](https://github.com/jeremyjh/dialyxir)
- [mix-format](https://hexdocs.pm/mix/main/Mix.Tasks.Format.html)
- [mix-test](https://hexdocs.pm/mix/1.13/Mix.Tasks.Test.html)

## OCaml
### OCaml

- [dune-fmt](https://dune.build/)
- [dune-opam-sync](https://dune.build/)
- [opam-lint](https://opam.ocaml.org/)
- [ocp-indent](http://www.typerex.org/ocp-indent.html)
- [opam-lint](https://opam.ocaml.org/)

## Purescript
### Purescript

- [purty](https://gitlab.com/joneshf/purty)

## JavaScript/TypeScript
### JavaScript/TypeScript

- denofmt: Runs `deno fmt`
- denolint: Runs `deno lint`
- [eslint](https://github.com/eslint/eslint)
- [rome](https://github.com/rome/tools)

## Python
### Python

- [autoflake](https://github.com/PyCQA/autoflake)
- [black](https://github.com/psf/black)
- [ruff](https://github.com/charliermarsh/ruff)
- [check-builtin-literals](https://github.com/pre-commit/pre-commit-hooks/blob/main/pre_commit_hooks/check_builtin_literals.py)
- [check-docstring-first](https://github.com/pre-commit/pre-commit-hooks/blob/main/pre_commit_hooks/check_docstring_first.py)
- [check-python](https://github.com/pre-commit/pre-commit-hooks/blob/main/pre_commit_hooks/check_ast.py)
- [fix-encoding-pragma](https://github.com/pre-commit/pre-commit-hooks/blob/main/pre_commit_hooks/fix_encoding_pragma.py)
- [flake8](https://github.com/PyCQA/flake8)
- [isort](https://github.com/PyCQA/isort)
- [mypy](https://github.com/python/mypy)
- [name-tests-test](https://github.com/pre-commit/pre-commit-hooks/blob/main/pre_commit_hooks/tests_should_end_in_test.py)
- [pylint](https://github.com/PyCQA/pylint)
- [pyright](https://github.com/microsoft/pyright)
- [python-debug-statements](https://github.com/pre-commit/pre-commit-hooks/blob/main/pre_commit_hooks/debug_statement_hook.py)
- [poetry](https://python-poetry.org/docs/pre-commit-hooks)
- [pyupgrade](https://github.com/asottile/pyupgrade)
- [pylint](https://github.com/PyCQA/pylint)
- [flake8](https://github.com/PyCQA/flake8)
- [ruff](https://github.com/charliermarsh/ruff)
- [sort-requirements-txt](https://github.com/pre-commit/pre-commit-hooks/blob/main/pre_commit_hooks/requirements_txt_fixer.py)

## PHP
### PHP

- [php-cs-fixer](https://github.com/PHP-CS-Fixer/PHP-CS-Fixer)
- [phpcbf](https://github.com/squizlabs/PHP_CodeSniffer)
- [php-cs-fixer](https://github.com/PHP-CS-Fixer/PHP-CS-Fixer)
- [phpcs](https://github.com/squizlabs/PHP_CodeSniffer)
- [phpstan](https://github.com/phpstan/phpstan)
- [psalm](https://github.com/vimeo/psalm)

## Rust
### Rust

- [rustfmt](https://github.com/rust-lang/rustfmt)
- [clippy](https://github.com/rust-lang/rust-clippy)
- cargo-check: Runs `cargo check`
- [clippy](https://github.com/rust-lang/rust-clippy)
- [rustfmt](https://github.com/rust-lang/rustfmt)

## Golang
### Golang

- gofmt: Runs `go fmt`
- gotest: Runs `go test`
- [golangci-lint](https://golangci-lint.run/)
- gotest: Runs `go test`
- [govet](https://pkg.go.dev/cmd/vet)
- [revive](https://github.com/mgechev/revive)
- [staticcheck](https://github.com/dominikh/go-tools)

## Julia
### Julia

- [JuiaFormatter.jl](https://github.com/domluna/JuliaFormatter.jl)

## Shell
### Shell

- [bats](https://github.com/bats-core/bats-core)
- [beautysh](https://github.com/lovesegfault/beautysh)
- [shellcheck](https://github.com/koalaman/shellcheck)
- [shfmt](https://github.com/mvdan/sh)
- [beautysh](https://github.com/lovesegfault/beautysh)
- [bats](https://github.com/bats-core/bats-core)

## LaTeX
### LaTeX

- [chktex](https://www.nongnu.org/chktex/)
- [latexindent](https://github.com/cmhughes/latexindent.pl)

## Lua
### Lua

- [luacheck](https://github.com/mpeterv/luacheck)
- [stylua](https://github.com/JohnnyMorganz/StyLua)
- [lua-ls](https://github.com/LuaLS/lua-language-server)
- [stylua](https://github.com/JohnnyMorganz/StyLua)

## HTML
### HTML

- [html-tidy](https://github.com/htacg/tidy-html5)

## Markdown
### Markdown

- [markdownlint](https://github.com/DavidAnson/markdownlint)
- [mdl](https://github.com/markdownlint/markdownlint/)
- [mdsh](https://zimbatm.github.io/mdsh/)

## Terraform
### Terraform

- `terraform-format`: built-in formatter
- [tflint](https://github.com/terraform-linters/tflint)

## YAML
### YAML

- [check-yaml](https://github.com/pre-commit/pre-commit-hooks/blob/main/pre_commit_hooks/check_yaml.py)
- [sort-simple-yaml](https://github.com/pre-commit/pre-commit-hooks/blob/main/pre_commit_hooks/sort_simple_yaml.py)
- [yamllint](https://github.com/adrienverge/yamllint)

## TOML
### TOML

- [check-toml](https://github.com/pre-commit/pre-commit-hooks/blob/main/pre_commit_hooks/check_toml.py)
- [taplo fmt](https://github.com/tamasfe/taplo)

## Typst
### JSON

- [check-json](https://github.com/pre-commit/pre-commit-hooks/blob/main/pre_commit_hooks/check_json.py)
- [pretty-format-json](https://github.com/pre-commit/pre-commit-hooks/blob/main/pre_commit_hooks/pretty_format_json.py)

### Typst

- [typstfmt](https://github.com/astrale-sharp/typstfmt)

## Fortran
### Fortran

- [fprettify](https://github.com/pseewald/fprettify)

## Spell checkers
### Spell checker

- [cspell](https://cspell.org/)
- [hunspell](https://github.com/hunspell/hunspell)
- [typos](https://github.com/crate-ci/typos)
- [cspell](https://cspell.org/)

## Other Formatters
### Link checker

- [prettier](https://prettier.io)
- `dhall format`: built-in formatter
- [hadolint](https://github.com/hadolint/hadolint)
- [editorconfig-checker](https://github.com/editorconfig-checker/editorconfig-checker)
- [actionlint](https://github.com/rhysd/actionlint)
- [tagref](https://github.com/stepchowfun/tagref)
- [treefmt](https://github.com/numtide/treefmt)
- [topiary](https://github.com/tweag/topiary)
- [checkmake](https://github.com/mrtazz/checkmake)
- [lychee](https://github.com/lycheeverse/lychee)
- [mkdocs-linkcheck](https://github.com/byrnereese/linkchecker-mkdocs)
- [headache](https://github.com/frama-c/headache)
- [crystal](https://crystal-lang.org/reference/man/crystal#crystal-tool-format)
- [cmake-format](https://cmake-format.readthedocs.io/en/latest/)

You may restrict which languages should be formatted by `clang-format` using
`clang-format.types_or`. For example to check only C and C++ files:

```nix
clang-format = {
enable = true;
types_or = lib.mkForce [ "c" "c++" ];
};
```

Otherwise, the default internal list is used which includes everything that
clang-format supports.

## Git
### Git

- [annex](https://git-annex.branchable.com/)
- [check-merge-conflicts](https://github.com/pre-commit/pre-commit-hooks/blob/main/pre_commit_hooks/check_merge_conflict.py)
- [commitizen](https://github.com/commitizen-tools/commitizen)
- [gptcommit](https://github.com/zurawiki/gptcommit)
- [convco](https://github.com/convco/convco)
- [annex](https://git-annex.branchable.com/)
- [forbid-new-submodules](https://github.com/pre-commit/pre-commit-hooks/blob/main/pre_commit_hooks/forbid_new_submodules.py)
- [gptcommit](https://github.com/zurawiki/gptcommit)
- [no-commit-to-branch](https://github.com/pre-commit/pre-commit-hooks/blob/main/pre_commit_hooks/no_commit_to_branch.py)

### Various other hooks

- [actionlint](https://github.com/rhysd/actionlint)
- [check-added-large-files](https://github.com/pre-commit/pre-commit-hooks/blob/main/pre_commit_hooks/check_added_large_files.py)
- [check-case-conflicts](https://github.com/pre-commit/pre-commit-hooks/blob/main/pre_commit_hooks/check_case_conflict.py)
- [check-executables-have-shebangs](https://github.com/pre-commit/pre-commit-hooks/blob/main/pre_commit_hooks/check_executables_have_shebangs.py)
- [checkmake](https://github.com/mrtazz/checkmake)
- [check-shebang-scripts-are-executable](https://github.com/pre-commit/pre-commit-hooks/blob/main/pre_commit_hooks/check_shebang_scripts_are_executable.py)
- [check-symlinks](https://github.com/pre-commit/pre-commit-hooks/blob/main/pre_commit_hooks/check_symlinks.py)
- [check-vcs-permalinks](https://github.com/pre-commit/pre-commit-hooks/blob/main/pre_commit_hooks/check_vcs_permalinks.py)
- [check-xml](https://github.com/pre-commit/pre-commit-hooks/blob/main/pre_commit_hooks/check_xml.py)
- [cmake-format](https://cmake-format.readthedocs.io/en/latest/)
- [crystal](https://crystal-lang.org/reference/man/crystal#crystal-tool-format)
- [detect-aws-credentials](https://github.com/pre-commit/pre-commit-hooks/blob/main/pre_commit_hooks/detect_aws_credentials.py)
- [detect-private-keys](https://github.com/pre-commit/pre-commit-hooks/blob/main/pre_commit_hooks/detect_private_key.py)
- `dhall format`: built-in formatter
- [editorconfig-checker](https://github.com/editorconfig-checker/editorconfig-checker)
- [end-of-file-fixer](https://github.com/pre-commit/pre-commit-hooks/blob/main/pre_commit_hooks/end_of_file_fixer.py)
- [fix-byte-order-marker](https://github.com/pre-commit/pre-commit-hooks/blob/main/pre_commit_hooks/fix_byte_order_marker.py)
- [hadolint](https://github.com/hadolint/hadolint)
- [headache](https://github.com/frama-c/headache)
- [mixed-line-endings](https://github.com/pre-commit/pre-commit-hooks/blob/main/pre_commit_hooks/mixed_line_ending.py)
- [mkdocs-linkcheck](https://github.com/byrnereese/linkchecker-mkdocs)
- [prettier](https://prettier.io)
- [sort-file-contents](https://github.com/pre-commit/pre-commit-hooks/blob/main/pre_commit_hooks/file_contents_sorter.py)
- [tagref](https://github.com/stepchowfun/tagref)
- [topiary](https://github.com/tweag/topiary)
- [treefmt](https://github.com/numtide/treefmt)
- [trim-trailing-whitespace](https://github.com/pre-commit/pre-commit-hooks/blob/main/pre_commit_hooks/trailing_whitespace_fixer.py)

## Custom hooks
### Custom hooks

Sometimes it is useful to add a project specific command as an extra check that
is not part of the pre-defined set of hooks provided by this project.
Expand Down Expand Up @@ -384,7 +422,7 @@ Custom hooks are defined with the same schema as [pre-defined
hooks](modules/pre-commit.nix).


# Contributing hooks
## Contributing hooks

Everyone is encouraged to add new hooks.

Expand All @@ -394,9 +432,11 @@ Have a look at the [existing hooks](modules/hooks.nix) and the [options](modules
There's no guarantee the hook will be accepted, but the general guidelines are:

- Nix closure of the tool should be small e.g. `< 50MB`. A problematic example:

```sh
$ du -sh $(nix-build -A go)
463M /nix/store/v4ys4lrjngf62lvvrdbs7r9kbxh9nqaa-go-1.18.6
```
$ du -sh $(nix-build -A go)
463M /nix/store/v4ys4lrjngf62lvvrdbs7r9kbxh9nqaa-go-1.18.6
```

- The tool must not be very specific (e.g. language tooling is OK, but project specific tooling is not)
- The tool needs to live in a separate repository (even if a simple bash script, unless it's a oneliner)
Loading
Loading