From 7bb2c65441048eb8f5610edc2755e619562a25d4 Mon Sep 17 00:00:00 2001 From: Matthias Thym Date: Thu, 22 Feb 2024 12:46:44 +0100 Subject: [PATCH] Add pre-commit default hooks --- modules/hooks.nix | 268 +++++++++++++++++++++++++++++++++++++++++++++- nix/tools.nix | 2 +- 2 files changed, 267 insertions(+), 3 deletions(-) diff --git a/modules/hooks.nix b/modules/hooks.nix index 66e37cbf..1b2ba4b5 100644 --- a/modules/hooks.nix +++ b/modules/hooks.nix @@ -633,6 +633,23 @@ in default = null; }; }; + no-commit-to-branch = + { + branch = + mkOption { + description = lib.mdDoc "Branches to disallow commits to."; + type = types.listOf types.str; + default = [ "main" ]; + example = [ "main" "master" ]; + }; + pattern = + mkOption { + description = lib.mdDoc "RegEx patterns for branch names to disallow commits to."; + type = types.listOf types.str; + default = [ ]; + example = [ "ma.*" ]; + }; + }; ormolu = { defaultExtensions = @@ -1057,6 +1074,21 @@ in example = [ "flake.nix" "_*" ]; }; }; + sort-file-contents = + { + ignore-case = + mkOption { + type = types.bool; + description = lib.mdDoc "Fold lower case to upper case characters."; + default = false; + }; + unique = + mkOption { + type = types.bool; + description = lib.mdDoc "Ensure each line is unique."; + default = false; + }; + }; treefmt = { package = mkOption { @@ -1356,6 +1388,106 @@ in "The version of nixpkgs used by pre-commit-hooks.nix must have `checkmake` in version at least 0.2.2 for it to work on non-Linux systems." "${tools.checkmake}/bin/checkmake"; }; + check-added-large-files = + { + name = "check-added-large-files"; + description = "Prevent very large files to be committed (e.g. binaries)."; + entry = "${tools.pre-commit-hooks}/bin/check-added-large-files"; + stages = [ "commit" "push" "manual" ]; + }; + check-builtin-literals = + { + name = "check-builtin-literals"; + description = "Require literal syntax when initializing empty or zero builtin types in Python."; + entry = "${tools.pre-commit-hooks}/bin/check-builtin-literals"; + types = [ "python" ]; + }; + check-case-conflicts = + { + name = "check-case-conflicts"; + description = "Check for files that would conflict in case-insensitive filesystems."; + entry = "${tools.pre-commit-hooks}/bin/check-case-conflict"; + types = [ "file" ]; + }; + check-docstring-first = + { + name = "check-docstring-above"; + description = "Check that all docstrings appear above the code."; + entry = "${tools.pre-commit-hooks}/bin/check-docstring-first"; + types = [ "python" ]; + }; + check-executables-have-shebangs = + { + name = "check-executables-have-shebangs"; + description = "Ensure that all non-binary executables have shebangs."; + entry = "${tools.pre-commit-hooks}/bin/check-executables-have-shebangs"; + types = [ "text" "executable" ]; + stages = [ "commit" "push" "manual" ]; + }; + check-json = + { + name = "check-json"; + description = "Check syntax of JSON files."; + entry = "${tools.pre-commit-hooks}/bin/check-json"; + types = [ "json" ]; + }; + check-merge-conflicts = + { + name = "check-merge-conflicts"; + description = "Check for files that contain merge conflict strings."; + entry = "${tools.pre-commit-hooks}/bin/check-merge-conflict"; + types = [ "text" ]; + }; + check-python = + { + name = "check-python"; + description = "Check syntax of Python file by parsing Python abstract syntax tree."; + entry = "${tools.pre-commit-hooks}/bin/check-ast"; + types = [ "python" ]; + }; + check-shebang-scripts-are-executable = + { + name = "check-shebang-scripts-are-executable"; + description = "Ensure that all (non-binary) files with a shebang are executable."; + entry = "${tools.pre-commit-hooks}/bin/check-shebang-scripts-are-executable"; + types = [ "text" ]; + stages = [ "commit" "push" "manual" ]; + }; + check-symlinks = + { + name = "check-symlinks"; + description = "Find broken symlinks."; + entry = "${tools.pre-commit-hooks}/bin/check-symlinks"; + types = [ "symlink" ]; + }; + check-toml = + { + name = "check-toml"; + description = "Check syntax of TOML files."; + entry = "${tools.pre-commit-hooks}/bin/check-toml"; + types = [ "toml" ]; + }; + check-vcs-permalinks = + { + name = "check-vcs-permalinks"; + description = "Ensure that links to VCS websites are permalinks."; + entry = "${tools.pre-commit-hooks}/bin/check-vcs-permalinks"; + types = [ "text" ]; + }; + check-xml = + { + name = "check-xml"; + description = "Check syntax of TOML files."; + entry = "${tools.pre-commit-hooks}/bin/check-xml"; + types = [ "xml" ]; + }; + check-yaml = + { + name = "check-yaml"; + description = "Check syntax of YAML files."; + entry = "${tools.pre-commit-hooks}/bin/check-yaml"; + types = [ "yaml" ]; + }; chktex = { name = "chktex"; @@ -1530,6 +1662,20 @@ in in "${tools.deno}/bin/deno lint ${cmdArgs}"; }; + detect-aws-credentials = + { + name = "detect-aws-credentials"; + description = "Detect AWS credentials from the AWS cli credentials file."; + entry = "${tools.pre-commit-hooks}/bin/detect-aws-credentials --allow-missing-credentials"; + types = [ "text" ]; + }; + detect-private-keys = + { + name = "detect-private-keys"; + description = "Detect the presence of private keys."; + entry = "${tools.pre-commit-hooks}/bin/detect-private-key"; + types = [ "text" ]; + }; dhall-format = { name = "dhall-format"; description = "Dhall code formatter."; @@ -1593,6 +1739,13 @@ in entry = "${tools.editorconfig-checker}/bin/editorconfig-checker"; types = [ "file" ]; }; + end-of-file-fixer = + { + name = "end-of-file-fixer"; + description = "Ensures that a file is either empty, or ends with a single newline."; + entry = "${tools.pre-commit-hooks}/bin/end-of-file-fixer"; + types = [ "text" ]; + }; elm-format = { name = "elm-format"; @@ -1624,6 +1777,13 @@ in entry = "${settings.eslint.binPath} --fix"; files = "${settings.eslint.extensions}"; }; + fix-byte-order-marker = + { + name = "fix-byte-order-marker"; + description = "Remove UTF-8 byte order marker."; + entry = "${tools.pre-commit-hooks}/bin/fix-byte-order-marker"; + types = [ "text" ]; + }; flake8 = let extendIgnoreStr = @@ -1660,14 +1820,28 @@ in "${settings.flynt.binPath} ${cmdArgs}"; types = [ "python" ]; }; + forbid-new-submodules = + { + name = "forbid-new-submodules"; + description = "Prevent addition of new Git submodules."; + entry = "${tools.pre-commit-hooks}/bin/forbid-new-submodules"; + types = [ "directory" ]; + }; + forbid-submodules = + { + name = "forbid-submodules"; + description = "Forbid any Git submodule in a repository."; + entry = "${tools.pre-commit-hooks}/bin/forbid-submodules"; + types = [ "directory" ]; + }; fourmolu = { name = "fourmolu"; description = "Haskell code prettifier."; entry = "${tools.fourmolu}/bin/fourmolu --mode inplace ${ - lib.escapeShellArgs (lib.concatMap (ext: [ "--ghc-opt" "-X${ext}" ]) settings.ormolu.defaultExtensions) - }"; +lib.escapeShellArgs (lib.concatMap (ext: [ "--ghc-opt" "-X${ext}" ]) settings.ormolu.defaultExtensions) +}"; files = "\\.l?hs(-boot)?$"; }; fprettify = { @@ -2010,6 +2184,12 @@ in entry = toString script; files = "\\.md$"; }; + mixed-line-endings = { + name = "mixed-line-endings"; + description = "Resolve mixed line endings."; + entry = "${tools.pre-commit-hooks}/bin/mixed-line-endings --fix"; + types = [ "text" ]; + }; mix-format = { name = "mix-format"; description = "Runs the built-in Elixir syntax formatter"; @@ -2047,6 +2227,13 @@ in entry = settings.mypy.binPath; files = "\\.py$"; }; + name-tests-test = + { + name = "mypy"; + description = "Verify that Python test files are named correctly."; + entry = "${tools.pre-commit-hooks}/bin/name-tests-test"; + files = "(^|/)tests/\.+\\.py$"; + }; nil = { name = "nil"; @@ -2087,6 +2274,23 @@ in entry = "${tools.nixpkgs-fmt}/bin/nixpkgs-fmt"; files = "\\.nix$"; }; + no-commit-to-branch = + { + name = "no-commit-to-branch"; + description = "Disallow committing to certain branch/branches."; + pass_filenames = false; + always_run = true; + entry = + let + cmdArgs = + mkCmdArgs + (with settings.no-commit-to-branch; [ + [ (branch != [ ]) "--branch ${lib.strings.concatStringsSep " --branch " branch}" ] + [ (pattern != [ ]) "--pattern ${lib.strings.concatStringsSep " --pattern " pattern}" ] + ]); + in + "${tools.pre-commit-hooks}/bin/no-commit-to-branch ${cmdArgs}"; + }; ocp-indent = { name = "ocp-indent"; @@ -2147,6 +2351,13 @@ in "${binPath} analyse"; types = [ "php" ]; }; + pretty-format-json = + { + name = "pretty-format-json"; + description = "Formats JSON files."; + entry = "${tools.pre-commit-hooks}/bin/pretty-format-json"; + types = [ "json" ]; + }; pre-commit-hook-ensure-sops = { name = "pre-commit-hook-ensure-sops"; entry = @@ -2251,6 +2462,13 @@ in entry = settings.pyright.binPath; files = "\\.py$"; }; + python-debug-statements = + { + name = "python-debug-statements"; + description = "Check for debugger imports and py37+ `breakpoint()` calls in python source."; + entry = "${tools.pre-commit-hooks}/bin/debug-statement-hook"; + types = [ "python" ]; + }; pyupgrade = { name = "pyupgrade"; @@ -2342,6 +2560,44 @@ in types = [ "shell" ]; entry = "${tools.shfmt}/bin/shfmt -w -s -l"; }; + single-quoted-strings = + { + name = "single-quoted-strings"; + description = "Replace double quoted strings with single quoted strings."; + entry = "${tools.pre-commit-hooks}/bin/double-quote-string-fixer"; + types = [ "python" ]; + }; + sort-file-contents = + { + name = "sort-file-contents"; + description = "Sort the lines in specified files (defaults to alphabetical)."; + types = [ "text" ]; + entry = + let + cmdArgs = + mkCmdArgs + (with settings.sort-file-contents; + [ + [ ignore-case "--ignore-case" ] + [ unique "--unique" ] + ]); + in + "${tools.pre-commit-hooks}/bin/file-contents-sorter ${cmdArgs}"; + }; + sort-requirements-txt = + { + name = "sort-requirements.txt"; + description = "Sort requirements in requirements.txt and constraints.txt files."; + entry = "${tools.pre-commit-hooks}/bin/requirements-txt-fixer"; + files = "\\.*(requirements|constraints)\\.*\\.txt$"; + }; + sort-simple-yaml = + { + name = "sort-simple-yaml"; + description = "Sort simple YAML files which consist only of top-level keys, preserving comments and blocks."; + entry = "${tools.pre-commit-hooks}/bin/sort-simple-yaml"; + files = "(\\.yaml$)|(\\.yml$)"; + }; staticcheck = { name = "staticcheck"; @@ -2447,6 +2703,14 @@ in ); files = "(\\.json$)|(\\.toml$)|(\\.mli?$)"; }; + trim-trailing-whitespace = + { + name = "trim-trailing-whitespace"; + description = "Trim trailing whitespace."; + types = [ "text" ]; + stages = [ "commit" "push" "manual" ]; + entry = "${tools.pre-commit-hooks}/bin/trailing-whitespace-fixer"; + }; treefmt = { name = "treefmt"; diff --git a/nix/tools.nix b/nix/tools.nix index 358b6715..be4a2285 100644 --- a/nix/tools.nix +++ b/nix/tools.nix @@ -152,7 +152,7 @@ in inherit (luaPackages) luacheck; inherit (nodePackages) eslint markdownlint-cli prettier pyright cspell; inherit (ocamlPackages) ocp-indent; - inherit (python3Packages) autoflake black flake8 flynt isort mkdocs-linkcheck mypy pylint pyupgrade; + inherit (python3Packages) autoflake black flake8 flynt isort mkdocs-linkcheck mypy pre-commit-hooks pylint pyupgrade; inherit (php82Packages) php-cs-fixer phpcbf phpcs psalm; # FIXME: workaround build failure phpstan = php82Packages.phpstan.overrideAttrs (old: {