From 15330bec112feb157a25091a5a88b788c477dad0 Mon Sep 17 00:00:00 2001 From: Sander Date: Sat, 10 Feb 2024 20:07:32 +0000 Subject: [PATCH 01/26] Implement new module design Based on #196. --- modules/hook.nix | 156 +++ modules/hooks.nix | 2450 ++++++++++++++++++++++------------------ modules/pre-commit.nix | 293 +++-- nix/run.nix | 3 +- 4 files changed, 1628 insertions(+), 1274 deletions(-) create mode 100644 modules/hook.nix diff --git a/modules/hook.nix b/modules/hook.nix new file mode 100644 index 00000000..9f78264a --- /dev/null +++ b/modules/hook.nix @@ -0,0 +1,156 @@ +{ config, name, lib, ... }: + + +let + inherit (lib) mkOption types; + cfg = config.options; +in +{ + options = { + enable = mkOption { + type = types.bool; + description = lib.mdDoc "Whether to enable this pre-commit hook."; + default = false; + }; + + raw = mkOption { + type = types.attrsOf types.unspecified; + description = lib.mdDoc + '' + Raw fields of a pre-commit hook. This is mostly for internal use but + exposed in case you need to work around something. + + Default: taken from the other hook options. + ''; + }; + + name = mkOption { + type = types.str; + defaultText = lib.literalMD "internal name, same as `id`"; + default = name; + description = lib.mdDoc + '' + The name of the hook - shown during hook execution. + ''; + }; + + description = mkOption { + type = types.str; + description = lib.mdDoc + '' + Description of the hook. used for metadata purposes only. + ''; + default = ""; + }; + + package = mkOption { + type = types.package; + description = lib.mdDoc + '' + The package that provides the hook. + ''; + }; + + entry = mkOption { + type = types.str; + description = lib.mdDoc + '' + The entry point - the executable to run. {option}`entry` can also contain arguments that will not be overridden, such as `entry = "autopep8 -i";`. + ''; + }; + + language = mkOption { + type = types.str; + description = lib.mdDoc + '' + The language of the hook - tells pre-commit how to install the hook. + ''; + default = "system"; + }; + + files = mkOption { + type = types.str; + description = lib.mdDoc + '' + The pattern of files to run on. + ''; + default = ""; + }; + + types = mkOption { + type = types.listOf types.str; + description = lib.mdDoc + '' + List of file types to run on. See [Filtering files with types](https://pre-commit.com/#plugins). + ''; + default = [ "file" ]; + }; + + types_or = mkOption { + type = types.listOf types.str; + description = lib.mdDoc + '' + List of file types to run on, where only a single type needs to match. + ''; + default = [ ]; + }; + + excludes = mkOption { + type = types.listOf types.str; + description = lib.mdDoc + '' + Exclude files that were matched by these patterns. + ''; + default = [ ]; + }; + + pass_filenames = mkOption { + type = types.bool; + description = lib.mdDoc '' + Whether to pass filenames as arguments to the entry point. + ''; + default = true; + }; + + fail_fast = mkOption { + type = types.bool; + description = lib.mdDoc '' + if true pre-commit will stop running hooks if this hook fails. + ''; + default = false; + }; + + require_serial = mkOption { + type = types.bool; + description = lib.mdDoc '' + if true this hook will execute using a single process instead of in parallel. + ''; + default = false; + }; + + stages = mkOption { + type = types.listOf types.str; + description = lib.mdDoc '' + Confines the hook to run at a particular stage. + ''; + default = cfg.default_stages; + defaultText = (lib.literalExpression or lib.literalExample) "default_stages"; + }; + + verbose = mkOption { + type = types.bool; + default = false; + description = lib.mdDoc '' + forces the output of the hook to be printed even when the hook passes. + ''; + }; + + always_run = mkOption { + type = types.bool; + default = false; + description = lib.mdDoc '' + if true this hook will run even if there are no matching files. + ''; + }; + }; +} diff --git a/modules/hooks.nix b/modules/hooks.nix index 66e37cbf..48973b35 100644 --- a/modules/hooks.nix +++ b/modules/hooks.nix @@ -1,8 +1,12 @@ { config, lib, pkgs, ... }: let - inherit (config) tools settings; + inherit (config) tools; + # TODO: rename all uses of settings. with hooks. + settings = config.hooks; inherit (lib) mkOption types; + hookModule = ./hook.nix; + cargoManifestPathArg = lib.optionalString (settings.rust.cargoManifestPath != null) @@ -20,1227 +24,1423 @@ let in { # PLEASE keep this sorted alphabetically. - options.settings = + options.hooks = { - alejandra = - { - check = - mkOption { - type = types.bool; - description = lib.mdDoc "Check if the input is already formatted and disable writing in-place the modified content"; - default = false; - example = true; - }; - exclude = - mkOption { - type = types.listOf types.str; - description = lib.mdDoc "Files or directories to exclude from formatting."; - default = [ ]; - example = [ "flake.nix" "./templates" ]; - }; - package = - mkOption { - type = types.package; - description = lib.mdDoc "The `alejandra` package to use."; - default = "${tools.alejandra}"; - defaultText = "\${pkgs.alejandra}"; - example = "\${pkgs.alejandra}"; - }; - threads = - mkOption { - type = types.nullOr types.int; - description = lib.mdDoc "Number of formatting threads to spawn."; - default = null; - example = 8; - }; - verbosity = - mkOption { - type = types.enum [ "normal" "quiet" "silent" ]; - description = lib.mdDoc "Whether informational messages or all messages should be hidden or not."; - default = "normal"; - example = "quiet"; - }; - }; - ansible-lint = - { - configPath = mkOption { - type = types.str; - description = lib.mdDoc "Path to the YAML configuration file."; - # an empty string translates to use default configuration of the - # underlying ansible-lint binary - default = ""; - }; - subdir = mkOption { - type = types.str; - description = lib.mdDoc "Path to the Ansible subdirectory."; - default = ""; + alejandra = mkOption { + type = types.submodule { + imports = [ hookModule ]; + options = { + check = + mkOption { + type = types.bool; + description = lib.mdDoc "Check if the input is already formatted and disable writing in-place the modified content"; + default = false; + example = true; + }; + exclude = + mkOption { + type = types.listOf types.str; + description = lib.mdDoc "Files or directories to exclude from formatting."; + default = [ ]; + example = [ "flake.nix" "./templates" ]; + }; + package = + mkOption { + type = types.package; + description = lib.mdDoc "The `alejandra` package to use."; + default = "${tools.alejandra}"; + defaultText = "\${pkgs.alejandra}"; + example = "\${pkgs.alejandra}"; + }; + threads = + mkOption { + type = types.nullOr types.int; + description = lib.mdDoc "Number of formatting threads to spawn."; + default = null; + example = 8; + }; + verbosity = + mkOption { + type = types.enum [ "normal" "quiet" "silent" ]; + description = lib.mdDoc "Whether informational messages or all messages should be hidden or not."; + default = "normal"; + example = "quiet"; + }; }; }; - autoflake = - { - binPath = - mkOption { + }; + ansible-lint = mkOption { + type = types.submodule { + imports = [ hookModule ]; + options = { + configPath = mkOption { type = types.str; - description = lib.mdDoc "Path to autoflake binary."; - default = "${tools.autoflake}/bin/autoflake"; - defaultText = lib.literalExpression '' - "''${tools.autoflake}/bin/autoflake" - ''; + description = lib.mdDoc "Path to the YAML configuration file."; + # an empty string translates to use default configuration of the + # underlying ansible-lint binary + default = ""; }; - - flags = - mkOption { + subdir = mkOption { type = types.str; - description = lib.mdDoc "Flags passed to autoflake."; - default = "--in-place --expand-star-imports --remove-duplicate-keys --remove-unused-variables"; + description = lib.mdDoc "Path to the Ansible subdirectory."; + default = ""; }; - }; - clippy = - { - denyWarnings = mkOption { - type = types.bool; - description = lib.mdDoc "Fail when warnings are present"; - default = false; - }; - offline = mkOption { - type = types.bool; - description = lib.mdDoc "Run clippy offline"; - default = true; - }; - allFeatures = mkOption { - type = types.bool; - description = lib.mdDoc "Run clippy with --all-features"; - default = false; }; }; - cmake-format = - { - configPath = mkOption { - type = types.str; - description = lib.mdDoc "Path to the configuration file (.json,.python,.yaml)"; - default = ""; - example = ".cmake-format.json"; + }; + autoflake = mkOption { + type = types.submodule { + imports = [ hookModule ]; + options = { + binPath = + mkOption { + type = types.str; + description = lib.mdDoc "Path to autoflake binary."; + default = "${tools.autoflake}/bin/autoflake"; + defaultText = lib.literalExpression '' + "''${tools.autoflake}/bin/autoflake" + ''; + }; + + flags = + mkOption { + type = types.str; + description = lib.mdDoc "Flags passed to autoflake."; + default = "--in-place --expand-star-imports --remove-duplicate-keys --remove-unused-variables"; + }; }; }; - credo = { - strict = - mkOption { - type = types.bool; - description = lib.mdDoc "Whether to auto-promote the changes."; - default = true; - }; }; - deadnix = - { - edit = - mkOption { - type = types.bool; - description = lib.mdDoc "Remove unused code and write to source file."; - default = false; - }; - - exclude = - mkOption { - type = types.listOf types.str; - description = lib.mdDoc "Files to exclude from analysis."; - default = [ ]; - }; - - hidden = - mkOption { - type = types.bool; - description = lib.mdDoc "Recurse into hidden subdirectories and process hidden .*.nix files."; - default = false; - }; - - noLambdaArg = - mkOption { - type = types.bool; - description = lib.mdDoc "Don't check lambda parameter arguments."; - default = false; - }; - - noLambdaPatternNames = - mkOption { + clippy = mkOption { + type = types.submodule { + imports = [ hookModule ]; + options = { + denyWarnings = mkOption { type = types.bool; - description = lib.mdDoc "Don't check lambda pattern names (don't break nixpkgs `callPackage`)."; + description = lib.mdDoc "Fail when warnings are present"; default = false; }; - - noUnderscore = - mkOption { + offline = mkOption { type = types.bool; - description = lib.mdDoc "Don't check any bindings that start with a `_`."; - default = false; + description = lib.mdDoc "Run clippy offline"; + default = true; }; - - quiet = - mkOption { + allFeatures = mkOption { type = types.bool; - description = lib.mdDoc "Don't print a dead code report."; + description = lib.mdDoc "Run clippy with --all-features"; default = false; }; + }; }; - denofmt = - { - write = - mkOption { - type = types.bool; - description = lib.mdDoc "Whether to edit files inplace."; - default = true; - }; - configPath = - mkOption { + }; + cmake-format = mkOption { + type = types.submodule { + imports = [ hookModule ]; + options = { + configPath = mkOption { type = types.str; - description = lib.mdDoc "Path to the configuration JSON file"; - # an empty string translates to use default configuration of the - # underlying deno binary (i.e deno.json or deno.jsonc) + description = lib.mdDoc "Path to the configuration file (.json,.python,.yaml)"; default = ""; + example = ".cmake-format.json"; }; + }; }; - denolint = - { - format = - mkOption { - type = types.enum [ "default" "compact" "json" ]; - description = lib.mdDoc "Output format."; - default = "default"; - }; - - configPath = - mkOption { - type = types.str; - description = lib.mdDoc "Path to the configuration JSON file"; - # an empty string translates to use default configuration of the - # underlying deno binary (i.e deno.json or deno.jsonc) - default = ""; - }; + }; + credo = mkOption { + type = types.submodule { + imports = [ hookModule ]; + options = { + strict = + mkOption { + type = types.bool; + description = lib.mdDoc "Whether to auto-promote the changes."; + default = true; + }; + }; }; - dune-fmt = - { - auto-promote = - mkOption { - type = types.bool; - description = lib.mdDoc "Whether to auto-promote the changes."; - default = true; - }; + }; + deadnix = mkOption { + type = types.submodule { + imports = [ hookModule ]; + options = { + edit = + mkOption { + type = types.bool; + description = lib.mdDoc "Remove unused code and write to source file."; + default = false; + }; - extraRuntimeInputs = - mkOption { - type = types.listOf types.package; - description = lib.mdDoc "Extra runtimeInputs to add to the environment, eg. `ocamlformat`."; - default = [ ]; - }; + exclude = + mkOption { + type = types.listOf types.str; + description = lib.mdDoc "Files to exclude from analysis."; + default = [ ]; + }; + + hidden = + mkOption { + type = types.bool; + description = lib.mdDoc "Recurse into hidden subdirectories and process hidden .*.nix files."; + default = false; + }; + + noLambdaArg = + mkOption { + type = types.bool; + description = lib.mdDoc "Don't check lambda parameter arguments."; + default = false; + }; + + noLambdaPatternNames = + mkOption { + type = types.bool; + description = lib.mdDoc "Don't check lambda pattern names (don't break nixpkgs `callPackage`)."; + default = false; + }; + + noUnderscore = + mkOption { + type = types.bool; + description = lib.mdDoc "Don't check any bindings that start with a `_`."; + default = false; + }; + + quiet = + mkOption { + type = types.bool; + description = lib.mdDoc "Don't print a dead code report."; + default = false; + }; + }; }; - eclint = - { - package = - mkOption { - type = types.package; - description = lib.mdDoc "The `eclint` package to use."; - default = "${tools.eclint}"; - defaultText = lib.literalExpression "\${tools.eclint}"; - example = lib.literalExpression "\${pkgs.eclint}"; - }; - fix = - mkOption { - type = types.bool; - description = lib.mdDoc "Modify files in place rather than showing the errors."; - default = false; - }; - summary = - mkOption { - type = types.bool; - description = lib.mdDoc "Only show number of errors per file."; - default = false; - }; - color = - mkOption { - type = types.enum [ "auto" "always" "never" ]; - description = lib.mdDoc "When to generate colored output."; - default = "auto"; - }; - exclude = - mkOption { - type = types.listOf types.str; - description = lib.mdDoc "Filter to exclude files."; - default = [ ]; - }; - verbosity = - mkOption { - type = types.enum [ 0 1 2 3 4 ]; - description = lib.mdDoc "Log level verbosity"; - default = 0; - }; + }; + denofmt = mkOption { + type = types.submodule { + imports = [ hookModule ]; + options = { + write = + mkOption { + type = types.bool; + description = lib.mdDoc "Whether to edit files inplace."; + default = true; + }; + configPath = + mkOption { + type = types.str; + description = lib.mdDoc "Path to the configuration JSON file"; + # an empty string translates to use default configuration of the + # underlying deno binary (i.e deno.json or deno.jsonc) + default = ""; + }; + }; }; - eslint = - { - binPath = - mkOption { - type = types.path; - description = lib.mdDoc - "`eslint` binary path. E.g. if you want to use the `eslint` in `node_modules`, use `./node_modules/.bin/eslint`."; - default = "${tools.eslint}/bin/eslint"; - defaultText = lib.literalExpression "\${tools.eslint}/bin/eslint"; - }; + }; + denolint = mkOption { + type = types.submodule { + imports = [ hookModule ]; + options = { + format = + mkOption { + type = types.enum [ "default" "compact" "json" ]; + description = lib.mdDoc "Output format."; + default = "default"; + }; - extensions = - mkOption { - type = types.str; - description = lib.mdDoc - "The pattern of files to run on, see [https://pre-commit.com/#hooks-files](https://pre-commit.com/#hooks-files)."; - default = "\\.js$"; - }; - }; - flake8 = - { - binPath = - mkOption { - type = types.str; - description = lib.mdDoc "flake8 binary path. Should be used to specify flake8 binary from your Nix-managed Python environment."; - default = "${tools.flake8}/bin/flake8"; - defaultText = lib.literalExpression '' - "''${tools.flake8}/bin/flake8" - ''; - }; - extendIgnore = - mkOption { - type = types.listOf types.str; - description = lib.mdDoc "List of additional ignore codes"; - default = [ ]; - example = [ "E501" ]; - }; - format = - mkOption { - type = types.str; - description = lib.mdDoc "Output format."; - default = "default"; - }; + configPath = + mkOption { + type = types.str; + description = lib.mdDoc "Path to the configuration JSON file"; + # an empty string translates to use default configuration of the + # underlying deno binary (i.e deno.json or deno.jsonc) + default = ""; + }; + }; }; - flynt = - { - aggressive = - mkOption { - type = types.bool; - description = lib.mdDoc "Include conversions with potentially changed behavior."; - default = false; - }; - binPath = - mkOption { - type = types.str; - description = lib.mdDoc "flynt binary path. Can be used to specify the flynt binary from an existing Python environment."; - default = "${settings.flynt.package}/bin/flynt"; - defaultText = "\${settings.flynt.package}/bin/flynt"; - }; - dry-run = - mkOption { - type = types.bool; - description = lib.mdDoc "Do not change files in-place and print diff instead."; - default = false; - }; - exclude = - mkOption { - type = types.listOf types.str; - description = lib.mdDoc "Ignore files with given strings in their absolute path."; - default = [ ]; - }; - fail-on-change = - mkOption { - type = types.bool; - description = lib.mdDoc "Fail when diff is not empty (for linting purposes)."; - default = true; - }; - line-length = - mkOption { - type = types.nullOr types.int; - description = lib.mdDoc "Convert expressions spanning multiple lines, only if the resulting single line will fit into this line length limit."; - default = null; - }; - no-multiline = - mkOption { - type = types.bool; - description = lib.mdDoc "Convert only single line expressions."; - default = false; - }; - package = - mkOption { - type = types.package; - description = lib.mdDoc "The `flynt` package to use."; - default = "${tools.flynt}"; - defaultText = "\${tools.flynt}"; - example = "\${pkgs.python310Packages.flynt}"; - }; - quiet = - mkOption { - type = types.bool; - description = lib.mdDoc "Run without output."; - default = false; - }; - string = - mkOption { - type = types.bool; - description = lib.mdDoc "Interpret the input as a Python code snippet and print the converted version."; - default = false; - }; - transform-concats = - mkOption { - type = types.bool; - description = lib.mdDoc "Replace string concatenations with f-strings."; - default = false; - }; - verbose = - mkOption { - type = types.bool; - description = lib.mdDoc "Run with verbose output."; - default = false; - }; + }; + dune-fmt = mkOption { + type = types.submodule { + imports = [ hookModule ]; + options = { + auto-promote = + mkOption { + type = types.bool; + description = lib.mdDoc "Whether to auto-promote the changes."; + default = true; + }; + + extraRuntimeInputs = + mkOption { + type = types.listOf types.package; + description = lib.mdDoc "Extra runtimeInputs to add to the environment, eg. `ocamlformat`."; + default = [ ]; + }; + }; }; - headache = - { - header-file = mkOption { - type = types.str; - description = lib.mdDoc "Path to the header file."; - default = ".header"; + }; + eclint = mkOption { + type = types.submodule { + imports = [ hookModule ]; + options = { + package = + mkOption { + type = types.package; + description = lib.mdDoc "The `eclint` package to use."; + default = "${tools.eclint}"; + defaultText = lib.literalExpression "\${tools.eclint}"; + example = lib.literalExpression "\${pkgs.eclint}"; + }; + fix = + mkOption { + type = types.bool; + description = lib.mdDoc "Modify files in place rather than showing the errors."; + default = false; + }; + summary = + mkOption { + type = types.bool; + description = lib.mdDoc "Only show number of errors per file."; + default = false; + }; + color = + mkOption { + type = types.enum [ "auto" "always" "never" ]; + description = lib.mdDoc "When to generate colored output."; + default = "auto"; + }; + exclude = + mkOption { + type = types.listOf types.str; + description = lib.mdDoc "Filter to exclude files."; + default = [ ]; + }; + verbosity = + mkOption { + type = types.enum [ 0 1 2 3 4 ]; + description = lib.mdDoc "Log level verbosity"; + default = 0; + }; }; }; - hlint = - { - hintFile = - mkOption { - type = types.nullOr types.path; - description = lib.mdDoc "Path to hlint.yaml. By default, hlint searches for .hlint.yaml in the project root."; - default = null; - }; + }; + eslint = mkOption { + type = types.submodule { + imports = [ hookModule ]; + options = { + binPath = + mkOption { + type = types.path; + description = lib.mdDoc + "`eslint` binary path. E.g. if you want to use the `eslint` in `node_modules`, use `./node_modules/.bin/eslint`."; + default = "${tools.eslint}/bin/eslint"; + defaultText = lib.literalExpression "\${tools.eslint}/bin/eslint"; + }; + + extensions = + mkOption { + type = types.str; + description = lib.mdDoc + "The pattern of files to run on, see [https://pre-commit.com/#hooks-files](https://pre-commit.com/#hooks-files)."; + default = "\\.js$"; + }; + }; }; - hpack = - { - silent = - mkOption { - type = types.bool; - description = lib.mdDoc "Whether generation should be silent."; - default = false; - }; + }; + flake8 = mkOption { + type = types.submodule { + imports = [ hookModule ]; + options = { + binPath = + mkOption { + type = types.str; + description = lib.mdDoc "flake8 binary path. Should be used to specify flake8 binary from your Nix-managed Python environment."; + default = "${tools.flake8}/bin/flake8"; + defaultText = lib.literalExpression '' + "''${tools.flake8}/bin/flake8" + ''; + }; + extendIgnore = + mkOption { + type = types.listOf types.str; + description = lib.mdDoc "List of additional ignore codes"; + default = [ ]; + example = [ "E501" ]; + }; + format = + mkOption { + type = types.str; + description = lib.mdDoc "Output format."; + default = "default"; + }; + }; }; - isort = - { - profile = - mkOption { - type = types.enum [ "" "black" "django" "pycharm" "google" "open_stack" "plone" "attrs" "hug" "wemake" "appnexus" ]; - description = lib.mdDoc "Built-in profiles to allow easy interoperability with common projects and code styles."; - default = ""; - }; - flags = - mkOption { - type = types.str; - description = lib.mdDoc "Flags passed to isort. See all available [here](https://pycqa.github.io/isort/docs/configuration/options.html)."; - default = ""; - }; + }; + flynt = mkOption { + type = types.submodule { + imports = [ hookModule ]; + options = { + aggressive = + mkOption { + type = types.bool; + description = lib.mdDoc "Include conversions with potentially changed behavior."; + default = false; + }; + binPath = + mkOption { + type = types.str; + description = lib.mdDoc "flynt binary path. Can be used to specify the flynt binary from an existing Python environment."; + default = "${settings.flynt.package}/bin/flynt"; + defaultText = "\${settings.flynt.package}/bin/flynt"; + }; + dry-run = + mkOption { + type = types.bool; + description = lib.mdDoc "Do not change files in-place and print diff instead."; + default = false; + }; + exclude = + mkOption { + type = types.listOf types.str; + description = lib.mdDoc "Ignore files with given strings in their absolute path."; + default = [ ]; + }; + fail-on-change = + mkOption { + type = types.bool; + description = lib.mdDoc "Fail when diff is not empty (for linting purposes)."; + default = true; + }; + line-length = + mkOption { + type = types.nullOr types.int; + description = lib.mdDoc "Convert expressions spanning multiple lines, only if the resulting single line will fit into this line length limit."; + default = null; + }; + no-multiline = + mkOption { + type = types.bool; + description = lib.mdDoc "Convert only single line expressions."; + default = false; + }; + package = + mkOption { + type = types.package; + description = lib.mdDoc "The `flynt` package to use."; + default = "${tools.flynt}"; + defaultText = "\${tools.flynt}"; + example = "\${pkgs.python310Packages.flynt}"; + }; + quiet = + mkOption { + type = types.bool; + description = lib.mdDoc "Run without output."; + default = false; + }; + string = + mkOption { + type = types.bool; + description = lib.mdDoc "Interpret the input as a Python code snippet and print the converted version."; + default = false; + }; + transform-concats = + mkOption { + type = types.bool; + description = lib.mdDoc "Replace string concatenations with f-strings."; + default = false; + }; + verbose = + mkOption { + type = types.bool; + description = lib.mdDoc "Run with verbose output."; + default = false; + }; + }; }; - latexindent = - { - flags = - mkOption { + }; + headache = mkOption { + type = types.submodule { + imports = [ hookModule ]; + options = { + header-file = mkOption { type = types.str; - description = lib.mdDoc "Flags passed to latexindent. See available flags [here](https://latexindentpl.readthedocs.io/en/latest/sec-how-to-use.html#from-the-command-line)"; - default = "--local --silent --overwriteIfDifferent"; + description = lib.mdDoc "Path to the header file."; + default = ".header"; }; - }; - lua-ls = - { - checklevel = mkOption { - type = types.enum [ "Error" "Warning" "Information" "Hint" ]; - description = lib.mdDoc - "The diagnostic check level"; - default = "Warning"; - }; - config = mkOption { - type = types.attrs; - description = lib.mdDoc - "See https://github.com/LuaLS/lua-language-server/wiki/Configuration-File#luarcjson"; - default = { }; }; }; - lychee = { - configPath = - mkOption { - type = types.str; - description = lib.mdDoc "Path to the config file."; - default = ""; - }; - flags = - mkOption { - type = types.str; - description = lib.mdDoc "Flags passed to lychee. See all available [here](https://lychee.cli.rs/#/usage/cli)."; - default = ""; - }; }; - markdownlint = { - config = - mkOption { - type = types.attrs; - description = lib.mdDoc - "See https://github.com/DavidAnson/markdownlint/blob/main/schema/.markdownlint.jsonc"; - default = { }; + hlint = mkOption { + type = types.submodule { + imports = [ hookModule ]; + options = { + hintFile = + mkOption { + type = types.nullOr types.path; + description = lib.mdDoc "Path to hlint.yaml. By default, hlint searches for .hlint.yaml in the project root."; + default = null; + }; }; + }; }; - mdl = { - package = - mkOption { - type = types.package; - description = lib.mdDoc "The `mdl` package to use."; - default = "${tools.mdl}"; - defaultText = "\${tools.mdl}"; - example = "\${pkgs.mdl}"; - }; - configPath = - mkOption { - type = types.str; - description = lib.mdDoc "The configuration file to use."; - default = ""; - }; - git-recurse = - mkOption { - type = types.bool; - description = lib.mdDoc "Only process files known to git when given a directory."; - default = false; - }; - ignore-front-matter = - mkOption { - type = types.bool; - description = lib.mdDoc "Ignore YAML front matter."; - default = false; - }; - json = - mkOption { - type = types.bool; - description = lib.mdDoc "Format output as JSON."; - default = false; - }; - rules = - mkOption { - type = types.listOf types.str; - description = lib.mdDoc "Markdown rules to use for linting. Per default all rules are processed."; - default = [ ]; - }; - rulesets = - mkOption { - type = types.listOf types.str; - description = lib.mdDoc "Specify additional ruleset files to load."; - default = [ ]; + hpack = mkOption { + type = types.submodule { + imports = [ hookModule ]; + options = { + silent = + mkOption { + type = types.bool; + description = lib.mdDoc "Whether generation should be silent."; + default = false; + }; }; - show-aliases = - mkOption { - type = types.bool; - description = lib.mdDoc "Show rule alias instead of rule ID when viewing rules."; - default = false; + }; + }; + isort = mkOption { + type = types.submodule { + imports = [ hookModule ]; + options = { + profile = + mkOption { + type = types.enum [ "" "black" "django" "pycharm" "google" "open_stack" "plone" "attrs" "hug" "wemake" "appnexus" ]; + description = lib.mdDoc "Built-in profiles to allow easy interoperability with common projects and code styles."; + default = ""; + }; + flags = + mkOption { + type = types.str; + description = lib.mdDoc "Flags passed to isort. See all available [here](https://pycqa.github.io/isort/docs/configuration/options.html)."; + default = ""; + }; }; - warnings = - mkOption { - type = types.bool; - description = lib.mdDoc "Show Kramdown warnings."; - default = false; + }; + }; + latexindent = mkOption { + type = types.submodule { + imports = [ hookModule ]; + options = { + flags = + mkOption { + type = types.str; + description = lib.mdDoc "Flags passed to latexindent. See available flags [here](https://latexindentpl.readthedocs.io/en/latest/sec-how-to-use.html#from-the-command-line)"; + default = "--local --silent --overwriteIfDifferent"; + }; }; - skip-default-ruleset = - mkOption { - type = types.bool; - description = lib.mdDoc "Do not load the default markdownlint ruleset. Use this option if you only want to load custom rulesets."; - default = false; + }; + }; + lua-ls = mkOption { + type = types.submodule { + imports = [ hookModule ]; + options = { + checklevel = mkOption { + type = types.enum [ "Error" "Warning" "Information" "Hint" ]; + description = lib.mdDoc + "The diagnostic check level"; + default = "Warning"; + }; + config = mkOption { + type = types.attrs; + description = lib.mdDoc + "See https://github.com/LuaLS/lua-language-server/wiki/Configuration-File#luarcjson"; + default = { }; + }; }; - style = - mkOption { - type = types.str; - description = lib.mdDoc "Select which style mdl uses."; - default = "default"; + }; + }; + lychee = mkOption { + type = types.submodule { + imports = [ hookModule ]; + options = { + configPath = + mkOption { + type = types.str; + description = lib.mdDoc "Path to the config file."; + default = ""; + }; + flags = + mkOption { + type = types.str; + description = lib.mdDoc "Flags passed to lychee. See all available [here](https://lychee.cli.rs/#/usage/cli)."; + default = ""; + }; }; - tags = - mkOption { - type = types.listOf types.str; - description = lib.mdDoc "Markdown rules to use for linting containing the given tags. Per default all rules are processed."; - default = [ ]; + }; + }; + markdownlint = mkOption { + type = types.submodule { + imports = [ hookModule ]; + options = { + config = + mkOption { + type = types.attrs; + description = lib.mdDoc + "See https://github.com/DavidAnson/markdownlint/blob/main/schema/.markdownlint.jsonc"; + default = { }; + }; }; - verbose = - mkOption { - type = types.bool; - description = lib.mdDoc "Increase verbosity."; - default = false; + }; + }; + mdl = mkOption { + type = types.submodule { + imports = [ hookModule ]; + options = { + package = + mkOption { + type = types.package; + description = lib.mdDoc "The `mdl` package to use."; + default = "${tools.mdl}"; + defaultText = "\${tools.mdl}"; + example = "\${pkgs.mdl}"; + }; + configPath = + mkOption { + type = types.str; + description = lib.mdDoc "The configuration file to use."; + default = ""; + }; + git-recurse = + mkOption { + type = types.bool; + description = lib.mdDoc "Only process files known to git when given a directory."; + default = false; + }; + ignore-front-matter = + mkOption { + type = types.bool; + description = lib.mdDoc "Ignore YAML front matter."; + default = false; + }; + json = + mkOption { + type = types.bool; + description = lib.mdDoc "Format output as JSON."; + default = false; + }; + rules = + mkOption { + type = types.listOf types.str; + description = lib.mdDoc "Markdown rules to use for linting. Per default all rules are processed."; + default = [ ]; + }; + rulesets = + mkOption { + type = types.listOf types.str; + description = lib.mdDoc "Specify additional ruleset files to load."; + default = [ ]; + }; + show-aliases = + mkOption { + type = types.bool; + description = lib.mdDoc "Show rule alias instead of rule ID when viewing rules."; + default = false; + }; + warnings = + mkOption { + type = types.bool; + description = lib.mdDoc "Show Kramdown warnings."; + default = false; + }; + skip-default-ruleset = + mkOption { + type = types.bool; + description = lib.mdDoc "Do not load the default markdownlint ruleset. Use this option if you only want to load custom rulesets."; + default = false; + }; + style = + mkOption { + type = types.str; + description = lib.mdDoc "Select which style mdl uses."; + default = "default"; + }; + tags = + mkOption { + type = types.listOf types.str; + description = lib.mdDoc "Markdown rules to use for linting containing the given tags. Per default all rules are processed."; + default = [ ]; + }; + verbose = + mkOption { + type = types.bool; + description = lib.mdDoc "Increase verbosity."; + default = false; + }; }; + }; }; - mkdocs-linkcheck = - { - binPath = - mkOption { - type = types.path; - description = lib.mdDoc "mkdocs-linkcheck binary path. Should be used to specify the mkdocs-linkcheck binary from your Nix-managed Python environment."; - default = "${tools.mkdocs-linkcheck}/bin/mkdocs-linkcheck"; - defaultText = lib.literalExpression '' - "''${tools.mkdocs-linkcheck}/bin/mkdocs-linkcheck" - ''; - }; + mkdocs-linkcheck = mkOption { + type = types.submodule { + imports = [ hookModule ]; + options = { + binPath = + mkOption { + type = types.path; + description = lib.mdDoc "mkdocs-linkcheck binary path. Should be used to specify the mkdocs-linkcheck binary from your Nix-managed Python environment."; + default = "${tools.mkdocs-linkcheck}/bin/mkdocs-linkcheck"; + defaultText = lib.literalExpression '' + "''${tools.mkdocs-linkcheck}/bin/mkdocs-linkcheck" + ''; + }; - path = - mkOption { - type = types.str; - description = lib.mdDoc "Path to check"; - default = ""; - }; + path = + mkOption { + type = types.str; + description = lib.mdDoc "Path to check"; + default = ""; + }; - local-only = - mkOption { - type = types.bool; - description = lib.mdDoc "Whether to only check local links."; - default = false; - }; + local-only = + mkOption { + type = types.bool; + description = lib.mdDoc "Whether to only check local links."; + default = false; + }; - recurse = - mkOption { - type = types.bool; - description = lib.mdDoc "Whether to recurse directories under path."; - default = false; - }; + recurse = + mkOption { + type = types.bool; + description = lib.mdDoc "Whether to recurse directories under path."; + default = false; + }; - extension = - mkOption { - type = types.str; - description = lib.mdDoc "File extension to scan for."; - default = ""; - }; + extension = + mkOption { + type = types.str; + description = lib.mdDoc "File extension to scan for."; + default = ""; + }; - method = - mkOption { - type = types.enum [ "get" "head" ]; - description = lib.mdDoc "HTTP method to use when checking external links."; - default = "get"; - }; + method = + mkOption { + type = types.enum [ "get" "head" ]; + description = lib.mdDoc "HTTP method to use when checking external links."; + default = "get"; + }; + }; }; - mypy = - { - binPath = - mkOption { - type = types.str; - description = lib.mdDoc "Mypy binary path. Should be used to specify the mypy executable in an environment containing your typing stubs."; - default = "${tools.mypy}/bin/mypy"; - defaultText = lib.literalExpression '' - "''${tools.mypy}/bin/mypy" - ''; - }; + }; + mypy = mkOption { + type = types.submodule { + imports = [ hookModule ]; + options = { + binPath = + mkOption { + type = types.str; + description = lib.mdDoc "Mypy binary path. Should be used to specify the mypy executable in an environment containing your typing stubs."; + default = "${tools.mypy}/bin/mypy"; + defaultText = lib.literalExpression '' + "''${tools.mypy}/bin/mypy" + ''; + }; + }; }; - nixfmt = - { - width = - mkOption { - type = types.nullOr types.int; - description = lib.mdDoc "Line width."; - default = null; - }; + }; + nixfmt = mkOption { + type = types.submodule { + imports = [ hookModule ]; + options = { + width = + mkOption { + type = types.nullOr types.int; + description = lib.mdDoc "Line width."; + default = null; + }; + }; }; - ormolu = - { - defaultExtensions = - mkOption { - type = types.listOf types.str; - description = lib.mdDoc "Haskell language extensions to enable."; - default = [ ]; - }; - cabalDefaultExtensions = - mkOption { - type = types.bool; - description = lib.mdDoc "Use `default-extensions` from `.cabal` files."; - default = false; - }; + }; + ormolu = mkOption { + type = types.submodule { + imports = [ hookModule ]; + options = { + defaultExtensions = + mkOption { + type = types.listOf types.str; + description = lib.mdDoc "Haskell language extensions to enable."; + default = [ ]; + }; + cabalDefaultExtensions = + mkOption { + type = types.bool; + description = lib.mdDoc "Use `default-extensions` from `.cabal` files."; + default = false; + }; + }; }; - php-cs-fixer = - { - binPath = - mkOption { - type = types.str; - description = lib.mdDoc "PHP-CS-Fixer binary path."; - default = "${tools.php-cs-fixer}/bin/php-cs-fixer"; - defaultText = lib.literalExpression '' - "''${tools.php-cs-fixer}/bin/php-cs-fixer" - ''; - }; + }; + php-cs-fixer = mkOption { + type = types.submodule { + imports = [ hookModule ]; + options = { + binPath = + mkOption { + type = types.str; + description = lib.mdDoc "PHP-CS-Fixer binary path."; + default = "${tools.php-cs-fixer}/bin/php-cs-fixer"; + defaultText = lib.literalExpression '' + "''${tools.php-cs-fixer}/bin/php-cs-fixer" + ''; + }; + }; }; - phpcbf = - { - binPath = - mkOption { - type = types.str; - description = lib.mdDoc "PHP_CodeSniffer binary path."; - default = "${tools.phpcbf}/bin/phpcbf"; - defaultText = lib.literalExpression '' - "''${tools.phpcbf}/bin/phpcbf" - ''; - }; + }; + phpcbf = mkOption { + type = types.submodule { + imports = [ hookModule ]; + options = { + binPath = + mkOption { + type = types.str; + description = lib.mdDoc "PHP_CodeSniffer binary path."; + default = "${tools.phpcbf}/bin/phpcbf"; + defaultText = lib.literalExpression '' + "''${tools.phpcbf}/bin/phpcbf" + ''; + }; + }; }; - phpcs = - { - binPath = - mkOption { - type = types.str; - description = lib.mdDoc "PHP_CodeSniffer binary path."; - default = "${tools.phpcs}/bin/phpcs"; - defaultText = lib.literalExpression '' - "''${tools.phpcs}/bin/phpcs" - ''; - }; + }; + phpcs = mkOption { + type = types.submodule { + imports = [ hookModule ]; + options = { + binPath = + mkOption { + type = types.str; + description = lib.mdDoc "PHP_CodeSniffer binary path."; + default = "${tools.phpcs}/bin/phpcs"; + defaultText = lib.literalExpression '' + "''${tools.phpcs}/bin/phpcs" + ''; + }; + }; }; - phpstan = - { - binPath = - mkOption { - type = types.str; - description = lib.mdDoc "PHPStan binary path."; - default = "${tools.phpstan}/bin/phpstan"; - defaultText = lib.literalExpression '' - "''${tools.phpstan}/bin/phpstan" - ''; - }; + }; + phpstan = mkOption { + type = types.submodule { + imports = [ hookModule ]; + options = { + binPath = + mkOption { + type = types.str; + description = lib.mdDoc "PHPStan binary path."; + default = "${tools.phpstan}/bin/phpstan"; + defaultText = lib.literalExpression '' + "''${tools.phpstan}/bin/phpstan" + ''; + }; + }; }; + }; # See all CLI flags for prettier [here](https://prettier.io/docs/en/cli.html). # See all options for prettier [here](https://prettier.io/docs/en/options.html). - prettier = - { - binPath = - mkOption { - description = lib.mdDoc - "`prettier` binary path. E.g. if you want to use the `prettier` in `node_modules`, use `./node_modules/.bin/prettier`."; - type = types.path; - default = "${tools.prettier}/bin/prettier"; - defaultText = lib.literalExpression '' - "''${tools.prettier}/bin/prettier" - ''; - }; - allow-parens = - mkOption { - description = lib.mdDoc "Include parentheses around a sole arrow function parameter."; - default = "always"; - type = types.enum [ "always" "avoid" ]; - }; - bracket-same-line = - mkOption { - description = lib.mdDoc "Put > of opening tags on the last line instead of on a new line."; - type = types.bool; - default = false; - }; - cache = - mkOption { - description = lib.mdDoc "Only format changed files."; - type = types.bool; - default = false; - }; - cache-location = - mkOption { - description = lib.mdDoc "Path to the cache file location used by `--cache` flag."; - type = types.str; - default = "./node_modules/.cache/prettier/.prettier-cache"; - }; - cache-strategy = - mkOption { - description = lib.mdDoc "Strategy for the cache to use for detecting changed files."; - type = types.nullOr (types.enum [ "metadata" "content" ]); - default = null; - }; - check = - mkOption { - description = lib.mdDoc "Output a human-friendly message and a list of unformatted files, if any."; - type = types.bool; - default = false; - }; - list-different = - mkOption { - description = lib.mdDoc "Print the filenames of files that are different from Prettier formatting."; - type = types.bool; - default = true; - }; - color = - mkOption { - description = lib.mdDoc "Colorize error messages."; - type = types.bool; - default = true; - }; - configPath = - mkOption { - description = lib.mdDoc "Path to a Prettier configuration file (.prettierrc, package.json, prettier.config.js)."; - type = types.str; - default = ""; - }; - config-precedence = - mkOption { - description = lib.mdDoc "Defines how config file should be evaluated in combination of CLI options."; - type = types.enum [ "cli-override" "file-override" "prefer-file" ]; - default = "cli-override"; - }; - embedded-language-formatting = - mkOption { - description = lib.mdDoc "Control how Prettier formats quoted code embedded in the file."; - type = types.enum [ "auto" "off" ]; - default = "auto"; - }; - end-of-line = - mkOption { - description = lib.mdDoc "Which end of line characters to apply."; - type = types.enum [ "lf" "crlf" "cr" "auto" ]; - default = "lf"; - }; - html-whitespace-sensitivity = - mkOption { - description = lib.mdDoc "How to handle whitespaces in HTML."; - type = types.enum [ "css" "strict" "ignore" ]; - default = "css"; - }; - ignore-path = - mkOption { - description = lib.mdDoc "Path to a file containing patterns that describe files to ignore. - By default, prettier looks for `./.gitignore` and `./.prettierignore`. - Multiple values are accepted."; - type = types.listOf types.path; - default = [ ]; - }; - ignore-unknown = - mkOption { - description = lib.mdDoc "Ignore unknown files."; - type = types.bool; - default = true; - }; - insert-pragma = - mkOption { - description = lib.mdDoc "Insert @format pragma into file's first docblock comment."; - type = types.bool; - default = false; - }; - jsx-single-quote = - mkOption { - description = lib.mdDoc "Use single quotes in JSX."; - type = types.bool; - default = false; - }; - log-level = - mkOption { - description = lib.mdDoc "What level of logs to report."; - type = types.enum [ "silent" "error" "warn" "log" "debug" ]; - default = "log"; - example = "debug"; - }; - no-bracket-spacing = - mkOption { - description = lib.mdDoc "Do not print spaces between brackets."; - type = types.bool; - default = false; - }; - no-config = - mkOption { - description = lib.mdDoc "Do not look for a configuration file."; - type = types.bool; - default = false; - }; - no-editorconfig = - mkOption { - description = lib.mdDoc "Don't take .editorconfig into account when parsing configuration."; - type = types.bool; - default = false; - }; - no-error-on-unmatched-pattern = - mkOption { - description = lib.mdDoc "Prevent errors when pattern is unmatched."; - type = types.bool; - default = false; - }; - no-semi = - mkOption { - description = lib.mdDoc "Do not print semicolons, except at the beginning of lines which may need them."; - type = types.bool; - default = false; - }; - parser = - mkOption { - description = lib.mdDoc "Which parser to use."; - type = types.enum [ "" "flow" "babel" "babel-flow" "babel-ts" "typescript" "acorn" "espree" "meriyah" "css" "less" "scss" "json" "json5" "json-stringify" "graphql" "markdown" "mdx" "vue" "yaml" "glimmer" "html" "angular" "lwc" ]; - default = ""; - }; - print-width = - mkOption { - type = types.int; - description = lib.mdDoc "Line length that the printer will wrap on."; - default = 80; - }; - prose-wrap = - mkOption { - description = lib.mdDoc "When to or if at all hard wrap prose to print width."; - type = types.enum [ "always" "never" "preserve" ]; - default = "preserve"; - }; - plugins = - mkOption { - description = lib.mdDoc "Add plugins from paths."; - type = types.listOf types.str; - default = [ ]; - }; - quote-props = - mkOption { - description = lib.mdDoc "Change when properties in objects are quoted."; - type = types.enum [ "as-needed" "consistent" "preserve" ]; - default = "as-needed"; - }; - require-pragma = - mkOption { - description = lib.mdDoc "Require either '@prettier' or '@format' to be present in the file's first docblock comment."; - type = types.bool; - default = false; - }; - single-attribute-per-line = - mkOption { - description = lib.mdDoc "Enforce single attribute per line in HTML, Vue andJSX."; - type = types.bool; - default = false; - }; - single-quote = - mkOption { - description = lib.mdDoc "Number of spaces per indentation-level."; - type = types.bool; - default = false; - }; - tab-width = - mkOption { - description = lib.mdDoc "Line length that the printer will wrap on."; - type = types.int; - default = 2; - }; - trailing-comma = - mkOption { - description = lib.mdDoc "Print trailing commas wherever possible in multi-line comma-separated syntactic structures."; - type = types.enum [ "all" "es5" "none" ]; - default = "all"; - }; - use-tabs = - mkOption { - type = types.bool; - description = lib.mdDoc "Indent with tabs instead of spaces."; - default = false; - }; - vue-indent-script-and-style = - mkOption { - description = lib.mdDoc "Indent script and style tags in Vue files."; - type = types.bool; - default = false; - }; - with-node-modules = - mkOption { - type = types.bool; - description = lib.mdDoc "Process files inside 'node_modules' directory."; - default = false; - }; - write = - mkOption { - description = lib.mdDoc "Edit files in-place."; - type = types.bool; - default = true; - }; + prettier = mkOption { + type = types.submodule { + imports = [ hookModule ]; + options = { + binPath = + mkOption { + description = lib.mdDoc + "`prettier` binary path. E.g. if you want to use the `prettier` in `node_modules`, use `./node_modules/.bin/prettier`."; + type = types.path; + default = "${tools.prettier}/bin/prettier"; + defaultText = lib.literalExpression '' + "''${tools.prettier}/bin/prettier" + ''; + }; + allow-parens = + mkOption { + description = lib.mdDoc "Include parentheses around a sole arrow function parameter."; + default = "always"; + type = types.enum [ "always" "avoid" ]; + }; + bracket-same-line = + mkOption { + description = lib.mdDoc "Put > of opening tags on the last line instead of on a new line."; + type = types.bool; + default = false; + }; + cache = + mkOption { + description = lib.mdDoc "Only format changed files."; + type = types.bool; + default = false; + }; + cache-location = + mkOption { + description = lib.mdDoc "Path to the cache file location used by `--cache` flag."; + type = types.str; + default = "./node_modules/.cache/prettier/.prettier-cache"; + }; + cache-strategy = + mkOption { + description = lib.mdDoc "Strategy for the cache to use for detecting changed files."; + type = types.nullOr (types.enum [ "metadata" "content" ]); + default = null; + }; + # check = + # mkOption { + # description = lib.mdDoc "Output a human-friendly message and a list of unformatted files, if any."; + # type = types.bool; + # default = false; + # }; + list-different = + mkOption { + description = lib.mdDoc "Print the filenames of files that are different from Prettier formatting."; + type = types.bool; + default = true; + }; + color = + mkOption { + description = lib.mdDoc "Colorize error messages."; + type = types.bool; + default = true; + }; + configPath = + mkOption { + description = lib.mdDoc "Path to a Prettier configuration file (.prettierrc, package.json, prettier.config.js)."; + type = types.str; + default = ""; + }; + config-precedence = + mkOption { + description = lib.mdDoc "Defines how config file should be evaluated in combination of CLI options."; + type = types.enum [ "cli-override" "file-override" "prefer-file" ]; + default = "cli-override"; + }; + embedded-language-formatting = + mkOption { + description = lib.mdDoc "Control how Prettier formats quoted code embedded in the file."; + type = types.enum [ "auto" "off" ]; + default = "auto"; + }; + end-of-line = + mkOption { + description = lib.mdDoc "Which end of line characters to apply."; + type = types.enum [ "lf" "crlf" "cr" "auto" ]; + default = "lf"; + }; + html-whitespace-sensitivity = + mkOption { + description = lib.mdDoc "How to handle whitespaces in HTML."; + type = types.enum [ "css" "strict" "ignore" ]; + default = "css"; + }; + ignore-path = + mkOption { + description = lib.mdDoc "Path to a file containing patterns that describe files to ignore. + By default, prettier looks for `./.gitignore` and `./.prettierignore`. + Multiple values are accepted."; + type = types.listOf types.path; + default = [ ]; + }; + ignore-unknown = + mkOption { + description = lib.mdDoc "Ignore unknown files."; + type = types.bool; + default = true; + }; + insert-pragma = + mkOption { + description = lib.mdDoc "Insert @format pragma into file's first docblock comment."; + type = types.bool; + default = false; + }; + jsx-single-quote = + mkOption { + description = lib.mdDoc "Use single quotes in JSX."; + type = types.bool; + default = false; + }; + log-level = + mkOption { + description = lib.mdDoc "What level of logs to report."; + type = types.enum [ "silent" "error" "warn" "log" "debug" ]; + default = "log"; + example = "debug"; + }; + no-bracket-spacing = + mkOption { + description = lib.mdDoc "Do not print spaces between brackets."; + type = types.bool; + default = false; + }; + no-config = + mkOption { + description = lib.mdDoc "Do not look for a configuration file."; + type = types.bool; + default = false; + }; + no-editorconfig = + mkOption { + description = lib.mdDoc "Don't take .editorconfig into account when parsing configuration."; + type = types.bool; + default = false; + }; + no-error-on-unmatched-pattern = + mkOption { + description = lib.mdDoc "Prevent errors when pattern is unmatched."; + type = types.bool; + default = false; + }; + no-semi = + mkOption { + description = lib.mdDoc "Do not print semicolons, except at the beginning of lines which may need them."; + type = types.bool; + default = false; + }; + parser = + mkOption { + description = lib.mdDoc "Which parser to use."; + type = types.enum [ "" "flow" "babel" "babel-flow" "babel-ts" "typescript" "acorn" "espree" "meriyah" "css" "less" "scss" "json" "json5" "json-stringify" "graphql" "markdown" "mdx" "vue" "yaml" "glimmer" "html" "angular" "lwc" ]; + default = ""; + }; + print-width = + mkOption { + type = types.int; + description = lib.mdDoc "Line length that the printer will wrap on."; + default = 80; + }; + prose-wrap = + mkOption { + description = lib.mdDoc "When to or if at all hard wrap prose to print width."; + type = types.enum [ "always" "never" "preserve" ]; + default = "preserve"; + }; + plugins = + mkOption { + description = lib.mdDoc "Add plugins from paths."; + type = types.listOf types.str; + default = [ ]; + }; + quote-props = + mkOption { + description = lib.mdDoc "Change when properties in objects are quoted."; + type = types.enum [ "as-needed" "consistent" "preserve" ]; + default = "as-needed"; + }; + require-pragma = + mkOption { + description = lib.mdDoc "Require either '@prettier' or '@format' to be present in the file's first docblock comment."; + type = types.bool; + default = false; + }; + single-attribute-per-line = + mkOption { + description = lib.mdDoc "Enforce single attribute per line in HTML, Vue andJSX."; + type = types.bool; + default = false; + }; + single-quote = + mkOption { + description = lib.mdDoc "Number of spaces per indentation-level."; + type = types.bool; + default = false; + }; + tab-width = + mkOption { + description = lib.mdDoc "Line length that the printer will wrap on."; + type = types.int; + default = 2; + }; + trailing-comma = + mkOption { + description = lib.mdDoc "Print trailing commas wherever possible in multi-line comma-separated syntactic structures."; + type = types.enum [ "all" "es5" "none" ]; + default = "all"; + }; + use-tabs = + mkOption { + type = types.bool; + description = lib.mdDoc "Indent with tabs instead of spaces."; + default = false; + }; + vue-indent-script-and-style = + mkOption { + description = lib.mdDoc "Indent script and style tags in Vue files."; + type = types.bool; + default = false; + }; + with-node-modules = + mkOption { + type = types.bool; + description = lib.mdDoc "Process files inside 'node_modules' directory."; + default = false; + }; + write = + mkOption { + description = lib.mdDoc "Edit files in-place."; + type = types.bool; + default = true; + }; + }; }; - psalm = - { - binPath = - mkOption { - type = types.str; - description = lib.mdDoc "Psalm binary path."; - default = "${tools.psalm}/bin/psalm"; - defaultText = lib.literalExpression '' - "''${tools.psalm}/bin/psalm" - ''; - }; + }; + psalm = mkOption { + type = types.submodule { + imports = [ hookModule ]; + options = { + binPath = + mkOption { + type = types.str; + description = lib.mdDoc "Psalm binary path."; + default = "${tools.psalm}/bin/psalm"; + defaultText = lib.literalExpression '' + "''${tools.psalm}/bin/psalm" + ''; + }; + }; }; - pylint = - { - binPath = - mkOption { - type = types.str; - description = lib.mdDoc "Pylint binary path. Should be used to specify Pylint binary from your Nix-managed Python environment."; - default = "${tools.pylint}/bin/pylint"; - defaultText = lib.literalExpression '' - "''${tools.pylint}/bin/pylint" - ''; - }; - reports = - mkOption { - type = types.bool; - description = lib.mdDoc "Whether to display a full report."; - default = false; - }; - score = - mkOption { - type = types.bool; - description = lib.mdDoc "Whether to activate the evaluation score."; - default = true; - }; + }; + pylint = mkOption { + type = types.submodule { + imports = [ hookModule ]; + options = { + binPath = + mkOption { + type = types.str; + description = lib.mdDoc "Pylint binary path. Should be used to specify Pylint binary from your Nix-managed Python environment."; + default = "${tools.pylint}/bin/pylint"; + defaultText = lib.literalExpression '' + "''${tools.pylint}/bin/pylint" + ''; + }; + reports = + mkOption { + type = types.bool; + description = lib.mdDoc "Whether to display a full report."; + default = false; + }; + score = + mkOption { + type = types.bool; + description = lib.mdDoc "Whether to activate the evaluation score."; + default = true; + }; + }; }; - pyright = - { - binPath = - mkOption { - type = types.str; - description = lib.mdDoc "Pyright binary path. Should be used to specify the pyright executable in an environment containing your typing stubs."; - default = "${tools.pyright}/bin/pyright"; - defaultText = lib.literalExpression '' - "''${tools.pyright}/bin/pyright" - ''; - }; + }; + pyright = mkOption { + type = types.submodule { + imports = [ hookModule ]; + options = { + binPath = + mkOption { + type = types.str; + description = lib.mdDoc "Pyright binary path. Should be used to specify the pyright executable in an environment containing your typing stubs."; + default = "${tools.pyright}/bin/pyright"; + defaultText = lib.literalExpression '' + "''${tools.pyright}/bin/pyright" + ''; + }; + }; }; - pyupgrade = - { - binPath = - mkOption { - type = types.str; - description = lib.mdDoc "pyupgrade binary path. Should be used to specify the pyupgrade binary from your Nix-managed Python environment."; - default = "${tools.pyupgrade}/bin/pyupgrade"; - defaultText = lib.literalExpression '' - "''${tools.pyupgrade}/bin/pyupgrade" - ''; - }; + }; + pyupgrade = mkOption { + type = types.submodule { + imports = [ hookModule ]; + options = { + binPath = + mkOption { + type = types.str; + description = lib.mdDoc "pyupgrade binary path. Should be used to specify the pyupgrade binary from your Nix-managed Python environment."; + default = "${tools.pyupgrade}/bin/pyupgrade"; + defaultText = lib.literalExpression '' + "''${tools.pyupgrade}/bin/pyupgrade" + ''; + }; + }; }; - revive = - { - configPath = - mkOption { + }; + revive = mkOption { + type = types.submodule { + imports = [ hookModule ]; + options = { + configPath = + mkOption { + type = types.str; + description = lib.mdDoc "Path to the configuration TOML file."; + # an empty string translates to use default configuration of the + # underlying revive binary + default = ""; + }; + }; + }; + }; + rome = mkOption { + type = types.submodule { + imports = [ hookModule ]; + options = { + binPath = + mkOption { + type = types.path; + description = lib.mdDoc "`rome` binary path. E.g. if you want to use the `rome` in `node_modules`, use `./node_modules/.bin/rome`."; + default = "${tools.biome}/bin/biome"; + defaultText = "\${tools.biome}/bin/biome"; + }; + + write = + mkOption { + type = types.bool; + description = lib.mdDoc "Whether to edit files inplace."; + default = true; + }; + + configPath = mkOption { type = types.str; - description = lib.mdDoc "Path to the configuration TOML file."; + description = lib.mdDoc "Path to the configuration JSON file"; # an empty string translates to use default configuration of the - # underlying revive binary + # underlying rome binary (i.e rome.json if exists) default = ""; }; + }; }; - rome = - { - binPath = - mkOption { - type = types.path; - description = lib.mdDoc "`rome` binary path. E.g. if you want to use the `rome` in `node_modules`, use `./node_modules/.bin/rome`."; - default = "${tools.biome}/bin/biome"; - defaultText = "\${tools.biome}/bin/biome"; - }; - - write = - mkOption { - type = types.bool; - description = lib.mdDoc "Whether to edit files inplace."; - default = true; + }; + rust = mkOption { + type = types.submodule { + imports = [ hookModule ]; + options = { + cargoManifestPath = mkOption { + type = types.nullOr types.str; + description = lib.mdDoc "Path to Cargo.toml"; + default = null; }; - - configPath = mkOption { - type = types.str; - description = lib.mdDoc "Path to the configuration JSON file"; - # an empty string translates to use default configuration of the - # underlying rome binary (i.e rome.json if exists) - default = ""; }; }; - rust = - { - cargoManifestPath = mkOption { - type = types.nullOr types.str; - description = lib.mdDoc "Path to Cargo.toml"; - default = null; + }; + statix = mkOption { + type = types.submodule { + imports = [ hookModule ]; + options = { + format = + mkOption { + type = types.enum [ "stderr" "errfmt" "json" ]; + description = lib.mdDoc "Error Output format."; + default = "errfmt"; + }; + + ignore = + mkOption { + type = types.listOf types.str; + description = lib.mdDoc "Globs of file patterns to skip."; + default = [ ]; + example = [ "flake.nix" "_*" ]; + }; }; }; - statix = - { - format = - mkOption { - type = types.enum [ "stderr" "errfmt" "json" ]; - description = lib.mdDoc "Error Output format."; - default = "errfmt"; - }; + }; + treefmt = mkOption { + type = types.submodule { + imports = [ hookModule ]; + options = { + package = mkOption { + type = types.package; + description = lib.mdDoc + '' + The `treefmt` package to use. - ignore = - mkOption { - type = types.listOf types.str; - description = lib.mdDoc "Globs of file patterns to skip."; - default = [ ]; - example = [ "flake.nix" "_*" ]; + Should include all the formatters configured by treefmt. + + For example: + ```nix + pkgs.writeShellApplication { + name = "treefmt"; + runtimeInputs = [ + pkgs.treefmt + pkgs.nixpkgs-fmt + pkgs.black + ]; + text = + ''' + exec treefmt "$@" + '''; + } + ``` + ''; }; + }; }; - treefmt = - { - package = mkOption { - type = types.package; - description = lib.mdDoc - '' - The `treefmt` package to use. + }; + typos = mkOption { + type = types.submodule { + imports = [ hookModule ]; + options = { + binary = + mkOption { + type = types.bool; + description = lib.mdDoc "Whether to search binary files."; + default = false; + }; - Should include all the formatters configured by treefmt. + color = + mkOption { + type = types.enum [ "auto" "always" "never" ]; + description = lib.mdDoc "When to use generate output."; + default = "auto"; + }; - For example: - ```nix - pkgs.writeShellApplication { - name = "treefmt"; - runtimeInputs = [ - pkgs.treefmt - pkgs.nixpkgs-fmt - pkgs.black - ]; - text = - ''' - exec treefmt "$@" - '''; - } - ``` - ''; + config = + mkOption { + type = types.str; + description = lib.mdDoc "Multiline-string configuration passed as config file. If set, config set in `typos.settings.configPath` gets ignored."; + default = ""; + example = '' + [files] + ignore-dot = true + + [default] + binary = false + + [type.py] + extend-glob = [] + ''; + }; + + configPath = + mkOption { + type = types.str; + description = lib.mdDoc "Path to a custom config file."; + default = ""; + example = ".typos.toml"; + }; + + diff = + mkOption { + type = types.bool; + description = lib.mdDoc "Print a diff of what would change."; + default = false; + }; + + exclude = + mkOption { + type = types.str; + description = lib.mdDoc "Ignore files and directories matching the glob."; + default = ""; + example = "*.nix"; + }; + + format = + mkOption { + type = types.enum [ "silent" "brief" "long" "json" ]; + description = lib.mdDoc "Output format to use."; + default = "long"; + }; + + hidden = + mkOption { + type = types.bool; + description = lib.mdDoc "Search hidden files and directories."; + default = false; + }; + + ignored-words = + mkOption { + type = types.listOf types.str; + description = lib.mdDoc "Spellings and words to ignore."; + default = [ ]; + example = [ + "MQTT" + "mosquitto" + ]; + }; + + locale = + mkOption { + type = types.enum [ "en" "en-us" "en-gb" "en-ca" "en-au" ]; + description = lib.mdDoc "Which language to use for spell checking."; + default = "en"; + }; + + no-check-filenames = + mkOption { + type = types.bool; + description = lib.mdDoc "Skip verifying spelling in file names."; + default = false; + }; + + no-check-files = + mkOption { + type = types.bool; + description = lib.mdDoc "Skip verifying spelling in files."; + default = false; + }; + + no-unicode = + mkOption { + type = types.bool; + description = lib.mdDoc "Only allow ASCII characters in identifiers."; + default = false; + }; + + quiet = + mkOption { + type = types.bool; + description = lib.mdDoc "Less output per occurence."; + default = false; + }; + + verbose = + mkOption { + type = types.bool; + description = lib.mdDoc "More output per occurence."; + default = false; + }; + + write = + mkOption { + type = types.bool; + description = lib.mdDoc "Fix spelling in files by writing them. Cannot be used with `typos.settings.diff`."; + default = false; + }; }; }; - typos = - { - binary = - mkOption { + }; + vale = mkOption { + type = types.submodule { + imports = [ hookModule ]; + options = { + config = + mkOption { + type = types.str; + description = lib.mdDoc "Multiline-string configuration passed as config file."; + default = ""; + example = '' + MinAlertLevel = suggestion + [*] + BasedOnStyles = Vale + ''; + }; + configPath = + mkOption { + type = types.str; + description = lib.mdDoc "Path to the config file."; + default = ""; + }; + flags = + mkOption { + type = types.str; + description = lib.mdDoc "Flags passed to vale."; + default = ""; + }; + }; + }; + }; + yamllint = mkOption { + type = types.submodule { + imports = [ hookModule ]; + options = { + relaxed = mkOption { type = types.bool; - description = lib.mdDoc "Whether to search binary files."; + description = lib.mdDoc "Whether to use the relaxed configuration."; default = false; }; - color = - mkOption { - type = types.enum [ "auto" "always" "never" ]; - description = lib.mdDoc "When to use generate output."; - default = "auto"; - }; - config = - mkOption { - type = types.str; - description = lib.mdDoc "Multiline-string configuration passed as config file. If set, config set in `typos.settings.configPath` gets ignored."; - default = ""; - example = '' - [files] - ignore-dot = true - - [default] - binary = false - [type.py] - extend-glob = [] - ''; - }; - configPath = - mkOption { - type = types.str; - description = lib.mdDoc "Path to a custom config file."; - default = ""; - example = ".typos.toml"; - }; - diff = - mkOption { - type = types.bool; - description = lib.mdDoc "Print a diff of what would change."; - default = false; - }; - exclude = - mkOption { + configPath = mkOption { type = types.str; - description = lib.mdDoc "Ignore files and directories matching the glob."; + description = lib.mdDoc "Path to the YAML configuration file."; + # an empty string translates to use default configuration of the + # underlying yamllint binary default = ""; - example = "*.nix"; - }; - format = - mkOption { - type = types.enum [ "silent" "brief" "long" "json" ]; - description = lib.mdDoc "Output format to use."; - default = "long"; - }; - hidden = - mkOption { - type = types.bool; - description = lib.mdDoc "Search hidden files and directories."; - default = false; - }; - ignored-words = - mkOption { - type = types.listOf types.str; - description = lib.mdDoc "Spellings and words to ignore."; - default = [ ]; - example = [ - "MQTT" - "mosquitto" - ]; }; - locale = - mkOption { - type = types.enum [ "en" "en-us" "en-gb" "en-ca" "en-au" ]; - description = lib.mdDoc "Which language to use for spell checking."; - default = "en"; - }; - no-check-filenames = - mkOption { - type = types.bool; - description = lib.mdDoc "Skip verifying spelling in file names."; - default = false; - }; - no-check-files = - mkOption { - type = types.bool; - description = lib.mdDoc "Skip verifying spelling in files."; - default = false; - }; - no-unicode = - mkOption { - type = types.bool; - description = lib.mdDoc "Only allow ASCII characters in identifiers."; - default = false; - }; - quiet = - mkOption { - type = types.bool; - description = lib.mdDoc "Less output per occurence."; - default = false; - }; - verbose = - mkOption { - type = types.bool; - description = lib.mdDoc "More output per occurence."; - default = false; - }; - write = - mkOption { - type = types.bool; - description = lib.mdDoc "Fix spelling in files by writing them. Cannot be used with `typos.settings.diff`."; - default = false; - }; - }; - vale = { - config = - mkOption { - type = types.str; - description = lib.mdDoc "Multiline-string configuration passed as config file."; - default = ""; - example = '' - MinAlertLevel = suggestion - [*] - BasedOnStyles = Vale - ''; - }; - configPath = - mkOption { - type = types.str; - description = lib.mdDoc "Path to the config file."; - default = ""; - }; - flags = - mkOption { - type = types.str; - description = lib.mdDoc "Flags passed to vale."; - default = ""; - }; - }; - yamllint = - { - relaxed = mkOption { - type = types.bool; - description = lib.mdDoc "Whether to use the relaxed configuration."; - default = false; - }; - - configPath = mkOption { - type = types.str; - description = lib.mdDoc "Path to the YAML configuration file."; - # an empty string translates to use default configuration of the - # underlying yamllint binary - default = ""; }; }; + }; }; # PLEASE keep this sorted alphabetically. @@ -2305,7 +2505,7 @@ in ruff = { name = "ruff"; - description = " An extremely fast Python linter, written in Rust."; + description = "An extremely fast Python linter, written in Rust."; entry = "${tools.ruff}/bin/ruff --fix"; types = [ "python" ]; }; diff --git a/modules/pre-commit.nix b/modules/pre-commit.nix index 88faeb59..3e51d85f 100644 --- a/modules/pre-commit.nix +++ b/modules/pre-commit.nix @@ -17,158 +17,155 @@ let cfg = config; install_stages = lib.unique (cfg.default_stages ++ (builtins.concatLists (lib.mapAttrsToList (_: h: h.stages) enabledHooks))); - hookType = - types.submodule ( - { config, name, ... }: - { - options = - { - enable = - mkOption { - type = types.bool; - description = lib.mdDoc "Whether to enable this pre-commit hook."; - default = false; - }; - raw = - mkOption { - type = types.attrsOf types.unspecified; - description = lib.mdDoc - '' - Raw fields of a pre-commit hook. This is mostly for internal use but - exposed in case you need to work around something. - - Default: taken from the other hook options. - ''; - }; - name = - mkOption { - type = types.str; - default = name; - defaultText = lib.literalMD "internal name, same as `id`"; - description = lib.mdDoc - '' - The name of the hook - shown during hook execution. - ''; - }; - entry = - mkOption { - type = types.str; - description = lib.mdDoc - '' - The entry point - the executable to run. {option}`entry` can also contain arguments that will not be overridden, such as `entry = "autopep8 -i";`. - ''; - }; - language = - mkOption { - type = types.str; - description = lib.mdDoc - '' - The language of the hook - tells pre-commit how to install the hook. - ''; - default = "system"; - }; - files = - mkOption { - type = types.str; - description = lib.mdDoc - '' - The pattern of files to run on. - ''; - default = ""; - }; - types = - mkOption { - type = types.listOf types.str; - description = lib.mdDoc - '' - List of file types to run on. See [Filtering files with types](https://pre-commit.com/#plugins). - ''; - default = [ "file" ]; - }; - types_or = - mkOption { - type = types.listOf types.str; - description = lib.mdDoc - '' - List of file types to run on, where only a single type needs to match. - ''; - default = [ ]; - }; - description = - mkOption { - type = types.str; - description = lib.mdDoc - '' - Description of the hook. used for metadata purposes only. - ''; - default = ""; - }; - excludes = - mkOption { - type = types.listOf types.str; - description = lib.mdDoc - '' - Exclude files that were matched by these patterns. - ''; - default = [ ]; - }; - pass_filenames = - mkOption { - type = types.bool; - description = lib.mdDoc '' - Whether to pass filenames as arguments to the entry point. - ''; - default = true; - }; - fail_fast = mkOption { - type = types.bool; - description = lib.mdDoc '' - if true pre-commit will stop running hooks if this hook fails. + hookType = types.submodule ( + { config, name, ... }: { + options = { + enable = + mkOption { + type = types.bool; + description = lib.mdDoc "Whether to enable this pre-commit hook."; + default = false; + }; + raw = + mkOption { + type = types.attrsOf types.unspecified; + description = lib.mdDoc + '' + Raw fields of a pre-commit hook. This is mostly for internal use but + exposed in case you need to work around something. + + Default: taken from the other hook options. ''; - default = false; - }; - require_serial = mkOption { - type = types.bool; - description = lib.mdDoc '' - if true this hook will execute using a single process instead of in parallel. + }; + name = + mkOption { + type = types.str; + # default = name; + defaultText = lib.literalMD "internal name, same as `id`"; + description = lib.mdDoc + '' + The name of the hook - shown during hook execution. ''; - default = false; - }; - stages = - mkOption { - type = types.listOf types.str; - description = lib.mdDoc '' - Confines the hook to run at a particular stage. - ''; - default = cfg.default_stages; - defaultText = (lib.literalExpression or lib.literalExample) "default_stages"; - }; - verbose = mkOption { - type = types.bool; - default = false; - description = lib.mdDoc '' - forces the output of the hook to be printed even when the hook passes. + }; + entry = + mkOption { + type = types.str; + description = lib.mdDoc + '' + The entry point - the executable to run. {option}`entry` can also contain arguments that will not be overridden, such as `entry = "autopep8 -i";`. ''; - }; - always_run = mkOption { - type = types.bool; - default = false; - description = lib.mdDoc '' - if true this hook will run even if there are no matching files. + }; + language = + mkOption { + type = types.str; + description = lib.mdDoc + '' + The language of the hook - tells pre-commit how to install the hook. ''; - }; + default = "system"; }; - config = - { - raw = - { - inherit (config) name entry language files types types_or pass_filenames fail_fast require_serial stages verbose always_run; - id = name; - exclude = mergeExcludes config.excludes; - }; + files = + mkOption { + type = types.str; + description = lib.mdDoc + '' + The pattern of files to run on. + ''; + default = ""; + }; + types = + mkOption { + type = types.listOf types.str; + description = lib.mdDoc + '' + List of file types to run on. See [Filtering files with types](https://pre-commit.com/#plugins). + ''; + default = [ "file" ]; }; - } - ); + types_or = + mkOption { + type = types.listOf types.str; + description = lib.mdDoc + '' + List of file types to run on, where only a single type needs to match. + ''; + default = [ ]; + }; + description = + mkOption { + type = types.str; + description = lib.mdDoc + '' + Description of the hook. used for metadata purposes only. + ''; + default = ""; + }; + excludes = + mkOption { + type = types.listOf types.str; + description = lib.mdDoc + '' + Exclude files that were matched by these patterns. + ''; + default = [ ]; + }; + pass_filenames = + mkOption { + type = types.bool; + description = lib.mdDoc '' + Whether to pass filenames as arguments to the entry point. + ''; + default = true; + }; + fail_fast = mkOption { + type = types.bool; + description = lib.mdDoc '' + if true pre-commit will stop running hooks if this hook fails. + ''; + default = false; + }; + require_serial = mkOption { + type = types.bool; + description = lib.mdDoc '' + if true this hook will execute using a single process instead of in parallel. + ''; + default = false; + }; + stages = + mkOption { + type = types.listOf types.str; + description = lib.mdDoc '' + Confines the hook to run at a particular stage. + ''; + default = cfg.default_stages; + defaultText = (lib.literalExpression or lib.literalExample) "default_stages"; + }; + verbose = mkOption { + type = types.bool; + default = false; + description = lib.mdDoc '' + forces the output of the hook to be printed even when the hook passes. + ''; + }; + always_run = mkOption { + type = types.bool; + default = false; + description = lib.mdDoc '' + if true this hook will run even if there are no matching files. + ''; + }; + }; + config = + { + raw = + { + inherit (config) name entry language files types types_or pass_filenames fail_fast require_serial stages verbose always_run; + id = config.name; + exclude = mergeExcludes config.excludes; + }; + }; + } + ); mergeExcludes = excludes: @@ -259,7 +256,9 @@ in hooks = mkOption { - type = types.attrsOf hookType; + type = types.submodule { + freeformType = types.attrsOf hookType; + }; description = lib.mdDoc '' The hook definitions. diff --git a/nix/run.nix b/nix/run.nix index de2402e9..492724fd 100644 --- a/nix/run.nix +++ b/nix/run.nix @@ -4,7 +4,6 @@ builtinStuff@{ pkgs, tools, isFlakes, pre-commit, git, runCommand, writeText, wr , hooks ? { } , excludes ? [ ] , tools ? { } -, settings ? { } , default_stages ? [ "commit" ] }: let @@ -18,7 +17,7 @@ let { _module.args.pkgs = pkgs; _module.args.gitignore-nix-src = gitignore-nix-src; - inherit hooks excludes settings default_stages; + inherit hooks excludes default_stages; tools = builtinStuff.tools // tools; package = pre-commit; } // (if isFlakes From 4f427b47fb35f15899139b7845a1eed21a1f7880 Mon Sep 17 00:00:00 2001 From: Sander Date: Sat, 10 Feb 2024 20:47:32 +0000 Subject: [PATCH 02/26] Annotate and fix errors --- modules/hooks.nix | 150 +++++++++++++++++++--------------------------- nix/default.nix | 2 +- 2 files changed, 61 insertions(+), 91 deletions(-) diff --git a/modules/hooks.nix b/modules/hooks.nix index 48973b35..9d90139b 100644 --- a/modules/hooks.nix +++ b/modules/hooks.nix @@ -9,8 +9,8 @@ let cargoManifestPathArg = lib.optionalString - (settings.rust.cargoManifestPath != null) - "--manifest-path ${lib.escapeShellArg settings.rust.cargoManifestPath}"; + (config.settings.rust.cargoManifestPath != null) + "--manifest-path ${lib.escapeShellArg config.settings.rust.cargoManifestPath}"; mkCmdArgs = predActionList: lib.concatStringsSep @@ -23,6 +23,13 @@ let in { + # PLEASE keep this sorted alphabetically. + options.settings.rust.cargoManifestPath = mkOption { + type = types.nullOr types.str; + description = lib.mdDoc "Path to Cargo.toml"; + default = null; + }; + # PLEASE keep this sorted alphabetically. options.hooks = { @@ -44,14 +51,6 @@ in default = [ ]; example = [ "flake.nix" "./templates" ]; }; - package = - mkOption { - type = types.package; - description = lib.mdDoc "The `alejandra` package to use."; - default = "${tools.alejandra}"; - defaultText = "\${pkgs.alejandra}"; - example = "\${pkgs.alejandra}"; - }; threads = mkOption { type = types.nullOr types.int; @@ -281,14 +280,6 @@ in type = types.submodule { imports = [ hookModule ]; options = { - package = - mkOption { - type = types.package; - description = lib.mdDoc "The `eclint` package to use."; - default = "${tools.eclint}"; - defaultText = lib.literalExpression "\${tools.eclint}"; - example = lib.literalExpression "\${pkgs.eclint}"; - }; fix = mkOption { type = types.bool; @@ -421,14 +412,6 @@ in description = lib.mdDoc "Convert only single line expressions."; default = false; }; - package = - mkOption { - type = types.package; - description = lib.mdDoc "The `flynt` package to use."; - default = "${tools.flynt}"; - defaultText = "\${tools.flynt}"; - example = "\${pkgs.python310Packages.flynt}"; - }; quiet = mkOption { type = types.bool; @@ -447,12 +430,13 @@ in description = lib.mdDoc "Replace string concatenations with f-strings."; default = false; }; - verbose = - mkOption { - type = types.bool; - description = lib.mdDoc "Run with verbose output."; - default = false; - }; + # TODO: clashes with hook setting + # verbose = + # mkOption { + # type = types.bool; + # description = lib.mdDoc "Run with verbose output."; + # default = false; + # }; }; }; }; @@ -582,14 +566,6 @@ in type = types.submodule { imports = [ hookModule ]; options = { - package = - mkOption { - type = types.package; - description = lib.mdDoc "The `mdl` package to use."; - default = "${tools.mdl}"; - defaultText = "\${tools.mdl}"; - example = "\${pkgs.mdl}"; - }; configPath = mkOption { type = types.str; @@ -656,12 +632,13 @@ in description = lib.mdDoc "Markdown rules to use for linting containing the given tags. Per default all rules are processed."; default = [ ]; }; - verbose = - mkOption { - type = types.bool; - description = lib.mdDoc "Increase verbosity."; - default = false; - }; + # TODO: clases with hook setting + # verbose = + # mkOption { + # type = types.bool; + # description = lib.mdDoc "Increase verbosity."; + # default = false; + # }; }; }; }; @@ -874,12 +851,12 @@ in type = types.nullOr (types.enum [ "metadata" "content" ]); default = null; }; - # check = - # mkOption { - # description = lib.mdDoc "Output a human-friendly message and a list of unformatted files, if any."; - # type = types.bool; - # default = false; - # }; + check = + mkOption { + description = lib.mdDoc "Output a human-friendly message and a list of unformatted files, if any."; + type = types.bool; + default = false; + }; list-different = mkOption { description = lib.mdDoc "Print the filenames of files that are different from Prettier formatting."; @@ -1192,18 +1169,6 @@ in }; }; }; - rust = mkOption { - type = types.submodule { - imports = [ hookModule ]; - options = { - cargoManifestPath = mkOption { - type = types.nullOr types.str; - description = lib.mdDoc "Path to Cargo.toml"; - default = null; - }; - }; - }; - }; statix = mkOption { type = types.submodule { imports = [ hookModule ]; @@ -1229,31 +1194,31 @@ in type = types.submodule { imports = [ hookModule ]; options = { - package = mkOption { - type = types.package; - description = lib.mdDoc - '' - The `treefmt` package to use. - - Should include all the formatters configured by treefmt. - - For example: - ```nix - pkgs.writeShellApplication { - name = "treefmt"; - runtimeInputs = [ - pkgs.treefmt - pkgs.nixpkgs-fmt - pkgs.black - ]; - text = - ''' - exec treefmt "$@" - '''; - } - ``` - ''; - }; + # package = mkOption { + # type = types.package; + # description = lib.mdDoc + # '' + # The `treefmt` package to use. + # + # Should include all the formatters configured by treefmt. + # + # For example: + # ```nix + # pkgs.writeShellApplication { + # name = "treefmt"; + # runtimeInputs = [ + # pkgs.treefmt + # pkgs.nixpkgs-fmt + # pkgs.black + # ]; + # text = + # ''' + # exec treefmt "$@" + # '''; + # } + # ``` + # ''; + # }; }; }; }; @@ -1458,6 +1423,7 @@ in { name = "alejandra"; description = "The Uncompromising Nix Code Formatter."; + package = tools.alejandra; entry = let cmdArgs = @@ -1772,6 +1738,7 @@ in name = "eclint"; description = "EditorConfig linter written in Go."; types = [ "file" ]; + package = tools.eclint; entry = let cmdArgs = @@ -1841,6 +1808,7 @@ in { name = "flynt"; description = "CLI tool to convert a python project's %-formatted strings to f-strings."; + package = tools.flynt; entry = let cmdArgs = @@ -2174,6 +2142,7 @@ in { name = "mdl"; description = "A tool to check markdown files and flag style issues."; + package = tools.mdl; entry = let cmdArgs = @@ -2698,7 +2667,8 @@ in description = "A markup-aware linter for prose built with speed and extensibility in mind."; entry = let - configFile = builtins.toFile ".vale.ini" "${settings.vale.config}"; + # TODO: was .vale.ini, throwed error in Nix + configFile = builtins.toFile "vale.ini" "${settings.vale.config}"; cmdArgs = mkCmdArgs (with settings.vale; [ diff --git a/nix/default.nix b/nix/default.nix index a50950dd..2e73c5f2 100644 --- a/nix/default.nix +++ b/nix/default.nix @@ -32,7 +32,7 @@ let ../modules/all-modules.nix { inherit tools; - settings.treefmt.package = pkgs.treefmt; + hooks.treefmt.package = pkgs.treefmt; } ]; specialArgs = { inherit pkgs; }; From 94283df0a7d5c49c30d7c3534968221f46bd6c8e Mon Sep 17 00:00:00 2001 From: Sander Date: Sat, 10 Feb 2024 21:06:24 +0000 Subject: [PATCH 03/26] Add placeholder descriptions --- modules/hooks.nix | 43 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) diff --git a/modules/hooks.nix b/modules/hooks.nix index 9d90139b..6fc693ac 100644 --- a/modules/hooks.nix +++ b/modules/hooks.nix @@ -34,6 +34,7 @@ in options.hooks = { alejandra = mkOption { + description = ""; type = types.submodule { imports = [ hookModule ]; options = { @@ -69,6 +70,7 @@ in }; }; ansible-lint = mkOption { + description = ""; type = types.submodule { imports = [ hookModule ]; options = { @@ -88,6 +90,7 @@ in }; }; autoflake = mkOption { + description = ""; type = types.submodule { imports = [ hookModule ]; options = { @@ -111,6 +114,7 @@ in }; }; clippy = mkOption { + description = ""; type = types.submodule { imports = [ hookModule ]; options = { @@ -133,6 +137,7 @@ in }; }; cmake-format = mkOption { + description = ""; type = types.submodule { imports = [ hookModule ]; options = { @@ -146,6 +151,7 @@ in }; }; credo = mkOption { + description = ""; type = types.submodule { imports = [ hookModule ]; options = { @@ -159,6 +165,7 @@ in }; }; deadnix = mkOption { + description = ""; type = types.submodule { imports = [ hookModule ]; options = { @@ -214,6 +221,7 @@ in }; }; denofmt = mkOption { + description = ""; type = types.submodule { imports = [ hookModule ]; options = { @@ -235,6 +243,7 @@ in }; }; denolint = mkOption { + description = ""; type = types.submodule { imports = [ hookModule ]; options = { @@ -257,6 +266,7 @@ in }; }; dune-fmt = mkOption { + description = ""; type = types.submodule { imports = [ hookModule ]; options = { @@ -277,6 +287,7 @@ in }; }; eclint = mkOption { + description = ""; type = types.submodule { imports = [ hookModule ]; options = { @@ -314,6 +325,7 @@ in }; }; eslint = mkOption { + description = ""; type = types.submodule { imports = [ hookModule ]; options = { @@ -337,6 +349,7 @@ in }; }; flake8 = mkOption { + description = ""; type = types.submodule { imports = [ hookModule ]; options = { @@ -366,6 +379,7 @@ in }; }; flynt = mkOption { + description = ""; type = types.submodule { imports = [ hookModule ]; options = { @@ -441,6 +455,7 @@ in }; }; headache = mkOption { + description = ""; type = types.submodule { imports = [ hookModule ]; options = { @@ -453,6 +468,7 @@ in }; }; hlint = mkOption { + description = ""; type = types.submodule { imports = [ hookModule ]; options = { @@ -466,6 +482,7 @@ in }; }; hpack = mkOption { + description = ""; type = types.submodule { imports = [ hookModule ]; options = { @@ -479,6 +496,7 @@ in }; }; isort = mkOption { + description = ""; type = types.submodule { imports = [ hookModule ]; options = { @@ -498,6 +516,7 @@ in }; }; latexindent = mkOption { + description = ""; type = types.submodule { imports = [ hookModule ]; options = { @@ -511,6 +530,7 @@ in }; }; lua-ls = mkOption { + description = ""; type = types.submodule { imports = [ hookModule ]; options = { @@ -530,6 +550,7 @@ in }; }; lychee = mkOption { + description = ""; type = types.submodule { imports = [ hookModule ]; options = { @@ -549,6 +570,7 @@ in }; }; markdownlint = mkOption { + description = ""; type = types.submodule { imports = [ hookModule ]; options = { @@ -563,6 +585,7 @@ in }; }; mdl = mkOption { + description = ""; type = types.submodule { imports = [ hookModule ]; options = { @@ -643,6 +666,7 @@ in }; }; mkdocs-linkcheck = mkOption { + description = ""; type = types.submodule { imports = [ hookModule ]; options = { @@ -694,6 +718,7 @@ in }; }; mypy = mkOption { + description = ""; type = types.submodule { imports = [ hookModule ]; options = { @@ -710,6 +735,7 @@ in }; }; nixfmt = mkOption { + description = ""; type = types.submodule { imports = [ hookModule ]; options = { @@ -723,6 +749,7 @@ in }; }; ormolu = mkOption { + description = ""; type = types.submodule { imports = [ hookModule ]; options = { @@ -742,6 +769,7 @@ in }; }; php-cs-fixer = mkOption { + description = ""; type = types.submodule { imports = [ hookModule ]; options = { @@ -758,6 +786,7 @@ in }; }; phpcbf = mkOption { + description = ""; type = types.submodule { imports = [ hookModule ]; options = { @@ -774,6 +803,7 @@ in }; }; phpcs = mkOption { + description = ""; type = types.submodule { imports = [ hookModule ]; options = { @@ -790,6 +820,7 @@ in }; }; phpstan = mkOption { + description = ""; type = types.submodule { imports = [ hookModule ]; options = { @@ -808,6 +839,7 @@ in # See all CLI flags for prettier [here](https://prettier.io/docs/en/cli.html). # See all options for prettier [here](https://prettier.io/docs/en/options.html). prettier = mkOption { + description = ""; type = types.submodule { imports = [ hookModule ]; options = { @@ -1050,6 +1082,7 @@ in }; }; psalm = mkOption { + description = ""; type = types.submodule { imports = [ hookModule ]; options = { @@ -1066,6 +1099,7 @@ in }; }; pylint = mkOption { + description = ""; type = types.submodule { imports = [ hookModule ]; options = { @@ -1094,6 +1128,7 @@ in }; }; pyright = mkOption { + description = ""; type = types.submodule { imports = [ hookModule ]; options = { @@ -1110,6 +1145,7 @@ in }; }; pyupgrade = mkOption { + description = ""; type = types.submodule { imports = [ hookModule ]; options = { @@ -1126,6 +1162,7 @@ in }; }; revive = mkOption { + description = ""; type = types.submodule { imports = [ hookModule ]; options = { @@ -1141,6 +1178,7 @@ in }; }; rome = mkOption { + description = ""; type = types.submodule { imports = [ hookModule ]; options = { @@ -1170,6 +1208,7 @@ in }; }; statix = mkOption { + description = ""; type = types.submodule { imports = [ hookModule ]; options = { @@ -1191,6 +1230,7 @@ in }; }; treefmt = mkOption { + description = ""; type = types.submodule { imports = [ hookModule ]; options = { @@ -1223,6 +1263,7 @@ in }; }; typos = mkOption { + description = ""; type = types.submodule { imports = [ hookModule ]; options = { @@ -1357,6 +1398,7 @@ in }; }; vale = mkOption { + description = ""; type = types.submodule { imports = [ hookModule ]; options = { @@ -1387,6 +1429,7 @@ in }; }; yamllint = mkOption { + description = ""; type = types.submodule { imports = [ hookModule ]; options = { From 2545f40fa5f08e5acc43e90e9f7f1a0b77eb8601 Mon Sep 17 00:00:00 2001 From: Sander Date: Sat, 10 Feb 2024 21:25:44 +0000 Subject: [PATCH 04/26] Set raw --- modules/hook.nix | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/modules/hook.nix b/modules/hook.nix index 9f78264a..75b82987 100644 --- a/modules/hook.nix +++ b/modules/hook.nix @@ -2,8 +2,11 @@ let - inherit (lib) mkOption types; + inherit (lib) concatStringsSep mkOption types; cfg = config.options; + mergeExcludes = + excludes: + if excludes == [ ] then "^$" else "(${concatStringsSep "|" excludes})"; in { options = { @@ -153,4 +156,14 @@ in ''; }; }; + + config = + { + raw = + { + inherit (config) name entry language files types types_or pass_filenames fail_fast require_serial stages verbose always_run; + id = config.name; + exclude = mergeExcludes config.excludes; + }; + }; } From ce684eb2e56f411e089e0d45b84947846dc15174 Mon Sep 17 00:00:00 2001 From: Sander Date: Sat, 10 Feb 2024 21:29:32 +0000 Subject: [PATCH 05/26] Fix --- modules/hook.nix | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/modules/hook.nix b/modules/hook.nix index 75b82987..78d80c9a 100644 --- a/modules/hook.nix +++ b/modules/hook.nix @@ -1,9 +1,8 @@ { config, name, lib, ... }: - let inherit (lib) concatStringsSep mkOption types; - cfg = config.options; + cfg = config; mergeExcludes = excludes: if excludes == [ ] then "^$" else "(${concatStringsSep "|" excludes})"; From 3d416f0ddc32462a217203ba64496b206d556984 Mon Sep 17 00:00:00 2001 From: Sander Date: Sat, 10 Feb 2024 21:42:33 +0000 Subject: [PATCH 06/26] Pass down default_states to each hook --- modules/hook.nix | 5 +- modules/pre-commit.nix | 155 ++--------------------------------------- 2 files changed, 8 insertions(+), 152 deletions(-) diff --git a/modules/hook.nix b/modules/hook.nix index 78d80c9a..b7dc9a06 100644 --- a/modules/hook.nix +++ b/modules/hook.nix @@ -1,8 +1,7 @@ -{ config, name, lib, ... }: +{ config, name, lib, default_stages, ... }: let inherit (lib) concatStringsSep mkOption types; - cfg = config; mergeExcludes = excludes: if excludes == [ ] then "^$" else "(${concatStringsSep "|" excludes})"; @@ -135,7 +134,7 @@ in description = lib.mdDoc '' Confines the hook to run at a particular stage. ''; - default = cfg.default_stages; + default = default_stages; defaultText = (lib.literalExpression or lib.literalExample) "default_stages"; }; diff --git a/modules/pre-commit.nix b/modules/pre-commit.nix index 3e51d85f..ab65bb3f 100644 --- a/modules/pre-commit.nix +++ b/modules/pre-commit.nix @@ -17,155 +17,12 @@ let cfg = config; install_stages = lib.unique (cfg.default_stages ++ (builtins.concatLists (lib.mapAttrsToList (_: h: h.stages) enabledHooks))); - hookType = types.submodule ( - { config, name, ... }: { - options = { - enable = - mkOption { - type = types.bool; - description = lib.mdDoc "Whether to enable this pre-commit hook."; - default = false; - }; - raw = - mkOption { - type = types.attrsOf types.unspecified; - description = lib.mdDoc - '' - Raw fields of a pre-commit hook. This is mostly for internal use but - exposed in case you need to work around something. - - Default: taken from the other hook options. - ''; - }; - name = - mkOption { - type = types.str; - # default = name; - defaultText = lib.literalMD "internal name, same as `id`"; - description = lib.mdDoc - '' - The name of the hook - shown during hook execution. - ''; - }; - entry = - mkOption { - type = types.str; - description = lib.mdDoc - '' - The entry point - the executable to run. {option}`entry` can also contain arguments that will not be overridden, such as `entry = "autopep8 -i";`. - ''; - }; - language = - mkOption { - type = types.str; - description = lib.mdDoc - '' - The language of the hook - tells pre-commit how to install the hook. - ''; - default = "system"; - }; - files = - mkOption { - type = types.str; - description = lib.mdDoc - '' - The pattern of files to run on. - ''; - default = ""; - }; - types = - mkOption { - type = types.listOf types.str; - description = lib.mdDoc - '' - List of file types to run on. See [Filtering files with types](https://pre-commit.com/#plugins). - ''; - default = [ "file" ]; - }; - types_or = - mkOption { - type = types.listOf types.str; - description = lib.mdDoc - '' - List of file types to run on, where only a single type needs to match. - ''; - default = [ ]; - }; - description = - mkOption { - type = types.str; - description = lib.mdDoc - '' - Description of the hook. used for metadata purposes only. - ''; - default = ""; - }; - excludes = - mkOption { - type = types.listOf types.str; - description = lib.mdDoc - '' - Exclude files that were matched by these patterns. - ''; - default = [ ]; - }; - pass_filenames = - mkOption { - type = types.bool; - description = lib.mdDoc '' - Whether to pass filenames as arguments to the entry point. - ''; - default = true; - }; - fail_fast = mkOption { - type = types.bool; - description = lib.mdDoc '' - if true pre-commit will stop running hooks if this hook fails. - ''; - default = false; - }; - require_serial = mkOption { - type = types.bool; - description = lib.mdDoc '' - if true this hook will execute using a single process instead of in parallel. - ''; - default = false; - }; - stages = - mkOption { - type = types.listOf types.str; - description = lib.mdDoc '' - Confines the hook to run at a particular stage. - ''; - default = cfg.default_stages; - defaultText = (lib.literalExpression or lib.literalExample) "default_stages"; - }; - verbose = mkOption { - type = types.bool; - default = false; - description = lib.mdDoc '' - forces the output of the hook to be printed even when the hook passes. - ''; - }; - always_run = mkOption { - type = types.bool; - default = false; - description = lib.mdDoc '' - if true this hook will run even if there are no matching files. - ''; - }; - }; - config = - { - raw = - { - inherit (config) name entry language files types types_or pass_filenames fail_fast require_serial stages verbose always_run; - id = config.name; - exclude = mergeExcludes config.excludes; - }; - }; - } - ); + hookType = types.submodule { + imports = [ + ({ ... }: { _module.args.default_stages = cfg.default_stages; }) + ./hook.nix + ]; + }; mergeExcludes = excludes: From 3833dfde314828046f89b76255bdb53bdc394045 Mon Sep 17 00:00:00 2001 From: Sander Date: Sat, 10 Feb 2024 21:50:51 +0000 Subject: [PATCH 07/26] Try passing default_stages again --- modules/hooks.nix | 93 +++++++++++++++++++++++++---------------------- 1 file changed, 49 insertions(+), 44 deletions(-) diff --git a/modules/hooks.nix b/modules/hooks.nix index 6fc693ac..ab839267 100644 --- a/modules/hooks.nix +++ b/modules/hooks.nix @@ -4,8 +4,13 @@ let # TODO: rename all uses of settings. with hooks. settings = config.hooks; inherit (lib) mkOption types; + cfg = config; - hookModule = ./hook.nix; + hookModule = + [ + ({ ... }: { _module.args.default_stages = cfg.default_stages; }) + ./hook.nix + ]; cargoManifestPathArg = lib.optionalString @@ -36,7 +41,7 @@ in alejandra = mkOption { description = ""; type = types.submodule { - imports = [ hookModule ]; + imports = hookModule; options = { check = mkOption { @@ -72,7 +77,7 @@ in ansible-lint = mkOption { description = ""; type = types.submodule { - imports = [ hookModule ]; + imports = hookModule; options = { configPath = mkOption { type = types.str; @@ -92,7 +97,7 @@ in autoflake = mkOption { description = ""; type = types.submodule { - imports = [ hookModule ]; + imports = hookModule; options = { binPath = mkOption { @@ -116,7 +121,7 @@ in clippy = mkOption { description = ""; type = types.submodule { - imports = [ hookModule ]; + imports = hookModule; options = { denyWarnings = mkOption { type = types.bool; @@ -139,7 +144,7 @@ in cmake-format = mkOption { description = ""; type = types.submodule { - imports = [ hookModule ]; + imports = hookModule; options = { configPath = mkOption { type = types.str; @@ -153,7 +158,7 @@ in credo = mkOption { description = ""; type = types.submodule { - imports = [ hookModule ]; + imports = hookModule; options = { strict = mkOption { @@ -167,7 +172,7 @@ in deadnix = mkOption { description = ""; type = types.submodule { - imports = [ hookModule ]; + imports = hookModule; options = { edit = mkOption { @@ -223,7 +228,7 @@ in denofmt = mkOption { description = ""; type = types.submodule { - imports = [ hookModule ]; + imports = hookModule; options = { write = mkOption { @@ -245,7 +250,7 @@ in denolint = mkOption { description = ""; type = types.submodule { - imports = [ hookModule ]; + imports = hookModule; options = { format = mkOption { @@ -268,7 +273,7 @@ in dune-fmt = mkOption { description = ""; type = types.submodule { - imports = [ hookModule ]; + imports = hookModule; options = { auto-promote = mkOption { @@ -289,7 +294,7 @@ in eclint = mkOption { description = ""; type = types.submodule { - imports = [ hookModule ]; + imports = hookModule; options = { fix = mkOption { @@ -327,7 +332,7 @@ in eslint = mkOption { description = ""; type = types.submodule { - imports = [ hookModule ]; + imports = hookModule; options = { binPath = mkOption { @@ -351,7 +356,7 @@ in flake8 = mkOption { description = ""; type = types.submodule { - imports = [ hookModule ]; + imports = hookModule; options = { binPath = mkOption { @@ -381,7 +386,7 @@ in flynt = mkOption { description = ""; type = types.submodule { - imports = [ hookModule ]; + imports = hookModule; options = { aggressive = mkOption { @@ -457,7 +462,7 @@ in headache = mkOption { description = ""; type = types.submodule { - imports = [ hookModule ]; + imports = hookModule; options = { header-file = mkOption { type = types.str; @@ -470,7 +475,7 @@ in hlint = mkOption { description = ""; type = types.submodule { - imports = [ hookModule ]; + imports = hookModule; options = { hintFile = mkOption { @@ -484,7 +489,7 @@ in hpack = mkOption { description = ""; type = types.submodule { - imports = [ hookModule ]; + imports = hookModule; options = { silent = mkOption { @@ -498,7 +503,7 @@ in isort = mkOption { description = ""; type = types.submodule { - imports = [ hookModule ]; + imports = hookModule; options = { profile = mkOption { @@ -518,7 +523,7 @@ in latexindent = mkOption { description = ""; type = types.submodule { - imports = [ hookModule ]; + imports = hookModule; options = { flags = mkOption { @@ -532,7 +537,7 @@ in lua-ls = mkOption { description = ""; type = types.submodule { - imports = [ hookModule ]; + imports = hookModule; options = { checklevel = mkOption { type = types.enum [ "Error" "Warning" "Information" "Hint" ]; @@ -552,7 +557,7 @@ in lychee = mkOption { description = ""; type = types.submodule { - imports = [ hookModule ]; + imports = hookModule; options = { configPath = mkOption { @@ -572,7 +577,7 @@ in markdownlint = mkOption { description = ""; type = types.submodule { - imports = [ hookModule ]; + imports = hookModule; options = { config = mkOption { @@ -587,7 +592,7 @@ in mdl = mkOption { description = ""; type = types.submodule { - imports = [ hookModule ]; + imports = hookModule; options = { configPath = mkOption { @@ -668,7 +673,7 @@ in mkdocs-linkcheck = mkOption { description = ""; type = types.submodule { - imports = [ hookModule ]; + imports = hookModule; options = { binPath = mkOption { @@ -720,7 +725,7 @@ in mypy = mkOption { description = ""; type = types.submodule { - imports = [ hookModule ]; + imports = hookModule; options = { binPath = mkOption { @@ -737,7 +742,7 @@ in nixfmt = mkOption { description = ""; type = types.submodule { - imports = [ hookModule ]; + imports = hookModule; options = { width = mkOption { @@ -751,7 +756,7 @@ in ormolu = mkOption { description = ""; type = types.submodule { - imports = [ hookModule ]; + imports = hookModule; options = { defaultExtensions = mkOption { @@ -771,7 +776,7 @@ in php-cs-fixer = mkOption { description = ""; type = types.submodule { - imports = [ hookModule ]; + imports = hookModule; options = { binPath = mkOption { @@ -788,7 +793,7 @@ in phpcbf = mkOption { description = ""; type = types.submodule { - imports = [ hookModule ]; + imports = hookModule; options = { binPath = mkOption { @@ -805,7 +810,7 @@ in phpcs = mkOption { description = ""; type = types.submodule { - imports = [ hookModule ]; + imports = hookModule; options = { binPath = mkOption { @@ -822,7 +827,7 @@ in phpstan = mkOption { description = ""; type = types.submodule { - imports = [ hookModule ]; + imports = hookModule; options = { binPath = mkOption { @@ -841,7 +846,7 @@ in prettier = mkOption { description = ""; type = types.submodule { - imports = [ hookModule ]; + imports = hookModule; options = { binPath = mkOption { @@ -1084,7 +1089,7 @@ in psalm = mkOption { description = ""; type = types.submodule { - imports = [ hookModule ]; + imports = hookModule; options = { binPath = mkOption { @@ -1101,7 +1106,7 @@ in pylint = mkOption { description = ""; type = types.submodule { - imports = [ hookModule ]; + imports = hookModule; options = { binPath = mkOption { @@ -1130,7 +1135,7 @@ in pyright = mkOption { description = ""; type = types.submodule { - imports = [ hookModule ]; + imports = hookModule; options = { binPath = mkOption { @@ -1147,7 +1152,7 @@ in pyupgrade = mkOption { description = ""; type = types.submodule { - imports = [ hookModule ]; + imports = hookModule; options = { binPath = mkOption { @@ -1164,7 +1169,7 @@ in revive = mkOption { description = ""; type = types.submodule { - imports = [ hookModule ]; + imports = hookModule; options = { configPath = mkOption { @@ -1180,7 +1185,7 @@ in rome = mkOption { description = ""; type = types.submodule { - imports = [ hookModule ]; + imports = hookModule; options = { binPath = mkOption { @@ -1210,7 +1215,7 @@ in statix = mkOption { description = ""; type = types.submodule { - imports = [ hookModule ]; + imports = hookModule; options = { format = mkOption { @@ -1232,7 +1237,7 @@ in treefmt = mkOption { description = ""; type = types.submodule { - imports = [ hookModule ]; + imports = hookModule; options = { # package = mkOption { # type = types.package; @@ -1265,7 +1270,7 @@ in typos = mkOption { description = ""; type = types.submodule { - imports = [ hookModule ]; + imports = hookModule; options = { binary = mkOption { @@ -1400,7 +1405,7 @@ in vale = mkOption { description = ""; type = types.submodule { - imports = [ hookModule ]; + imports = hookModule; options = { config = mkOption { @@ -1431,7 +1436,7 @@ in yamllint = mkOption { description = ""; type = types.submodule { - imports = [ hookModule ]; + imports = hookModule; options = { relaxed = mkOption { type = types.bool; From 22d19cf1d647bde40ad67f0bea9baf7f5db4f51d Mon Sep 17 00:00:00 2001 From: Sander Date: Sat, 10 Feb 2024 22:11:09 +0000 Subject: [PATCH 08/26] Rename options --- modules/hooks.nix | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/modules/hooks.nix b/modules/hooks.nix index ab839267..a293bf2a 100644 --- a/modules/hooks.nix +++ b/modules/hooks.nix @@ -3,7 +3,7 @@ let inherit (config) tools; # TODO: rename all uses of settings. with hooks. settings = config.hooks; - inherit (lib) mkOption types; + inherit (lib) mkOption mkRenamedOptionModule types; cfg = config; hookModule = @@ -28,6 +28,10 @@ let in { + imports = + map (o: mkRenamedOptionModule [ "settings" o ] [ "hooks" o ]) + [ "alejandra" "ansible-lint" "autoflake" "clippy" "cmake-format" "credo" "deadnix" "denofmt" "denolint" "dune-fmt" "eclint" "eslint" "flake8" "flynt" "headache" "hlint" "hpack" "isort" "latexindent" "lua-ls" "lychee" "markdownlint" "mdl" "mkdocs-linkcheck" "mypy" "nixfmt" "ormolu" "php-cs-fixer" "phpcbf" "phpcs" "phpstan" "prettier" "psalm" "pylint" "pyright" "pyupgrade" "revive" "rome" "statix" "treefmt" "typos" "vale" "yamllint" ]; + # PLEASE keep this sorted alphabetically. options.settings.rust.cargoManifestPath = mkOption { type = types.nullOr types.str; From bc05acff3c120531130e1e0a9b0c4c9dac254f88 Mon Sep 17 00:00:00 2001 From: Sander Date: Sat, 10 Feb 2024 22:14:32 +0000 Subject: [PATCH 09/26] Make run command backwards-compatible --- nix/run.nix | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/nix/run.nix b/nix/run.nix index 492724fd..a392e8aa 100644 --- a/nix/run.nix +++ b/nix/run.nix @@ -1,6 +1,7 @@ builtinStuff@{ pkgs, tools, isFlakes, pre-commit, git, runCommand, writeText, writeScript, lib, gitignore-nix-src }: { src +, settings ? { } , hooks ? { } , excludes ? [ ] , tools ? { } @@ -17,7 +18,7 @@ let { _module.args.pkgs = pkgs; _module.args.gitignore-nix-src = gitignore-nix-src; - inherit hooks excludes default_stages; + inherit hooks excludes default_stages settings; tools = builtinStuff.tools // tools; package = pre-commit; } // (if isFlakes From 4d53d13ff581737b42491ebc2f9205243d1910cb Mon Sep 17 00:00:00 2001 From: Sander Date: Sat, 10 Feb 2024 22:25:06 +0000 Subject: [PATCH 10/26] Move hook-specific settings under hooks..settings --- modules/hooks.nix | 266 +++++++++++++++++++++++----------------------- 1 file changed, 132 insertions(+), 134 deletions(-) diff --git a/modules/hooks.nix b/modules/hooks.nix index a293bf2a..a68e9f6c 100644 --- a/modules/hooks.nix +++ b/modules/hooks.nix @@ -1,10 +1,10 @@ { config, lib, pkgs, ... }: let inherit (config) tools; - # TODO: rename all uses of settings. with hooks. - settings = config.hooks; - inherit (lib) mkOption mkRenamedOptionModule types; cfg = config; + hooks = config.hooks; + settings = config.settings; + inherit (lib) mkOption mkRenamedOptionModule types; hookModule = [ @@ -14,8 +14,8 @@ let cargoManifestPathArg = lib.optionalString - (config.settings.rust.cargoManifestPath != null) - "--manifest-path ${lib.escapeShellArg config.settings.rust.cargoManifestPath}"; + (settings.rust.cargoManifestPath != null) + "--manifest-path ${lib.escapeShellArg settings.rust.cargoManifestPath}"; mkCmdArgs = predActionList: lib.concatStringsSep @@ -29,7 +29,7 @@ let in { imports = - map (o: mkRenamedOptionModule [ "settings" o ] [ "hooks" o ]) + map (o: mkRenamedOptionModule [ "settings" o ] [ "hooks" o "settings" ]) [ "alejandra" "ansible-lint" "autoflake" "clippy" "cmake-format" "credo" "deadnix" "denofmt" "denolint" "dune-fmt" "eclint" "eslint" "flake8" "flynt" "headache" "hlint" "hpack" "isort" "latexindent" "lua-ls" "lychee" "markdownlint" "mdl" "mkdocs-linkcheck" "mypy" "nixfmt" "ormolu" "php-cs-fixer" "phpcbf" "phpcs" "phpstan" "prettier" "psalm" "pylint" "pyright" "pyupgrade" "revive" "rome" "statix" "treefmt" "typos" "vale" "yamllint" ]; # PLEASE keep this sorted alphabetically. @@ -46,7 +46,7 @@ in description = ""; type = types.submodule { imports = hookModule; - options = { + options.settings = { check = mkOption { type = types.bool; @@ -82,7 +82,7 @@ in description = ""; type = types.submodule { imports = hookModule; - options = { + options.settings = { configPath = mkOption { type = types.str; description = lib.mdDoc "Path to the YAML configuration file."; @@ -102,7 +102,7 @@ in description = ""; type = types.submodule { imports = hookModule; - options = { + options.settings = { binPath = mkOption { type = types.str; @@ -126,7 +126,7 @@ in description = ""; type = types.submodule { imports = hookModule; - options = { + options.settings = { denyWarnings = mkOption { type = types.bool; description = lib.mdDoc "Fail when warnings are present"; @@ -149,7 +149,7 @@ in description = ""; type = types.submodule { imports = hookModule; - options = { + options.settings = { configPath = mkOption { type = types.str; description = lib.mdDoc "Path to the configuration file (.json,.python,.yaml)"; @@ -163,7 +163,7 @@ in description = ""; type = types.submodule { imports = hookModule; - options = { + options.settings = { strict = mkOption { type = types.bool; @@ -177,7 +177,7 @@ in description = ""; type = types.submodule { imports = hookModule; - options = { + options.settings = { edit = mkOption { type = types.bool; @@ -233,7 +233,7 @@ in description = ""; type = types.submodule { imports = hookModule; - options = { + options.settings = { write = mkOption { type = types.bool; @@ -255,7 +255,7 @@ in description = ""; type = types.submodule { imports = hookModule; - options = { + options.settings = { format = mkOption { type = types.enum [ "default" "compact" "json" ]; @@ -278,7 +278,7 @@ in description = ""; type = types.submodule { imports = hookModule; - options = { + options.settings = { auto-promote = mkOption { type = types.bool; @@ -299,7 +299,7 @@ in description = ""; type = types.submodule { imports = hookModule; - options = { + options.settings = { fix = mkOption { type = types.bool; @@ -337,7 +337,7 @@ in description = ""; type = types.submodule { imports = hookModule; - options = { + options.settings = { binPath = mkOption { type = types.path; @@ -361,7 +361,7 @@ in description = ""; type = types.submodule { imports = hookModule; - options = { + options.settings = { binPath = mkOption { type = types.str; @@ -391,7 +391,7 @@ in description = ""; type = types.submodule { imports = hookModule; - options = { + options.settings = { aggressive = mkOption { type = types.bool; @@ -402,8 +402,8 @@ in mkOption { type = types.str; description = lib.mdDoc "flynt binary path. Can be used to specify the flynt binary from an existing Python environment."; - default = "${settings.flynt.package}/bin/flynt"; - defaultText = "\${settings.flynt.package}/bin/flynt"; + default = "${hooks.flynt.package}/bin/flynt"; + defaultText = "\${hooks.flynt.package}/bin/flynt"; }; dry-run = mkOption { @@ -453,13 +453,12 @@ in description = lib.mdDoc "Replace string concatenations with f-strings."; default = false; }; - # TODO: clashes with hook setting - # verbose = - # mkOption { - # type = types.bool; - # description = lib.mdDoc "Run with verbose output."; - # default = false; - # }; + verbose = + mkOption { + type = types.bool; + description = lib.mdDoc "Run with verbose output."; + default = false; + }; }; }; }; @@ -467,7 +466,7 @@ in description = ""; type = types.submodule { imports = hookModule; - options = { + options.settings = { header-file = mkOption { type = types.str; description = lib.mdDoc "Path to the header file."; @@ -480,7 +479,7 @@ in description = ""; type = types.submodule { imports = hookModule; - options = { + options.settings = { hintFile = mkOption { type = types.nullOr types.path; @@ -494,7 +493,7 @@ in description = ""; type = types.submodule { imports = hookModule; - options = { + options.settings = { silent = mkOption { type = types.bool; @@ -508,7 +507,7 @@ in description = ""; type = types.submodule { imports = hookModule; - options = { + options.settings = { profile = mkOption { type = types.enum [ "" "black" "django" "pycharm" "google" "open_stack" "plone" "attrs" "hug" "wemake" "appnexus" ]; @@ -528,7 +527,7 @@ in description = ""; type = types.submodule { imports = hookModule; - options = { + options.settings = { flags = mkOption { type = types.str; @@ -542,7 +541,7 @@ in description = ""; type = types.submodule { imports = hookModule; - options = { + options.settings = { checklevel = mkOption { type = types.enum [ "Error" "Warning" "Information" "Hint" ]; description = lib.mdDoc @@ -562,7 +561,7 @@ in description = ""; type = types.submodule { imports = hookModule; - options = { + options.settings = { configPath = mkOption { type = types.str; @@ -582,7 +581,7 @@ in description = ""; type = types.submodule { imports = hookModule; - options = { + options.settings = { config = mkOption { type = types.attrs; @@ -597,7 +596,7 @@ in description = ""; type = types.submodule { imports = hookModule; - options = { + options.settings = { configPath = mkOption { type = types.str; @@ -664,13 +663,12 @@ in description = lib.mdDoc "Markdown rules to use for linting containing the given tags. Per default all rules are processed."; default = [ ]; }; - # TODO: clases with hook setting - # verbose = - # mkOption { - # type = types.bool; - # description = lib.mdDoc "Increase verbosity."; - # default = false; - # }; + verbose = + mkOption { + type = types.bool; + description = lib.mdDoc "Increase verbosity."; + default = false; + }; }; }; }; @@ -678,7 +676,7 @@ in description = ""; type = types.submodule { imports = hookModule; - options = { + options.settings = { binPath = mkOption { type = types.path; @@ -730,7 +728,7 @@ in description = ""; type = types.submodule { imports = hookModule; - options = { + options.settings = { binPath = mkOption { type = types.str; @@ -747,7 +745,7 @@ in description = ""; type = types.submodule { imports = hookModule; - options = { + options.settings = { width = mkOption { type = types.nullOr types.int; @@ -761,7 +759,7 @@ in description = ""; type = types.submodule { imports = hookModule; - options = { + options.settings = { defaultExtensions = mkOption { type = types.listOf types.str; @@ -781,7 +779,7 @@ in description = ""; type = types.submodule { imports = hookModule; - options = { + options.settings = { binPath = mkOption { type = types.str; @@ -798,7 +796,7 @@ in description = ""; type = types.submodule { imports = hookModule; - options = { + options.settings = { binPath = mkOption { type = types.str; @@ -815,7 +813,7 @@ in description = ""; type = types.submodule { imports = hookModule; - options = { + options.settings = { binPath = mkOption { type = types.str; @@ -832,7 +830,7 @@ in description = ""; type = types.submodule { imports = hookModule; - options = { + options.settings = { binPath = mkOption { type = types.str; @@ -851,7 +849,7 @@ in description = ""; type = types.submodule { imports = hookModule; - options = { + options.settings = { binPath = mkOption { description = lib.mdDoc @@ -1094,7 +1092,7 @@ in description = ""; type = types.submodule { imports = hookModule; - options = { + options.settings = { binPath = mkOption { type = types.str; @@ -1111,7 +1109,7 @@ in description = ""; type = types.submodule { imports = hookModule; - options = { + options.settings = { binPath = mkOption { type = types.str; @@ -1140,7 +1138,7 @@ in description = ""; type = types.submodule { imports = hookModule; - options = { + options.settings = { binPath = mkOption { type = types.str; @@ -1157,7 +1155,7 @@ in description = ""; type = types.submodule { imports = hookModule; - options = { + options.settings = { binPath = mkOption { type = types.str; @@ -1174,7 +1172,7 @@ in description = ""; type = types.submodule { imports = hookModule; - options = { + options.settings = { configPath = mkOption { type = types.str; @@ -1190,7 +1188,7 @@ in description = ""; type = types.submodule { imports = hookModule; - options = { + options.settings = { binPath = mkOption { type = types.path; @@ -1220,7 +1218,7 @@ in description = ""; type = types.submodule { imports = hookModule; - options = { + options.settings = { format = mkOption { type = types.enum [ "stderr" "errfmt" "json" ]; @@ -1242,7 +1240,7 @@ in description = ""; type = types.submodule { imports = hookModule; - options = { + options.settings = { # package = mkOption { # type = types.package; # description = lib.mdDoc @@ -1275,7 +1273,7 @@ in description = ""; type = types.submodule { imports = hookModule; - options = { + options.settings = { binary = mkOption { type = types.bool; @@ -1410,7 +1408,7 @@ in description = ""; type = types.submodule { imports = hookModule; - options = { + options.settings = { config = mkOption { type = types.str; @@ -1441,7 +1439,7 @@ in description = ""; type = types.submodule { imports = hookModule; - options = { + options.settings = { relaxed = mkOption { type = types.bool; description = lib.mdDoc "Whether to use the relaxed configuration."; @@ -1479,7 +1477,7 @@ in entry = let cmdArgs = - mkCmdArgs (with settings.alejandra; [ + mkCmdArgs (with hooks.alejandra.settings; [ [ check "--check" ] [ (exclude != [ ]) "--exclude ${lib.escapeShellArgs (lib.unique exclude)}" ] [ (verbosity == "quiet") "-q" ] @@ -1487,7 +1485,7 @@ in [ (threads != null) "--threads ${toString threads}" ] ]); in - "${settings.alejandra.package}/bin/alejandra ${cmdArgs}"; + "${hooks.alejandra.package}/bin/alejandra ${cmdArgs}"; files = "\\.nix$"; }; annex = @@ -1505,17 +1503,17 @@ in let cmdArgs = mkCmdArgs [ - [ (settings.ansible-lint.configPath != "") "-c ${settings.ansible-lint.configPath}" ] + [ (hooks.ansible-lint.settings.configPath != "") "-c ${hooks.ansible-lint.settings.configPath}" ] ]; in "${tools.ansible-lint}/bin/ansible-lint ${cmdArgs}"; - files = if settings.ansible-lint.subdir != "" then "${settings.ansible-lint.subdir}/" else ""; + files = if hooks.ansible-lint.settings.subdir != "" then "${hooks.ansible-lint.settings.subdir}/" else ""; }; autoflake = { name = "autoflake"; description = "Remove unused imports and variables from Python code."; - entry = "${settings.autoflake.binPath} ${settings.autoflake.flags}"; + entry = "${hooks.autoflake.settings.binPath} ${hooks.autoflake.settings.flags}"; types = [ "python" ]; }; bats = @@ -1621,7 +1619,7 @@ in { name = "clippy"; description = "Lint Rust code."; - entry = "${wrapper}/bin/cargo-clippy clippy ${cargoManifestPathArg} ${lib.optionalString settings.clippy.offline "--offline"} ${lib.optionalString settings.clippy.allFeatures "--all-features"} -- ${lib.optionalString settings.clippy.denyWarnings "-D warnings"}"; + entry = "${wrapper}/bin/cargo-clippy clippy ${cargoManifestPathArg} ${lib.optionalString hooks.clippy.settings.offline "--offline"} ${lib.optionalString hooks.clippy.settings.allFeatures "--all-features"} -- ${lib.optionalString hooks.clippy.settings.denyWarnings "-D warnings"}"; files = "\\.rs$"; pass_filenames = false; }; @@ -1639,10 +1637,10 @@ in entry = let maybeConfigPath = - if settings.cmake-format.configPath == "" + if hooks.cmake-format.settings.configPath == "" # Searches automatically for the config path. then "" - else "-C ${settings.cmake-format.configPath}"; + else "-C ${hooks.cmake-format.settings.configPath}"; in "${tools.cmake-format}/bin/cmake-format --check ${maybeConfigPath}"; files = "\\.cmake$|CMakeLists.txt"; @@ -1681,7 +1679,7 @@ in name = "credo"; description = "Runs a static code analysis using Credo"; entry = - let strict = if settings.credo.strict then "--strict" else ""; + let strict = if hooks.credo.settings.strict then "--strict" else ""; in "${pkgs.elixir}/bin/mix credo"; files = "\\.exs?$"; }; @@ -1704,7 +1702,7 @@ in entry = let cmdArgs = - mkCmdArgs (with settings.deadnix; [ + mkCmdArgs (with hooks.deadnix.settings; [ [ noLambdaArg "--no-lambda-arg" ] [ noLambdaPatternNames "--no-lambda-pattern-names" ] [ noUnderscore "--no-underscore" ] @@ -1726,8 +1724,8 @@ in let cmdArgs = mkCmdArgs [ - [ (!settings.denofmt.write) "--check" ] - [ (settings.denofmt.configPath != "") "-c ${settings.denofmt.configPath}" ] + [ (!hooks.denofmt.settings.write) "--check" ] + [ (hooks.denofmt.settings.configPath != "") "-c ${hooks.denofmt.settings.configPath}" ] ]; in "${tools.deno}/bin/deno fmt ${cmdArgs}"; @@ -1741,9 +1739,9 @@ in let cmdArgs = mkCmdArgs [ - [ (settings.denolint.format == "compact") "--compact" ] - [ (settings.denolint.format == "json") "--json" ] - [ (settings.denolint.configPath != "") "-c ${settings.denolint.configPath}" ] + [ (hooks.denolint.settings.format == "compact") "--compact" ] + [ (hooks.denolint.settings.format == "json") "--json" ] + [ (hooks.denolint.settings.configPath != "") "-c ${hooks.denolint.settings.configPath}" ] ]; in "${tools.deno}/bin/deno lint ${cmdArgs}"; @@ -1765,10 +1763,10 @@ in description = "Runs Dune's formatters on the code tree."; entry = let - auto-promote = if settings.dune-fmt.auto-promote then "--auto-promote" else ""; + auto-promote = if hooks.dune-fmt.settings.auto-promote then "--auto-promote" else ""; run-dune-fmt = pkgs.writeShellApplication { name = "run-dune-fmt"; - runtimeInputs = settings.dune-fmt.extraRuntimeInputs; + runtimeInputs = hooks.dune-fmt.settings.extraRuntimeInputs; text = "${tools.dune-fmt}/bin/dune-fmt ${auto-promote}"; }; in @@ -1795,7 +1793,7 @@ in let cmdArgs = mkCmdArgs - (with settings.eclint; [ + (with hooks.eclint.settings; [ [ fix "-fix" ] [ summary "-summary" ] [ (color != "auto") "-color ${color}" ] @@ -1803,7 +1801,7 @@ in [ (verbosity != 0) "-verbosity ${toString verbosity}" ] ]); in - "${settings.eclint.package}/bin/eclint ${cmdArgs}"; + "${hooks.eclint.package}/bin/eclint ${cmdArgs}"; }; editorconfig-checker = { @@ -1840,20 +1838,20 @@ in { name = "eslint"; description = "Find and fix problems in your JavaScript code."; - entry = "${settings.eslint.binPath} --fix"; - files = "${settings.eslint.extensions}"; + entry = "${hooks.eslint.settings.binPath} --fix"; + files = "${hooks.eslint.settings.extensions}"; }; flake8 = let extendIgnoreStr = - if lib.lists.length settings.flake8.extendIgnore > 0 - then "--extend-ignore " + builtins.concatStringsSep "," settings.flake8.extendIgnore + if lib.lists.length hooks.flake8.settings.extendIgnore > 0 + then "--extend-ignore " + builtins.concatStringsSep "," hooks.flake8.settings.extendIgnore else ""; in { name = "flake8"; description = "Check the style and quality of Python files."; - entry = "${settings.flake8.binPath} --format ${settings.flake8.format} ${extendIgnoreStr}"; + entry = "${hooks.flake8.settings.binPath} --format ${hooks.flake8.settings.format} ${extendIgnoreStr}"; types = [ "python" ]; }; flynt = @@ -1864,7 +1862,7 @@ in entry = let cmdArgs = - mkCmdArgs (with settings.flynt; [ + mkCmdArgs (with hooks.flynt.settings; [ [ aggressive "--aggressive" ] [ dry-run "--dry-run" ] [ (exclude != [ ]) "--exclude ${lib.escapeShellArgs exclude}" ] @@ -1877,7 +1875,7 @@ in [ verbose "--verbose" ] ]); in - "${settings.flynt.binPath} ${cmdArgs}"; + "${hooks.flynt.settings.binPath} ${cmdArgs}"; types = [ "python" ]; }; fourmolu = @@ -1886,7 +1884,7 @@ in 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}" ]) hooks.ormolu.settings.defaultExtensions) }"; files = "\\.l?hs(-boot)?$"; }; @@ -2033,7 +2031,7 @@ in lib.throwIf (tools.headache == null) "The version of nixpkgs used by pre-commit-hooks.nix does not have `ocamlPackages.headache`. Please use a more recent version of nixpkgs." - "${tools.headache}/bin/headache -h ${settings.headache.header-file}"; + "${tools.headache}/bin/headache -h ${hooks.headache.settings.header-file}"; }; hindent = { @@ -2047,7 +2045,7 @@ in name = "hlint"; description = "HLint gives suggestions on how to improve your source code."; - entry = "${tools.hlint}/bin/hlint${if settings.hlint.hintFile == null then "" else " --hint=${settings.hlint.hintFile}"}"; + entry = "${tools.hlint}/bin/hlint${if hooks.hlint.settings.hintFile == null then "" else " --hint=${hooks.hlint.settings.hintFile}"}"; files = "\\.l?hs(-boot)?$"; }; hpack = @@ -2055,7 +2053,7 @@ in name = "hpack"; description = "`hpack` converts package definitions in the hpack format (`package.yaml`) to Cabal files."; - entry = "${tools.hpack-dir}/bin/hpack-dir --${if settings.hpack.silent then "silent" else "verbose"}"; + entry = "${tools.hpack-dir}/bin/hpack-dir --${if hooks.hpack.settings.silent then "silent" else "verbose"}"; files = "(\\.l?hs(-boot)?$)|(\\.cabal$)|((^|/)package\\.yaml$)"; # We don't pass filenames because they can only be misleading. # Indeed, we need to rerun `hpack` in every directory: @@ -2090,11 +2088,11 @@ in let cmdArgs = mkCmdArgs - (with settings.isort; [ + (with hooks.isort.settings; [ [ (profile != "") " --profile ${profile}" ] ]); in - "${tools.isort}/bin/isort${cmdArgs} ${settings.isort.flags}"; + "${tools.isort}/bin/isort${cmdArgs} ${hooks.isort.settings.flags}"; }; juliaformatter = { @@ -2121,13 +2119,13 @@ in name = "latexindent"; description = "Perl script to add indentation to LaTeX files."; types = [ "file" "tex" ]; - entry = "${tools.latexindent}/bin/latexindent ${settings.latexindent.flags}"; + entry = "${tools.latexindent}/bin/latexindent ${hooks.latexindent.settings.flags}"; }; lua-ls = let # .luarc.json has to be in a directory, # or lua-language-server will hang forever. - luarc = pkgs.writeText ".luarc.json" (builtins.toJSON settings.lua-ls.config); + luarc = pkgs.writeText ".luarc.json" (builtins.toJSON hooks.lua-ls.settings.config); luarc-dir = pkgs.stdenv.mkDerivation { name = "luarc"; unpackPhase = "true"; @@ -2144,7 +2142,7 @@ in set -e export logpath="$(mktemp -d)" lua-language-server --check $(realpath .) \ - --checklevel="${settings.lua-ls.checklevel}" \ + --checklevel="${hooks.lua-ls.settings.checklevel}" \ --configpath="${luarc-dir}/.luarc.json" \ --logpath="$logpath" if [[ -f $logpath/check.json ]]; then @@ -2176,18 +2174,18 @@ in let cmdArgs = mkCmdArgs - (with settings.lychee; [ + (with hooks.lychee.settings; [ [ (configPath != "") " --config ${configPath}" ] ]); in - "${pkgs.lychee}/bin/lychee${cmdArgs} ${settings.lychee.flags}"; + "${pkgs.lychee}/bin/lychee${cmdArgs} ${hooks.lychee.settings.flags}"; types = [ "text" ]; }; markdownlint = { name = "markdownlint"; description = "Style checker and linter for markdown files."; - entry = "${tools.markdownlint-cli}/bin/markdownlint -c ${pkgs.writeText "markdownlint.json" (builtins.toJSON settings.markdownlint.config)}"; + entry = "${tools.markdownlint-cli}/bin/markdownlint -c ${pkgs.writeText "markdownlint.json" (builtins.toJSON hooks.markdownlint.settings.config)}"; files = "\\.md$"; }; mdl = @@ -2199,7 +2197,7 @@ in let cmdArgs = mkCmdArgs - (with settings.mdl; [ + (with hooks.mdl.settings; [ [ (configPath != "") "--config ${configPath}" ] [ git-recurse "--git-recurse" ] [ ignore-front-matter "--ignore-front-matter" ] @@ -2214,7 +2212,7 @@ in [ verbose "--verbose" ] ]); in - "${settings.mdl.package}/bin/mdl ${cmdArgs}"; + "${hooks.mdl.package}/bin/mdl ${cmdArgs}"; files = "\\.md$"; }; mdsh = @@ -2250,7 +2248,7 @@ in let cmdArgs = mkCmdArgs - (with settings.mkdocs-linkcheck; [ + (with hooks.mkdocs-linkcheck.settings; [ [ local-only " --local" ] [ recurse " --recurse" ] [ (extension != "") " --ext ${extension}" ] @@ -2258,14 +2256,14 @@ in [ (path != "") " ${path}" ] ]); in - "${settings.mkdocs-linkcheck.binPath}${cmdArgs}"; + "${hooks.mkdocs-linkcheck.settings.binPath}${cmdArgs}"; types = [ "text" "markdown" ]; }; mypy = { name = "mypy"; description = "Static type checker for Python"; - entry = settings.mypy.binPath; + entry = hooks.mypy.settings.binPath; files = "\\.py$"; }; nil = @@ -2298,7 +2296,7 @@ in { name = "nixfmt"; description = "Nix code prettifier."; - entry = "${tools.nixfmt}/bin/nixfmt ${lib.optionalString (settings.nixfmt.width != null) "--width=${toString settings.nixfmt.width}"}"; + entry = "${tools.nixfmt}/bin/nixfmt ${lib.optionalString (hooks.nixfmt.settings.width != null) "--width=${toString hooks.nixfmt.settings.width}"}"; files = "\\.nix$"; }; nixpkgs-fmt = @@ -2329,9 +2327,9 @@ in entry = let extensions = - lib.escapeShellArgs (lib.concatMap (ext: [ "--ghc-opt" "-X${ext}" ]) settings.ormolu.defaultExtensions); + lib.escapeShellArgs (lib.concatMap (ext: [ "--ghc-opt" "-X${ext}" ]) hooks.ormolu.settings.defaultExtensions); cabalExtensions = - if settings.ormolu.cabalDefaultExtensions then "--cabal-default-extensions" else ""; + if hooks.ormolu.settings.cabalDefaultExtensions then "--cabal-default-extensions" else ""; in "${tools.ormolu}/bin/ormolu --mode inplace ${extensions} ${cabalExtensions}"; files = "\\.l?hs(-boot)?$"; @@ -2340,7 +2338,7 @@ in { name = "php-cs-fixer"; description = "Lint PHP files."; - entry = with settings.php-cs-fixer; + entry = with hooks.php-cs-fixer.settings; "${binPath} fix"; types = [ "php" ]; }; @@ -2348,7 +2346,7 @@ in { name = "phpcbf"; description = "Lint PHP files."; - entry = with settings.phpcbf; + entry = with hooks.phpcbf.settings; "${binPath}"; types = [ "php" ]; }; @@ -2356,7 +2354,7 @@ in { name = "phpcs"; description = "Lint PHP files."; - entry = with settings.phpcs; + entry = with hooks.phpcs.settings; "${binPath}"; types = [ "php" ]; }; @@ -2364,7 +2362,7 @@ in { name = "phpstan"; description = "Static Analysis of PHP files."; - entry = with settings.phpstan; + entry = with hooks.phpstan.settings; "${binPath} analyse"; types = [ "php" ]; }; @@ -2393,7 +2391,7 @@ in let cmdArgs = mkCmdArgs - (with settings.prettier; [ + (with hooks.prettier.settings; [ [ (allow-parens != "always") "--allow-parens ${allow-parens}" ] [ bracket-same-line "--bracket-same-line" ] [ cache "--cache" ] @@ -2433,13 +2431,13 @@ in [ write "--write" ] ]); in - "${settings.prettier.binPath} ${cmdArgs}"; + "${hooks.prettier.settings.binPath} ${cmdArgs}"; }; psalm = { name = "psalm"; description = "Static Analysis of PHP files."; - entry = with settings.psalm; + entry = with hooks.psalm.settings; "${binPath}"; types = [ "php" ]; }; @@ -2461,7 +2459,7 @@ in { name = "pylint"; description = "Lint Python files."; - entry = with settings.pylint; + entry = with hooks.pylint.settings; "${binPath} ${lib.optionalString reports "-ry"} ${lib.optionalString (! score) "-sn"}"; types = [ "python" ]; }; @@ -2469,14 +2467,14 @@ in { name = "pyright"; description = "Static type checker for Python"; - entry = settings.pyright.binPath; + entry = hooks.pyright.settings.binPath; files = "\\.py$"; }; pyupgrade = { name = "pyupgrade"; description = "Automatically upgrade syntax for newer versions."; - entry = with settings.pyupgrade; + entry = with hooks.pyupgrade.settings; "${binPath}"; types = [ "python" ]; }; @@ -2489,7 +2487,7 @@ in cmdArgs = mkCmdArgs [ [ true "-set_exit_status" ] - [ (settings.revive.configPath != "") "-config ${settings.revive.configPath}" ] + [ (hooks.revive.settings.configPath != "") "-config ${hooks.revive.settings.configPath}" ] ]; # revive works with both files and directories; however some lints # may fail (e.g. package-comment) if they run on an individual file @@ -2517,11 +2515,11 @@ in let cmdArgs = mkCmdArgs [ - [ (settings.rome.write) "--apply" ] - [ (settings.rome.configPath != "") "--config-path ${settings.rome.configPath}" ] + [ (hooks.rome.settings.write) "--apply" ] + [ (hooks.rome.settings.configPath != "") "--config-path ${hooks.rome.settings.configPath}" ] ]; in - "${settings.rome.binPath} check ${cmdArgs}"; + "${hooks.rome.settings.binPath} check ${cmdArgs}"; }; ruff = { @@ -2592,7 +2590,7 @@ in { name = "statix"; description = "Lints and suggestions for the Nix programming language."; - entry = with settings.statix; + entry = with hooks.statix.settings; "${tools.statix}/bin/statix check -o ${format} ${if (ignore != [ ]) then "-i ${lib.escapeShellArgs (lib.unique ignore)}" else ""}"; files = "\\.nix$"; pass_filenames = false; @@ -2674,7 +2672,7 @@ in description = "One CLI to format the code tree."; types = [ "file" ]; pass_filenames = true; - entry = "${settings.treefmt.package}/bin/treefmt --fail-on-change"; + entry = "${hooks.treefmt.package}/bin/treefmt --fail-on-change"; }; typos = { @@ -2683,11 +2681,11 @@ in entry = let # Concatenate config in config file with section for ignoring words generated from list of words to ignore - config = "${settings.typos.config}" + lib.strings.optionalString (settings.typos.ignored-words != [ ]) "\n\[default.extend-words\]" + lib.strings.concatMapStrings (x: "\n${x} = \"${x}\"") settings.typos.ignored-words; + config = "${hooks.typos.settings.config}" + lib.strings.optionalString (hooks.typos.settings.ignored-words != [ ]) "\n\[default.extend-words\]" + lib.strings.concatMapStrings (x: "\n${x} = \"${x}\"") hooks.typos.settings.ignored-words; configFile = builtins.toFile "typos-config.toml" config; cmdArgs = mkCmdArgs - (with settings.typos; [ + (with hooks.typos.settings; [ [ binary "--binary" ] [ (color != "auto") "--color ${color}" ] [ (config != "") "--config ${configFile}" ] @@ -2720,15 +2718,15 @@ in entry = let # TODO: was .vale.ini, throwed error in Nix - configFile = builtins.toFile "vale.ini" "${settings.vale.config}"; + configFile = builtins.toFile "vale.ini" "${hooks.vale.settings.config}"; cmdArgs = mkCmdArgs - (with settings.vale; [ + (with hooks.vale.settings; [ [ (configPath != "") " --config ${configPath}" ] [ (config != "" && configPath == "") " --config ${configFile}" ] ]); in - "${pkgs.vale}/bin/vale${cmdArgs} ${settings.vale.flags}"; + "${pkgs.vale}/bin/vale${cmdArgs} ${hooks.vale.settings.flags}"; types = [ "text" ]; }; yamllint = @@ -2740,8 +2738,8 @@ in let cmdArgs = mkCmdArgs [ - [ (settings.yamllint.relaxed) "-d relaxed" ] - [ (settings.yamllint.configPath != "") "-c ${settings.yamllint.configPath}" ] + [ (hooks.yamllint.settings.relaxed) "-d relaxed" ] + [ (hooks.yamllint.settings.configPath != "") "-c ${hooks.yamllint.settings.configPath}" ] ]; in "${tools.yamllint}/bin/yamllint ${cmdArgs}"; From de16d2f6c625a5aa18599e76af09ed2f539fb97f Mon Sep 17 00:00:00 2001 From: Sander Date: Sat, 10 Feb 2024 22:55:40 +0000 Subject: [PATCH 11/26] Add package to raw config --- modules/hook.nix | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/modules/hook.nix b/modules/hook.nix index b7dc9a06..739e6683 100644 --- a/modules/hook.nix +++ b/modules/hook.nix @@ -155,13 +155,12 @@ in }; }; - config = - { - raw = - { - inherit (config) name entry language files types types_or pass_filenames fail_fast require_serial stages verbose always_run; - id = config.name; - exclude = mergeExcludes config.excludes; - }; - }; + config = { + raw = + { + inherit (config) name package entry language files types types_or pass_filenames fail_fast require_serial stages verbose always_run; + id = config.name; + exclude = mergeExcludes config.excludes; + }; + }; } From 27f30f03f58e21d4aa2efc08af5fae27697c5dee Mon Sep 17 00:00:00 2001 From: Sander Date: Sat, 10 Feb 2024 23:03:51 +0000 Subject: [PATCH 12/26] Add default packages --- modules/hooks.nix | 326 +++++++++++++++++++++++++++++++--------------- nix/run.nix | 1 + nix/tools.nix | 6 + 3 files changed, 227 insertions(+), 106 deletions(-) diff --git a/modules/hooks.nix b/modules/hooks.nix index a68e9f6c..8b5fc9ce 100644 --- a/modules/hooks.nix +++ b/modules/hooks.nix @@ -4,7 +4,7 @@ let cfg = config; hooks = config.hooks; settings = config.settings; - inherit (lib) mkOption mkRenamedOptionModule types; + inherit (lib) mkDefault mkOption mkRenamedOptionModule types; hookModule = [ @@ -1464,15 +1464,16 @@ in actionlint = { name = "actionlint"; - description = "Static checker for GitHub Actions workflow files."; + description = "Static checker for GitHub Actions workflow files"; files = "^.github/workflows/"; types = [ "yaml" ]; - entry = "${tools.actionlint}/bin/actionlint"; + package = tools.actionlint; + entry = "${hooks.actionlint.package}/bin/actionlint"; }; alejandra = { name = "alejandra"; - description = "The Uncompromising Nix Code Formatter."; + description = "The Uncompromising Nix Code Formatter"; package = tools.alejandra; entry = let @@ -1492,13 +1493,13 @@ in { name = "annex"; description = "Runs the git-annex hook for large file support"; - entry = "${tools.git-annex}/bin/git-annex pre-commit"; + package = tools.git-annex; + entry = "${hooks.git-annex.package}/bin/git-annex pre-commit"; }; ansible-lint = { name = "ansible-lint"; - description = - "Ansible linter."; + description = "Ansible linter"; entry = let cmdArgs = @@ -1512,78 +1513,89 @@ in autoflake = { name = "autoflake"; - description = "Remove unused imports and variables from Python code."; + description = "Remove unused imports and variables from Python code"; + # TODO: unused. see binPath. + package = tools.autoflake; entry = "${hooks.autoflake.settings.binPath} ${hooks.autoflake.settings.flags}"; types = [ "python" ]; }; bats = { name = "bats"; - description = "Run bash unit tests."; + description = "Run bash unit tests"; types = [ "shell" ]; types_or = [ "bats" "bash" ]; - entry = "${tools.bats}/bin/bats -p"; + package = tools.bats; + entry = "${hooks.bats.package}/bin/bats -p"; }; beautysh = { name = "beautysh"; - description = "Format shell files."; + description = "Format shell files"; types = [ "shell" ]; - entry = "${tools.beautysh}/bin/beautysh"; + package = tools.beautysh; + entry = "${hooks.beautysh.package}/bin/beautysh"; }; black = { name = "black"; - description = "The uncompromising Python code formatter."; - entry = "${tools.black}/bin/black"; + description = "The uncompromising Python code formatter"; + package = tools.black; + entry = "${hooks.black.package}/bin/black"; types = [ "file" "python" ]; }; cabal-fmt = { name = "cabal-fmt"; description = "Format Cabal files"; - entry = "${tools.cabal-fmt}/bin/cabal-fmt --inplace"; + package = tools.cabal-fmt; + entry = "${hooks.cabal-fmt.package}/bin/cabal-fmt --inplace"; files = "\\.cabal$"; }; cabal2nix = { name = "cabal2nix"; - description = "Run `cabal2nix` on all `*.cabal` files to generate corresponding `default.nix` files."; + description = "Run `cabal2nix` on all `*.cabal` files to generate corresponding `default.nix` files"; + package = tools.cabal2nix; + entry = "${hooks.cabal2nix-dir.package}/bin/cabal2nix-dir"; files = "\\.cabal$"; - entry = "${tools.cabal2nix-dir}/bin/cabal2nix-dir"; }; cargo-check = { name = "cargo-check"; - description = "Check the cargo package for errors."; - entry = "${tools.cargo}/bin/cargo check ${cargoManifestPathArg}"; + description = "Check the cargo package for errors"; + package = tools.cargo; + entry = "${hooks.cargo.package}/bin/cargo check ${cargoManifestPathArg}"; files = "\\.rs$"; pass_filenames = false; }; checkmake = { name = "checkmake"; - description = "Experimental linter/analyzer for Makefiles."; + description = "Experimental linter/analyzer for Makefiles"; types = [ "makefile" ]; + package = tools.checkmake; entry = ## NOTE: `checkmake` 0.2.2 landed in nixpkgs on 12 April 2023. Once ## this gets into a NixOS release, the following code will be useless. lib.throwIf - (tools.checkmake == null) + (hooks.checkmake.package == null) "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"; + "${hooks.checkmake.package}/bin/checkmake"; }; chktex = { name = "chktex"; description = "LaTeX semantic checker"; types = [ "file" "tex" ]; - entry = "${tools.chktex}/bin/chktex"; + package = tools.chktex; + entry = "${hooks.chktex.package}/bin/chktex"; }; clang-format = { name = "clang-format"; description = "Format your code using `clang-format`."; - entry = "${tools.clang-tools}/bin/clang-format -style=file -i"; + package = tools.clang-tools; + entry = "${hooks.clang-tools.package}/bin/clang-format -style=file -i"; # Source: # https://github.com/pre-commit/mirrors-clang-format/blob/46516e8f532c8f2d55e801c34a740ebb8036365c/.pre-commit-hooks.yaml types_or = [ @@ -1601,7 +1613,8 @@ in clang-tidy = { name = "clang-tidy"; description = "Static analyzer for C++ code."; - entry = "${tools.clang-tools}/bin/clang-tidy --fix"; + package = tools.clang-tools; + entry = "${hooks.clang-tools.package}/bin/clang-tidy --fix"; types = [ "c" "c++" "c#" "objective-c" ]; }; clippy = @@ -1619,7 +1632,8 @@ in { name = "clippy"; description = "Lint Rust code."; - entry = "${wrapper}/bin/cargo-clippy clippy ${cargoManifestPathArg} ${lib.optionalString hooks.clippy.settings.offline "--offline"} ${lib.optionalString hooks.clippy.settings.allFeatures "--all-features"} -- ${lib.optionalString hooks.clippy.settings.denyWarnings "-D warnings"}"; + package = wrapper; + entry = "${hooks.clippy.package}/bin/cargo-clippy clippy ${cargoManifestPathArg} ${lib.optionalString hooks.clippy.settings.offline "--offline"} ${lib.optionalString hooks.clippy.settings.allFeatures "--all-features"} -- ${lib.optionalString hooks.clippy.settings.denyWarnings "-D warnings"}"; files = "\\.rs$"; pass_filenames = false; }; @@ -1627,13 +1641,15 @@ in { name = "cljfmt"; description = "A tool for formatting Clojure code."; - entry = "${tools.cljfmt}/bin/cljfmt fix"; + package = tools.cljfmt; + entry = "${hooks.cljfmt.package}/bin/cljfmt fix"; types_or = [ "clojure" "clojurescript" "edn" ]; }; cmake-format = { name = "cmake-format"; description = "A tool for formatting CMake-files."; + package = tools.cmake-format; entry = let maybeConfigPath = @@ -1642,7 +1658,7 @@ in then "" else "-C ${hooks.cmake-format.settings.configPath}"; in - "${tools.cmake-format}/bin/cmake-format --check ${maybeConfigPath}"; + "${hooks.cmake-format.package}/bin/cmake-format --check ${maybeConfigPath}"; files = "\\.cmake$|CMakeLists.txt"; }; commitizen = @@ -1651,26 +1667,30 @@ in description = '' Check whether the current commit message follows committing rules. ''; - entry = "${tools.commitizen}/bin/cz check --allow-abort --commit-msg-file"; + package = tools.commitizen; + entry = "${hooks.commitizen.package}/bin/cz check --allow-abort --commit-msg-file"; stages = [ "commit-msg" ]; }; conform = { name = "conform enforce"; description = "Policy enforcement for commits."; - entry = "${tools.conform}/bin/conform enforce --commit-msg-file"; + package = tools.conform; + entry = "${hooks.conform.package}/bin/conform enforce --commit-msg-file"; stages = [ "commit-msg" ]; }; convco = { name = "convco"; + package = tools.convco; entry = let + convco = hooks.convco.package; script = pkgs.writeShellScript "precommit-convco" '' - cat $1 | ${pkgs.convco}/bin/convco check --from-stdin + cat $1 | ${convco}/bin/convco check --from-stdin ''; # need version >= 0.4.0 for the --from-stdin flag - toolVersionCheck = lib.versionAtLeast tools.convco.version "0.4.0"; + toolVersionCheck = lib.versionAtLeast convco.version "0.4.0"; in - lib.throwIf (tools.convco == null || !toolVersionCheck) "The version of Nixpkgs used by pre-commit-hooks.nix does not have the `convco` package (>=0.4.0). Please use a more recent version of Nixpkgs." + lib.throwIf (convco == null || !toolVersionCheck) "The version of Nixpkgs used by pre-commit-hooks.nix does not have the `convco` package (>=0.4.0). Please use a more recent version of Nixpkgs." builtins.toString script; stages = [ "commit-msg" ]; @@ -1678,27 +1698,31 @@ in credo = { name = "credo"; description = "Runs a static code analysis using Credo"; + package = tools.elixir; entry = let strict = if hooks.credo.settings.strict then "--strict" else ""; - in "${pkgs.elixir}/bin/mix credo"; + in "${hooks.credo.package}/bin/mix credo ${strict}"; files = "\\.exs?$"; }; crystal = { name = "crystal"; description = "A tool that automatically formats Crystal source code"; - entry = "${tools.crystal}/bin/crystal tool format"; + package = tools.crystal; + entry = "${hooks.crystal.package}/bin/crystal tool format"; files = "\\.cr$"; }; cspell = { name = "cspell"; description = "A Spell Checker for Code"; - entry = "${tools.cspell}/bin/cspell"; + package = tools.cspell; + entry = "${hooks.cspell.package}/bin/cspell"; }; deadnix = { name = "deadnix"; description = "Scan Nix files for dead code (unused variable bindings)."; + package = tools.deadnix; entry = let cmdArgs = @@ -1712,7 +1736,7 @@ in [ (exclude != [ ]) "--exclude ${lib.escapeShellArgs exclude}" ] ]); in - "${tools.deadnix}/bin/deadnix ${cmdArgs} --fail"; + "${hooks.deadnix.package}/bin/deadnix ${cmdArgs} --fail"; files = "\\.nix$"; }; denofmt = @@ -1720,6 +1744,7 @@ in name = "denofmt"; description = "Auto-format JavaScript, TypeScript, Markdown, and JSON files."; types_or = [ "javascript" "jsx" "ts" "tsx" "markdown" "json" ]; + package = tools.deno; entry = let cmdArgs = @@ -1728,13 +1753,14 @@ in [ (hooks.denofmt.settings.configPath != "") "-c ${hooks.denofmt.settings.configPath}" ] ]; in - "${tools.deno}/bin/deno fmt ${cmdArgs}"; + "${hooks.deno.package}/bin/deno fmt ${cmdArgs}"; }; denolint = { name = "denolint"; description = "Lint JavaScript/TypeScript source code."; types_or = [ "javascript" "jsx" "ts" "tsx" ]; + package = tools.deno; entry = let cmdArgs = @@ -1744,30 +1770,33 @@ in [ (hooks.denolint.settings.configPath != "") "-c ${hooks.denolint.settings.configPath}" ] ]; in - "${tools.deno}/bin/deno lint ${cmdArgs}"; + "${hooks.deno.package}/bin/deno lint ${cmdArgs}"; }; dhall-format = { name = "dhall-format"; description = "Dhall code formatter."; - entry = "${tools.dhall}/bin/dhall format"; + package = tools.dhall; + entry = "${hooks.dhall.package}/bin/dhall format"; files = "\\.dhall$"; }; dialyzer = { name = "dialyzer"; description = "Runs a static code analysis using Dialyzer"; - entry = "${tools.elixir}/bin/mix dialyzer"; + package = tools.elixir; + entry = "${hooks.elixir.package}/bin/mix dialyzer"; files = "\\.exs?$"; }; dune-fmt = { name = "dune-fmt"; description = "Runs Dune's formatters on the code tree."; + package = tools.dune; entry = let auto-promote = if hooks.dune-fmt.settings.auto-promote then "--auto-promote" else ""; run-dune-fmt = pkgs.writeShellApplication { name = "run-dune-fmt"; runtimeInputs = hooks.dune-fmt.settings.extraRuntimeInputs; - text = "${tools.dune-fmt}/bin/dune-fmt ${auto-promote}"; + text = "${hooks.dune-fmt.package}/bin/dune-fmt ${auto-promote}"; }; in "${run-dune-fmt}/bin/run-dune-fmt"; @@ -1776,7 +1805,8 @@ in dune-opam-sync = { name = "dune/opam sync"; description = "Check that Dune-generated OPAM files are in sync."; - entry = "${tools.dune-build-opam-files}/bin/dune-build-opam-files"; + package = tools.dune; + entry = "${hooks.dune-build-opam-files.package}/bin/dune-build-opam-files"; files = "(\\.opam$)|(\\.opam.template$)|((^|/)dune-project$)"; ## We don't pass filenames because they can only be misleading. Indeed, ## we need to re-run `dune build` for every `*.opam` file, but also when @@ -1807,22 +1837,24 @@ in { name = "editorconfig-checker"; description = "Verify that the files are in harmony with the `.editorconfig`."; - entry = "${tools.editorconfig-checker}/bin/editorconfig-checker"; + package = tools.editorconfig-checker; + entry = "${hooks.editorconfig-checker.package}/bin/editorconfig-checker"; types = [ "file" ]; }; elm-format = { name = "elm-format"; description = "Format Elm files."; - entry = - "${tools.elm-format}/bin/elm-format --yes --elm-version=0.19"; + package = tools.elm-format; + entry = "${hooks.elm-format.package}/bin/elm-format --yes --elm-version=0.19"; files = "\\.elm$"; }; elm-review = { name = "elm-review"; description = "Analyzes Elm projects, to help find mistakes before your users find them."; - entry = "${tools.elm-review}/bin/elm-review"; + package = tools.elm-review; + entry = "${hooks.elm-review.package}/bin/elm-review"; files = "\\.elm$"; pass_filenames = false; }; @@ -1830,7 +1862,8 @@ in { name = "elm-test"; description = "Run unit tests and fuzz tests for Elm code."; - entry = "${tools.elm-test}/bin/elm-test"; + package = tools.elm-test; + entry = "${hooks.elm-test.package}/bin/elm-test"; files = "\\.elm$"; pass_filenames = false; }; @@ -1838,6 +1871,8 @@ in { name = "eslint"; description = "Find and fix problems in your JavaScript code."; + # TODO: unused. see binPath. + package = tools.eslint; entry = "${hooks.eslint.settings.binPath} --fix"; files = "${hooks.eslint.settings.extensions}"; }; @@ -1851,6 +1886,8 @@ in { name = "flake8"; description = "Check the style and quality of Python files."; + # unused. see binPath. + package = tools.flake8; entry = "${hooks.flake8.settings.binPath} --format ${hooks.flake8.settings.format} ${extendIgnoreStr}"; types = [ "python" ]; }; @@ -1858,6 +1895,7 @@ in { name = "flynt"; description = "CLI tool to convert a python project's %-formatted strings to f-strings."; + # unused. see binPath. package = tools.flynt; entry = let @@ -1882,8 +1920,9 @@ in { name = "fourmolu"; description = "Haskell code prettifier."; + package = tools.fourmolu; entry = - "${tools.fourmolu}/bin/fourmolu --mode inplace ${ + "${hooks.fourmolu.package}/bin/fourmolu --mode inplace ${ lib.escapeShellArgs (lib.concatMap (ext: [ "--ghc-opt" "-X${ext}" ]) hooks.ormolu.settings.defaultExtensions) }"; files = "\\.l?hs(-boot)?$"; @@ -1892,12 +1931,14 @@ in name = "fprettify"; description = "Auto-formatter for modern Fortran code."; types = [ "fortran " ]; - entry = "${tools.fprettify}/bin/fprettify"; + package = tools.fprettify; + entry = "${hooks.fprettify.package}/bin/fprettify"; }; gofmt = { name = "gofmt"; description = "A tool that automatically formats Go source code"; + package = tools.go; entry = let script = pkgs.writeShellScript "precommit-gofmt" '' @@ -1905,7 +1946,7 @@ in failed=false for file in "$@"; do # redirect stderr so that violations and summaries are properly interleaved. - if ! ${tools.go}/bin/gofmt -l -w "$file" 2>&1 + if ! ${hooks.go.package}/bin/gofmt -l -w "$file" 2>&1 then failed=true fi @@ -1921,12 +1962,13 @@ in golangci-lint = { name = "golangci-lint"; description = "Fast linters runner for Go."; + package = tools.golangci-lint; entry = let script = pkgs.writeShellScript "precommit-golangci-lint" '' set -e for dir in $(echo "$@" | xargs -n1 dirname | sort -u); do - ${tools.golangci-lint}/bin/golangci-lint run ./"$dir" + ${hooks.golangci-lint.package}/bin/golangci-lint run ./"$dir" done ''; in @@ -1939,6 +1981,7 @@ in gotest = { name = "gotest"; description = "Run go tests"; + package = tools.go; entry = let script = pkgs.writeShellScript "precommit-gotest" '' @@ -1966,7 +2009,7 @@ in # test each directory one by one for dir in "''${sorted_dirs[@]}"; do - ${tools.go}/bin/go test "./$dir" + ${hooks.go.package}/bin/go test "./$dir" done ''; in @@ -1980,13 +2023,14 @@ in { name = "govet"; description = "Checks correctness of Go programs."; + package = tools.go; entry = let # go vet requires package (directory) names as inputs. script = pkgs.writeShellScript "precommit-govet" '' set -e for dir in $(echo "$@" | xargs -n1 dirname | sort -u); do - ${tools.go}/bin/go vet ./"$dir" + ${hooks.go.package}/bin/go vet ./"$dir" done ''; in @@ -1999,10 +2043,11 @@ in gptcommit = { name = "gptcommit"; description = "Generate a commit message using GPT3."; + package = tools.gptcommit; entry = let script = pkgs.writeShellScript "precommit-gptcomit" '' - ${tools.gptcommit}/bin/gptcommit prepare-commit-msg --commit-source \ + ${hooks.gptcommit.package}/bin/gptcommit prepare-commit-msg --commit-source \ "$PRE_COMMIT_COMMIT_MSG_SOURCE" --commit-msg-file "$1" ''; in @@ -2015,7 +2060,8 @@ in { name = "hadolint"; description = "Dockerfile linter, validate inline bash."; - entry = "${tools.hadolint}/bin/hadolint"; + package = tools.hadolint; + entry = "${hooks.hadolint.package}/bin/hadolint"; files = "Dockerfile$"; }; headache = @@ -2025,35 +2071,37 @@ in ## NOTE: Supported `files` are taken from ## https://github.com/Frama-C/headache/blob/master/config_builtin.txt files = "(\\.ml[ily]?$)|(\\.fmli?$)|(\\.[chy]$)|(\\.tex$)|(Makefile)|(README)|(LICENSE)"; + package = tools.headache; entry = ## NOTE: `headache` made into in nixpkgs on 12 April 2023. At the ## next NixOS release, the following code will become irrelevant. lib.throwIf - (tools.headache == null) + (hooks.headache.package == null) "The version of nixpkgs used by pre-commit-hooks.nix does not have `ocamlPackages.headache`. Please use a more recent version of nixpkgs." - "${tools.headache}/bin/headache -h ${hooks.headache.settings.header-file}"; + "${hooks.headache.package}/bin/headache -h ${hooks.headache.settings.header-file}"; }; hindent = { name = "hindent"; description = "Haskell code prettifier."; - entry = "${tools.hindent}/bin/hindent"; + package = tools.hindent; + entry = "${hooks.hindent.package}/bin/hindent"; files = "\\.l?hs(-boot)?$"; }; hlint = { name = "hlint"; - description = - "HLint gives suggestions on how to improve your source code."; - entry = "${tools.hlint}/bin/hlint${if hooks.hlint.settings.hintFile == null then "" else " --hint=${hooks.hlint.settings.hintFile}"}"; + description = "HLint gives suggestions on how to improve your source code."; + package = tools.hlint; + entry = "${hooks.hlint.package}/bin/hlint${if hooks.hlint.settings.hintFile == null then "" else " --hint=${hooks.hlint.settings.hintFile}"}"; files = "\\.l?hs(-boot)?$"; }; hpack = { name = "hpack"; - description = - "`hpack` converts package definitions in the hpack format (`package.yaml`) to Cabal files."; - entry = "${tools.hpack-dir}/bin/hpack-dir --${if hooks.hpack.settings.silent then "silent" else "verbose"}"; + description = "`hpack` converts package definitions in the hpack format (`package.yaml`) to Cabal files."; + package = tools.hpack; + entry = "${hooks.hpack-dir.package}/bin/hpack-dir --${if hooks.hpack.settings.silent then "silent" else "verbose"}"; files = "(\\.l?hs(-boot)?$)|(\\.cabal$)|((^|/)package\\.yaml$)"; # We don't pass filenames because they can only be misleading. # Indeed, we need to rerun `hpack` in every directory: @@ -2069,14 +2117,16 @@ in { name = "html-tidy"; description = "HTML linter."; - entry = "${tools.html-tidy}/bin/tidy -quiet -errors"; + package = tools.html-tidy; + entry = "${hooks.html-tidy.package}/bin/tidy -quiet -errors"; files = "\\.html$"; }; hunspell = { name = "hunspell"; description = "Spell checker and morphological analyzer."; - entry = "${tools.hunspell}/bin/hunspell -l"; + package = tools.hunspell; + entry = "${hooks.hunspell.package}/bin/hunspell -l"; files = "\\.((txt)|(html)|(xml)|(md)|(rst)|(tex)|(odf)|\\d)$"; }; isort = @@ -2084,6 +2134,7 @@ in name = "isort"; description = "A Python utility / library to sort imports."; types = [ "file" "python" ]; + package = tools.isort; entry = let cmdArgs = @@ -2092,14 +2143,15 @@ in [ (profile != "") " --profile ${profile}" ] ]); in - "${tools.isort}/bin/isort${cmdArgs} ${hooks.isort.settings.flags}"; + "${hooks.isort.package}/bin/isort${cmdArgs} ${hooks.isort.settings.flags}"; }; juliaformatter = { description = "Run JuliaFormatter.jl against Julia source files"; files = "\\.jl$"; + package = tools.julia; entry = '' - ${tools.julia-bin}/bin/julia -e ' + ${hooks.julia-bin.package}/bin/julia -e ' using Pkg Pkg.activate(".") using JuliaFormatter @@ -2119,7 +2171,8 @@ in name = "latexindent"; description = "Perl script to add indentation to LaTeX files."; types = [ "file" "tex" ]; - entry = "${tools.latexindent}/bin/latexindent ${hooks.latexindent.settings.flags}"; + package = tools.latexindent; + entry = "${hooks.latexindent.package}/bin/latexindent ${hooks.latexindent.settings.flags}"; }; lua-ls = let @@ -2136,7 +2189,7 @@ in }; script = pkgs.writeShellApplication { name = "lua-ls-lint"; - runtimeInputs = [ tools.lua-language-server ]; + runtimeInputs = [ hooks.lua-language-server.package ]; checkPhase = ""; # The default checkPhase depends on GHC text = '' set -e @@ -2156,6 +2209,7 @@ in { name = "lua-ls"; description = "Uses the lua-language-server CLI to statically type-check and lint Lua code."; + package = tools.lua-language-server; entry = "${script}/bin/lua-ls-lint"; files = "\\.lua$"; pass_filenames = false; @@ -2165,11 +2219,13 @@ in name = "luacheck"; description = "A tool for linting and static analysis of Lua code."; types = [ "file" "lua" ]; - entry = "${tools.luacheck}/bin/luacheck"; + package = tools.luacheck; + entry = "${hooks.luacheck.package}/bin/luacheck"; }; lychee = { name = "lychee"; description = "A fast, async, stream-based link checker that finds broken hyperlinks and mail adresses inside Markdown, HTML, reStructuredText, or any other text file or website."; + package = tools.lychee; entry = let cmdArgs = @@ -2178,14 +2234,15 @@ in [ (configPath != "") " --config ${configPath}" ] ]); in - "${pkgs.lychee}/bin/lychee${cmdArgs} ${hooks.lychee.settings.flags}"; + "${hooks.lychee.package}/bin/lychee${cmdArgs} ${hooks.lychee.settings.flags}"; types = [ "text" ]; }; markdownlint = { name = "markdownlint"; description = "Style checker and linter for markdown files."; - entry = "${tools.markdownlint-cli}/bin/markdownlint -c ${pkgs.writeText "markdownlint.json" (builtins.toJSON hooks.markdownlint.settings.config)}"; + package = tools.markdownlint-cli; + entry = "${hooks.markdownlint-cli.package}/bin/markdownlint -c ${pkgs.writeText "markdownlint.json" (builtins.toJSON hooks.markdownlint.settings.config)}"; files = "\\.md$"; }; mdl = @@ -2219,31 +2276,36 @@ in let script = pkgs.writeShellScript "precommit-mdsh" '' for file in $(echo "$@"); do - ${tools.mdsh}/bin/mdsh -i "$file" + ${hooks.mdsh.package}/bin/mdsh -i "$file" done ''; in { name = "mdsh"; description = "Markdown shell pre-processor."; + package = tools.mdsh; entry = toString script; files = "\\.md$"; }; mix-format = { name = "mix-format"; description = "Runs the built-in Elixir syntax formatter"; - entry = "${tools.elixir}/bin/mix format"; + package = tools.elixir; + entry = "${hooks.elixir.package}/bin/mix format"; files = "\\.exs?$"; }; mix-test = { name = "mix-test"; description = "Runs the built-in Elixir test framework"; - entry = "${tools.elixir}/bin/mix test"; + package = tools.elixir; + entry = "${hooks.elixir.package}/bin/mix test"; files = "\\.exs?$"; }; mkdocs-linkcheck = { name = "mkdocs-linkcheck"; description = "Validate links associated with markdown-based, statically generated websites."; + # TODO: unused. see binPath. + package = tools.mkdocs-linkcheck; entry = let cmdArgs = @@ -2256,6 +2318,7 @@ in [ (path != "") " ${path}" ] ]); in + # TODO: missing space? check cmdArgs "${hooks.mkdocs-linkcheck.settings.binPath}${cmdArgs}"; types = [ "text" "markdown" ]; }; @@ -2263,6 +2326,8 @@ in { name = "mypy"; description = "Static type checker for Python"; + # TODO: unused. see binPath. + package = tools.mypy; entry = hooks.mypy.settings.binPath; files = "\\.py$"; }; @@ -2270,13 +2335,14 @@ in { name = "nil"; description = "Incremental analysis assistant for writing in Nix."; + package = tools.nil; entry = let script = pkgs.writeShellScript "precommit-nil" '' errors=false echo Checking: $@ for file in $(echo "$@"); do - ${tools.nil}/bin/nil diagnostics "$file" + ${hooks.nil.package}/bin/nil diagnostics "$file" exit_code=$? if [[ $exit_code -ne 0 ]]; then @@ -2296,34 +2362,39 @@ in { name = "nixfmt"; description = "Nix code prettifier."; - entry = "${tools.nixfmt}/bin/nixfmt ${lib.optionalString (hooks.nixfmt.settings.width != null) "--width=${toString hooks.nixfmt.settings.width}"}"; + package = tools.nixfmt; + entry = "${hooks.nixfmt.package}/bin/nixfmt ${lib.optionalString (hooks.nixfmt.settings.width != null) "--width=${toString hooks.nixfmt.settings.width}"}"; files = "\\.nix$"; }; nixpkgs-fmt = { name = "nixpkgs-fmt"; description = "Nix code prettifier."; - entry = "${tools.nixpkgs-fmt}/bin/nixpkgs-fmt"; + package = tools.nixpkgs-fmt; + entry = "${hooks.nixpkgs-fmt.package}/bin/nixpkgs-fmt"; files = "\\.nix$"; }; ocp-indent = { name = "ocp-indent"; description = "A tool to indent OCaml code."; - entry = "${tools.ocp-indent}/bin/ocp-indent --inplace"; + package = tools.ocp-indent; + entry = "${hooks.ocp-indent.package}/bin/ocp-indent --inplace"; files = "\\.mli?$"; }; opam-lint = { name = "opam lint"; description = "OCaml package manager configuration checker."; - entry = "${tools.opam}/bin/opam lint"; + package = tools.opam; + entry = "${hooks.opam.package}/bin/opam lint"; files = "\\.opam$"; }; ormolu = { name = "ormolu"; description = "Haskell code prettifier."; + package = tools.ormolu; entry = let extensions = @@ -2331,13 +2402,15 @@ in cabalExtensions = if hooks.ormolu.settings.cabalDefaultExtensions then "--cabal-default-extensions" else ""; in - "${tools.ormolu}/bin/ormolu --mode inplace ${extensions} ${cabalExtensions}"; + "${hooks.ormolu.package}/bin/ormolu --mode inplace ${extensions} ${cabalExtensions}"; files = "\\.l?hs(-boot)?$"; }; php-cs-fixer = { name = "php-cs-fixer"; description = "Lint PHP files."; + # TODO: unused. see binPath. + package = tools.php-cs-fixer; entry = with hooks.php-cs-fixer.settings; "${binPath} fix"; types = [ "php" ]; @@ -2346,6 +2419,8 @@ in { name = "phpcbf"; description = "Lint PHP files."; + # TODO: unused. see binPath. + package = tools.phpcbf; entry = with hooks.phpcbf.settings; "${binPath}"; types = [ "php" ]; @@ -2354,6 +2429,8 @@ in { name = "phpcs"; description = "Lint PHP files."; + # TODO: unused. see binPath. + package = tools.phpcs; entry = with hooks.phpcs.settings; "${binPath}"; types = [ "php" ]; @@ -2362,21 +2439,24 @@ in { name = "phpstan"; description = "Static Analysis of PHP files."; + # TODO: unused. see binPath. + package = tools.phpstan; entry = with hooks.phpstan.settings; "${binPath} analyse"; types = [ "php" ]; }; pre-commit-hook-ensure-sops = { name = "pre-commit-hook-ensure-sops"; + package = tools.pre-commit-hook-ensure-sops; entry = ## NOTE: pre-commit-hook-ensure-sops landed in nixpkgs on 8 July 2022. Once it reaches a ## release of NixOS, the `throwIf` piece of code below will become ## useless. lib.throwIf - (tools.pre-commit-hook-ensure-sops == null) + (hooks.pre-commit-hook-ensure-sops.package == null) "The version of nixpkgs used by pre-commit-hooks.nix does not have the `pre-commit-hook-ensure-sops` package. Please use a more recent version of nixpkgs." '' - ${tools.pre-commit-hook-ensure-sops}/bin/pre-commit-hook-ensure-sops + ${hooks.pre-commit-hook-ensure-sops.package}/bin/pre-commit-hook-ensure-sops ''; files = lib.mkDefault "^secrets"; }; @@ -2387,6 +2467,8 @@ in name = "prettier"; description = "Opinionated multi-language code formatter."; types = [ "text" ]; + # TODO: unused. see binPath. + package = tools.prettier; entry = let cmdArgs = @@ -2437,6 +2519,8 @@ in { name = "psalm"; description = "Static Analysis of PHP files."; + # TODO: unused. see binPath. + package = tools.psalm; entry = with hooks.psalm.settings; "${binPath}"; types = [ "php" ]; @@ -2445,20 +2529,24 @@ in { name = "purs-tidy"; description = "Format purescript files."; - entry = "${tools.purs-tidy}/bin/purs-tidy format-in-place"; + package = tools.purs-tidy; + entry = "${hooks.purs-tidy.package}/bin/purs-tidy format-in-place"; files = "\\.purs$"; }; purty = { name = "purty"; description = "Format purescript files."; - entry = "${tools.purty}/bin/purty"; + package = tools.purty; + entry = "${hooks.purty.package}/bin/purty"; files = "\\.purs$"; }; pylint = { name = "pylint"; description = "Lint Python files."; + # TODO: unused. see binPath. + package = tools.pylint; entry = with hooks.pylint.settings; "${binPath} ${lib.optionalString reports "-ry"} ${lib.optionalString (! score) "-sn"}"; types = [ "python" ]; @@ -2467,6 +2555,8 @@ in { name = "pyright"; description = "Static type checker for Python"; + # TODO: unused. see binPath. + package = tools.pyright; entry = hooks.pyright.settings.binPath; files = "\\.py$"; }; @@ -2474,6 +2564,8 @@ in { name = "pyupgrade"; description = "Automatically upgrade syntax for newer versions."; + # TODO: unused. see binPath. + package = tools.pyupgrade; entry = with hooks.pyupgrade.settings; "${binPath}"; types = [ "python" ]; @@ -2482,6 +2574,7 @@ in { name = "revive"; description = "A linter for Go source code."; + package = tools.revive; entry = let cmdArgs = @@ -2496,7 +2589,7 @@ in script = pkgs.writeShellScript "precommit-revive" '' set -e for dir in $(echo "$@" | xargs -n1 dirname | sort -u); do - ${tools.revive}/bin/revive ${cmdArgs} ./"$dir" + ${hooks.revive.package}/bin/revive ${cmdArgs} ./"$dir" done ''; in @@ -2511,6 +2604,8 @@ in name = "rome"; description = "Unified developer tools for JavaScript, TypeScript, and the web"; types_or = [ "javascript" "jsx" "ts" "tsx" "json" ]; + # TODO: unused. see binPath. + package = tools.rome; entry = let cmdArgs = @@ -2525,7 +2620,8 @@ in { name = "ruff"; description = "An extremely fast Python linter, written in Rust."; - entry = "${tools.ruff}/bin/ruff --fix"; + package = tools.ruff; + entry = "${hooks.ruff.package}/bin/ruff --fix"; types = [ "python" ]; }; rustfmt = @@ -2543,6 +2639,7 @@ in { name = "rustfmt"; description = "Format Rust code."; + package = wrapper; entry = "${wrapper}/bin/cargo-fmt fmt ${cargoManifestPathArg} -- --color always"; files = "\\.rs$"; pass_filenames = false; @@ -2552,26 +2649,29 @@ in name = "shellcheck"; description = "Format shell files."; types = [ "shell" ]; - entry = "${tools.shellcheck}/bin/shellcheck"; + package = tools.shellcheck; + entry = "${hooks.shellcheck.package}/bin/shellcheck"; }; shfmt = { name = "shfmt"; description = "Format shell files."; types = [ "shell" ]; - entry = "${tools.shfmt}/bin/shfmt -w -s -l"; + package = tools.shfmt; + entry = "${hooks.shfmt.package}/bin/shfmt -w -s -l"; }; staticcheck = { name = "staticcheck"; description = "State of the art linter for the Go programming language"; + package = tools.go-tools; # staticheck works with directories. entry = let script = pkgs.writeShellScript "precommit-staticcheck" '' err=0 for dir in $(echo "$@" | xargs -n1 dirname | sort -u); do - ${tools.go-tools}/bin/staticcheck ./"$dir" + ${hooks.staticcheck.package}/bin/staticcheck ./"$dir" code="$?" if [[ "$err" -eq 0 ]]; then err="$code" @@ -2590,8 +2690,9 @@ in { name = "statix"; description = "Lints and suggestions for the Nix programming language."; + package = tools.statix; entry = with hooks.statix.settings; - "${tools.statix}/bin/statix check -o ${format} ${if (ignore != [ ]) then "-i ${lib.escapeShellArgs (lib.unique ignore)}" else ""}"; + "${hooks.statix.package}/bin/statix check -o ${format} ${if (ignore != [ ]) then "-i ${lib.escapeShellArgs (lib.unique ignore)}" else ""}"; files = "\\.nix$"; pass_filenames = false; }; @@ -2599,7 +2700,8 @@ in { name = "stylish-haskell"; description = "A simple Haskell code prettifier"; - entry = "${tools.stylish-haskell}/bin/stylish-haskell --inplace"; + package = tools.stylish-haskell; + entry = "${hooks.stylish-haskell.package}/bin/stylish-haskell --inplace"; files = "\\.l?hs(-boot)?$"; }; stylua = @@ -2607,7 +2709,8 @@ in name = "stylua"; description = "An Opinionated Lua Code Formatter."; types = [ "file" "lua" ]; - entry = "${tools.stylua}/bin/stylua --respect-ignores"; + package = tools.stylua; + entry = "${hooks.stylua.package}/bin/stylua --respect-ignores"; }; tagref = { @@ -2615,7 +2718,8 @@ in description = '' Have tagref check all references and tags. ''; - entry = "${tools.tagref}/bin/tagref"; + package = tools.tagref; + entry = "${hooks.tagref.package}/bin/tagref"; types = [ "text" ]; pass_filenames = false; }; @@ -2623,33 +2727,37 @@ in { name = "taplo"; description = "Format TOML files with taplo fmt"; - entry = "${tools.taplo}/bin/taplo fmt"; + package = tools.taplo; + entry = "${hooks.taplo.package}/bin/taplo fmt"; types = [ "toml" ]; }; terraform-format = { name = "terraform-format"; description = "Format terraform (`.tf`) files."; - entry = "${tools.terraform-fmt}/bin/terraform-fmt"; + package = tools.terraform-fmt; + entry = "${hooks.terraform-fmt.package}/bin/terraform-fmt"; files = "\\.tf$"; }; tflint = { name = "tflint"; description = "A Pluggable Terraform Linter."; - entry = "${tools.tflint}/bin/tflint"; + package = tools.tflint; + entry = "${hooks.tflint.package}/bin/tflint"; files = "\\.tf$"; }; topiary = { name = "topiary"; description = "A universal formatter engine within the Tree-sitter ecosystem, with support for many languages."; + package = tools.topiary; entry = ## NOTE: Topiary landed in nixpkgs on 2 Dec 2022. Once it reaches a ## release of NixOS, the `throwIf` piece of code below will become ## useless. lib.throwIf - (tools.topiary == null) + (hooks.topiary.package == null) "The version of nixpkgs used by pre-commit-hooks.nix does not have the `topiary` package. Please use a more recent version of nixpkgs." ( let @@ -2657,7 +2765,7 @@ in name = "topiary-inplace"; text = '' for file; do - ${tools.topiary}/bin/topiary --in-place --input-file "$file" + ${hooks.topiary.package}/bin/topiary --in-place --input-file "$file" done ''; }; @@ -2672,12 +2780,14 @@ in description = "One CLI to format the code tree."; types = [ "file" ]; pass_filenames = true; + package = mkDefault tools.treefmt; entry = "${hooks.treefmt.package}/bin/treefmt --fail-on-change"; }; typos = { name = "typos"; description = "Source code spell checker"; + package = tools.typos; entry = let # Concatenate config in config file with section for ignoring words generated from list of words to ignore @@ -2703,18 +2813,20 @@ in [ (write && !diff) "--write-changes" ] ]); in - "${tools.typos}/bin/typos ${cmdArgs}"; + "${hooks.typos.package}/bin/typos ${cmdArgs}"; types = [ "text" ]; }; typstfmt = { name = "typstfmt"; description = "format typst"; - entry = "${tools.typst-fmt}/bin/typst-fmt"; + package = tools.typst-fmt; + entry = "${hooks.typst-fmt.package}/bin/typst-fmt"; files = "\\.typ$"; }; vale = { name = "vale"; description = "A markup-aware linter for prose built with speed and extensibility in mind."; + package = tools.vale; entry = let # TODO: was .vale.ini, throwed error in Nix @@ -2726,7 +2838,7 @@ in [ (config != "" && configPath == "") " --config ${configFile}" ] ]); in - "${pkgs.vale}/bin/vale${cmdArgs} ${hooks.vale.settings.flags}"; + "${hooks.vale.package}/bin/vale${cmdArgs} ${hooks.vale.settings.flags}"; types = [ "text" ]; }; yamllint = @@ -2734,6 +2846,7 @@ in name = "yamllint"; description = "Yaml linter."; types = [ "file" "yaml" ]; + package = tools.yamllint; entry = let cmdArgs = @@ -2742,13 +2855,14 @@ in [ (hooks.yamllint.settings.configPath != "") "-c ${hooks.yamllint.settings.configPath}" ] ]; in - "${tools.yamllint}/bin/yamllint ${cmdArgs}"; + "${hooks.yamllint.package}/bin/yamllint ${cmdArgs}"; }; zprint = { name = "zprint"; description = "Beautifully format Clojure and Clojurescript source code and s-expressions."; - entry = "${tools.zprint}/bin/zprint '{:search-config? true}' -w"; + package = tools.zprint; + entry = "${hooks.zprint.package}/bin/zprint '{:search-config? true}' -w"; types_or = [ "clojure" "clojurescript" "edn" ]; }; diff --git a/nix/run.nix b/nix/run.nix index a392e8aa..04cce564 100644 --- a/nix/run.nix +++ b/nix/run.nix @@ -18,6 +18,7 @@ let { _module.args.pkgs = pkgs; _module.args.gitignore-nix-src = gitignore-nix-src; + _module.args.default_stages = default_stages; inherit hooks excludes default_stages settings; tools = builtinStuff.tools // tools; package = pre-commit; diff --git a/nix/tools.nix b/nix/tools.nix index 358b6715..54b7d4c7 100644 --- a/nix/tools.nix +++ b/nix/tools.nix @@ -40,6 +40,7 @@ , hunspell , luaPackages , lua-language-server +, lychee , julia-bin , mdl , mdsh @@ -69,6 +70,7 @@ , texlive , tflint , topiary ? null ## Added in nixpkgs on Dec 2, 2022 +, treefmt , typos , typst-fmt , zprint @@ -79,6 +81,7 @@ , go-tools , golangci-lint , revive ? null +, vale }: @@ -121,6 +124,7 @@ in hlint hpack html-tidy + lychee julia-bin mdl mdsh @@ -141,8 +145,10 @@ in tagref taplo topiary + treefmt typos typst-fmt + vale yamllint zprint ; From 72bc75c47a1fe4f765ca81af1c0d867f3c4fc77f Mon Sep 17 00:00:00 2001 From: Sander Date: Sat, 10 Feb 2024 23:55:56 +0000 Subject: [PATCH 13/26] Remove unused arg --- nix/run.nix | 1 - 1 file changed, 1 deletion(-) diff --git a/nix/run.nix b/nix/run.nix index 04cce564..a392e8aa 100644 --- a/nix/run.nix +++ b/nix/run.nix @@ -18,7 +18,6 @@ let { _module.args.pkgs = pkgs; _module.args.gitignore-nix-src = gitignore-nix-src; - _module.args.default_stages = default_stages; inherit hooks excludes default_stages settings; tools = builtinStuff.tools // tools; package = pre-commit; From f069ad80f6d80ca8041abd9308fb517c8dd3752c Mon Sep 17 00:00:00 2001 From: Sander Date: Sun, 11 Feb 2024 00:27:10 +0000 Subject: [PATCH 14/26] Fix package typos --- modules/hooks.nix | 58 +++++++++++++++++++++++------------------------ 1 file changed, 29 insertions(+), 29 deletions(-) diff --git a/modules/hooks.nix b/modules/hooks.nix index 8b5fc9ce..be4a69f3 100644 --- a/modules/hooks.nix +++ b/modules/hooks.nix @@ -1494,7 +1494,7 @@ in name = "annex"; description = "Runs the git-annex hook for large file support"; package = tools.git-annex; - entry = "${hooks.git-annex.package}/bin/git-annex pre-commit"; + entry = "${hooks.annex.package}/bin/git-annex pre-commit"; }; ansible-lint = { @@ -1556,8 +1556,8 @@ in { name = "cabal2nix"; description = "Run `cabal2nix` on all `*.cabal` files to generate corresponding `default.nix` files"; - package = tools.cabal2nix; - entry = "${hooks.cabal2nix-dir.package}/bin/cabal2nix-dir"; + package = tools.cabal2nix-dir; + entry = "${hooks.cabal2nix.package}/bin/cabal2nix-dir"; files = "\\.cabal$"; }; cargo-check = @@ -1565,7 +1565,7 @@ in name = "cargo-check"; description = "Check the cargo package for errors"; package = tools.cargo; - entry = "${hooks.cargo.package}/bin/cargo check ${cargoManifestPathArg}"; + entry = "${hooks.cargo-check.package}/bin/cargo check ${cargoManifestPathArg}"; files = "\\.rs$"; pass_filenames = false; }; @@ -1595,7 +1595,7 @@ in name = "clang-format"; description = "Format your code using `clang-format`."; package = tools.clang-tools; - entry = "${hooks.clang-tools.package}/bin/clang-format -style=file -i"; + entry = "${hooks.clang-format.package}/bin/clang-format -style=file -i"; # Source: # https://github.com/pre-commit/mirrors-clang-format/blob/46516e8f532c8f2d55e801c34a740ebb8036365c/.pre-commit-hooks.yaml types_or = [ @@ -1614,7 +1614,7 @@ in name = "clang-tidy"; description = "Static analyzer for C++ code."; package = tools.clang-tools; - entry = "${hooks.clang-tools.package}/bin/clang-tidy --fix"; + entry = "${hooks.clang-tidy.package}/bin/clang-tidy --fix"; types = [ "c" "c++" "c#" "objective-c" ]; }; clippy = @@ -1753,7 +1753,7 @@ in [ (hooks.denofmt.settings.configPath != "") "-c ${hooks.denofmt.settings.configPath}" ] ]; in - "${hooks.deno.package}/bin/deno fmt ${cmdArgs}"; + "${hooks.denofmt.package}/bin/deno fmt ${cmdArgs}"; }; denolint = { @@ -1770,26 +1770,26 @@ in [ (hooks.denolint.settings.configPath != "") "-c ${hooks.denolint.settings.configPath}" ] ]; in - "${hooks.deno.package}/bin/deno lint ${cmdArgs}"; + "${hooks.denolint.package}/bin/deno lint ${cmdArgs}"; }; dhall-format = { name = "dhall-format"; description = "Dhall code formatter."; package = tools.dhall; - entry = "${hooks.dhall.package}/bin/dhall format"; + entry = "${hooks.dhall-format.package}/bin/dhall format"; files = "\\.dhall$"; }; dialyzer = { name = "dialyzer"; description = "Runs a static code analysis using Dialyzer"; package = tools.elixir; - entry = "${hooks.elixir.package}/bin/mix dialyzer"; + entry = "${hooks.dialyzer.package}/bin/mix dialyzer"; files = "\\.exs?$"; }; dune-fmt = { name = "dune-fmt"; description = "Runs Dune's formatters on the code tree."; - package = tools.dune; + package = tools.dune-fmt; entry = let auto-promote = if hooks.dune-fmt.settings.auto-promote then "--auto-promote" else ""; @@ -1805,8 +1805,8 @@ in dune-opam-sync = { name = "dune/opam sync"; description = "Check that Dune-generated OPAM files are in sync."; - package = tools.dune; - entry = "${hooks.dune-build-opam-files.package}/bin/dune-build-opam-files"; + package = tools.dune-build-opam-files; + entry = "${hooks.dune-opam-sync.package}/bin/dune-build-opam-files"; files = "(\\.opam$)|(\\.opam.template$)|((^|/)dune-project$)"; ## We don't pass filenames because they can only be misleading. Indeed, ## we need to re-run `dune build` for every `*.opam` file, but also when @@ -1946,7 +1946,7 @@ in failed=false for file in "$@"; do # redirect stderr so that violations and summaries are properly interleaved. - if ! ${hooks.go.package}/bin/gofmt -l -w "$file" 2>&1 + if ! ${hooks.gofmt.package}/bin/gofmt -l -w "$file" 2>&1 then failed=true fi @@ -2009,7 +2009,7 @@ in # test each directory one by one for dir in "''${sorted_dirs[@]}"; do - ${hooks.go.package}/bin/go test "./$dir" + ${hooks.gotest.package}/bin/go test "./$dir" done ''; in @@ -2030,7 +2030,7 @@ in script = pkgs.writeShellScript "precommit-govet" '' set -e for dir in $(echo "$@" | xargs -n1 dirname | sort -u); do - ${hooks.go.package}/bin/go vet ./"$dir" + ${hooks.govet.package}/bin/go vet ./"$dir" done ''; in @@ -2051,7 +2051,7 @@ in "$PRE_COMMIT_COMMIT_MSG_SOURCE" --commit-msg-file "$1" ''; in - lib.throwIf (tools.gptcommit == null) "The version of Nixpkgs used by pre-commit-hooks.nix does not have the `gptcommit` package. Please use a more recent version of Nixpkgs." + lib.throwIf (hooks.gptcommit.package == null) "The version of Nixpkgs used by pre-commit-hooks.nix does not have the `gptcommit` package. Please use a more recent version of Nixpkgs." toString script; stages = [ "prepare-commit-msg" ]; @@ -2100,8 +2100,8 @@ in { name = "hpack"; description = "`hpack` converts package definitions in the hpack format (`package.yaml`) to Cabal files."; - package = tools.hpack; - entry = "${hooks.hpack-dir.package}/bin/hpack-dir --${if hooks.hpack.settings.silent then "silent" else "verbose"}"; + package = tools.hpack-dir; + entry = "${hooks.hpack.package}/bin/hpack-dir --${if hooks.hpack.settings.silent then "silent" else "verbose"}"; files = "(\\.l?hs(-boot)?$)|(\\.cabal$)|((^|/)package\\.yaml$)"; # We don't pass filenames because they can only be misleading. # Indeed, we need to rerun `hpack` in every directory: @@ -2149,9 +2149,9 @@ in { description = "Run JuliaFormatter.jl against Julia source files"; files = "\\.jl$"; - package = tools.julia; + package = tools.julia-bin; entry = '' - ${hooks.julia-bin.package}/bin/julia -e ' + ${hooks.juliaformatter.package}/bin/julia -e ' using Pkg Pkg.activate(".") using JuliaFormatter @@ -2189,7 +2189,7 @@ in }; script = pkgs.writeShellApplication { name = "lua-ls-lint"; - runtimeInputs = [ hooks.lua-language-server.package ]; + runtimeInputs = [ hooks.lua-ls.package ]; checkPhase = ""; # The default checkPhase depends on GHC text = '' set -e @@ -2242,7 +2242,7 @@ in name = "markdownlint"; description = "Style checker and linter for markdown files."; package = tools.markdownlint-cli; - entry = "${hooks.markdownlint-cli.package}/bin/markdownlint -c ${pkgs.writeText "markdownlint.json" (builtins.toJSON hooks.markdownlint.settings.config)}"; + entry = "${hooks.markdownlint.package}/bin/markdownlint -c ${pkgs.writeText "markdownlint.json" (builtins.toJSON hooks.markdownlint.settings.config)}"; files = "\\.md$"; }; mdl = @@ -2291,14 +2291,14 @@ in name = "mix-format"; description = "Runs the built-in Elixir syntax formatter"; package = tools.elixir; - entry = "${hooks.elixir.package}/bin/mix format"; + entry = "${hooks.mix-format.package}/bin/mix format"; files = "\\.exs?$"; }; mix-test = { name = "mix-test"; description = "Runs the built-in Elixir test framework"; package = tools.elixir; - entry = "${hooks.elixir.package}/bin/mix test"; + entry = "${hooks.mix-test.package}/bin/mix test"; files = "\\.exs?$"; }; mkdocs-linkcheck = { @@ -2387,7 +2387,7 @@ in name = "opam lint"; description = "OCaml package manager configuration checker."; package = tools.opam; - entry = "${hooks.opam.package}/bin/opam lint"; + entry = "${hooks.opam-lint.package}/bin/opam lint"; files = "\\.opam$"; }; ormolu = @@ -2640,7 +2640,7 @@ in name = "rustfmt"; description = "Format Rust code."; package = wrapper; - entry = "${wrapper}/bin/cargo-fmt fmt ${cargoManifestPathArg} -- --color always"; + entry = "${hooks.rustfmt.package}/bin/cargo-fmt fmt ${cargoManifestPathArg} -- --color always"; files = "\\.rs$"; pass_filenames = false; }; @@ -2736,7 +2736,7 @@ in name = "terraform-format"; description = "Format terraform (`.tf`) files."; package = tools.terraform-fmt; - entry = "${hooks.terraform-fmt.package}/bin/terraform-fmt"; + entry = "${hooks.terraform-format.package}/bin/terraform-fmt"; files = "\\.tf$"; }; tflint = @@ -2820,7 +2820,7 @@ in name = "typstfmt"; description = "format typst"; package = tools.typst-fmt; - entry = "${hooks.typst-fmt.package}/bin/typst-fmt"; + entry = "${hooks.typstfmt.package}/bin/typst-fmt"; files = "\\.typ$"; }; vale = { From d84404d088b2051c952c43dcf3a7af6483f290cc Mon Sep 17 00:00:00 2001 From: Sander Date: Sun, 11 Feb 2024 12:51:55 +0000 Subject: [PATCH 15/26] Apply mkDefault to built-in hooks --- modules/hooks.nix | 58 +++++++++++++++++++++++------------------------ 1 file changed, 29 insertions(+), 29 deletions(-) diff --git a/modules/hooks.nix b/modules/hooks.nix index be4a69f3..0f6cd139 100644 --- a/modules/hooks.nix +++ b/modules/hooks.nix @@ -4,7 +4,7 @@ let cfg = config; hooks = config.hooks; settings = config.settings; - inherit (lib) mkDefault mkOption mkRenamedOptionModule types; + inherit (lib) mapAttrs mkDefault mkOption mkRenamedOptionModule types; hookModule = [ @@ -1241,31 +1241,31 @@ in type = types.submodule { imports = hookModule; options.settings = { - # package = mkOption { - # type = types.package; - # description = lib.mdDoc - # '' - # The `treefmt` package to use. - # - # Should include all the formatters configured by treefmt. - # - # For example: - # ```nix - # pkgs.writeShellApplication { - # name = "treefmt"; - # runtimeInputs = [ - # pkgs.treefmt - # pkgs.nixpkgs-fmt - # pkgs.black - # ]; - # text = - # ''' - # exec treefmt "$@" - # '''; - # } - # ``` - # ''; - # }; + package = mkOption { + type = types.package; + description = lib.mdDoc + '' + The `treefmt` package to use. + + Should include all the formatters configured by treefmt. + + For example: + ```nix + pkgs.writeShellApplication { + name = "treefmt"; + runtimeInputs = [ + pkgs.treefmt + pkgs.nixpkgs-fmt + pkgs.black + ]; + text = + ''' + exec treefmt "$@" + '''; + } + ``` + ''; + }; }; }; }; @@ -1459,7 +1459,7 @@ in }; # PLEASE keep this sorted alphabetically. - config.hooks = + config.hooks = mapAttrs (_: mapAttrs (_: mkDefault)) { actionlint = { @@ -2458,7 +2458,7 @@ in '' ${hooks.pre-commit-hook-ensure-sops.package}/bin/pre-commit-hook-ensure-sops ''; - files = lib.mkDefault "^secrets"; + files = "^secrets"; }; # See all CLI flags for prettier [here](https://prettier.io/docs/en/cli.html). # See all options for prettier [here](https://prettier.io/docs/en/options.html). @@ -2780,7 +2780,7 @@ in description = "One CLI to format the code tree."; types = [ "file" ]; pass_filenames = true; - package = mkDefault tools.treefmt; + package = tools.treefmt; entry = "${hooks.treefmt.package}/bin/treefmt --fail-on-change"; }; typos = From db697eb3025f16a4c8d24418203572b5d568b62d Mon Sep 17 00:00:00 2001 From: Sander Date: Sun, 11 Feb 2024 14:21:39 +0000 Subject: [PATCH 16/26] Migrate `settings..package` to `hooks..package` --- modules/hooks.nix | 93 +++++++++++++++++++++++++++-------------------- 1 file changed, 53 insertions(+), 40 deletions(-) diff --git a/modules/hooks.nix b/modules/hooks.nix index 0f6cd139..b33909c9 100644 --- a/modules/hooks.nix +++ b/modules/hooks.nix @@ -4,7 +4,7 @@ let cfg = config; hooks = config.hooks; settings = config.settings; - inherit (lib) mapAttrs mkDefault mkOption mkRenamedOptionModule types; + inherit (lib) flatten mapAttrs mapAttrsToList mkDefault mkOption mkRenamedOptionModule types; hookModule = [ @@ -29,14 +29,26 @@ let in { imports = - map (o: mkRenamedOptionModule [ "settings" o ] [ "hooks" o "settings" ]) - [ "alejandra" "ansible-lint" "autoflake" "clippy" "cmake-format" "credo" "deadnix" "denofmt" "denolint" "dune-fmt" "eclint" "eslint" "flake8" "flynt" "headache" "hlint" "hpack" "isort" "latexindent" "lua-ls" "lychee" "markdownlint" "mdl" "mkdocs-linkcheck" "mypy" "nixfmt" "ormolu" "php-cs-fixer" "phpcbf" "phpcs" "phpstan" "prettier" "psalm" "pylint" "pyright" "pyupgrade" "revive" "rome" "statix" "treefmt" "typos" "vale" "yamllint" ]; + # Rename `settings..package` to `hooks..package` + map (name: mkRenamedOptionModule [ "settings" name "package" ] [ "hooks" name "package" ]) [ "alejandra" "eclint" "flynt" "mdl" "treefmt" ] + # Manually rename options that had a package option + ++ flatten (mapAttrsToList (name: map (o: mkRenamedOptionModule [ "settings" name o ] [ "hooks" name o ])) { + "alejandra" = [ "check" "exclude" "threads" "verbosity" ]; + "eclint" = [ "fix" "summary" "color" "exclude" "verbosity" ]; + "flynt" = [ "aggressive" "binPath" "dry-run" "exclude" "fail-on-change" "line-length" "no-multiline" "quiet" "string" "transform-concats" "verbose" ]; + "mdl" = [ "configPath" "git-recurse" "ignore-front-matter" "json" "rules" "rulesets" "show-aliases" "warnings" "skip-default-ruleset" "style" "tags" "verbose" ]; + }) + # Rename the remaining `settings.` to `hooks..settings` + ++ map (name: mkRenamedOptionModule [ "settings" name ] [ "hooks" name "settings" ]) + [ "ansible-lint" "autoflake" "clippy" "cmake-format" "credo" "deadnix" "denofmt" "denolint" "dune-fmt" "eslint" "flake8" "headache" "hlint" "hpack" "isort" "latexindent" "lua-ls" "lychee" "markdownlint" "mkdocs-linkcheck" "mypy" "nixfmt" "ormolu" "php-cs-fixer" "phpcbf" "phpcs" "phpstan" "prettier" "psalm" "pylint" "pyright" "pyupgrade" "revive" "rome" "statix" "typos" "vale" "yamllint" ]; # PLEASE keep this sorted alphabetically. - options.settings.rust.cargoManifestPath = mkOption { - type = types.nullOr types.str; - description = lib.mdDoc "Path to Cargo.toml"; - default = null; + options.settings = { + rust.cargoManifestPath = mkOption { + type = types.nullOr types.str; + description = lib.mdDoc "Path to Cargo.toml"; + default = null; + }; }; # PLEASE keep this sorted alphabetically. @@ -1236,39 +1248,40 @@ in }; }; }; - treefmt = mkOption { - description = ""; - type = types.submodule { - imports = hookModule; - options.settings = { - package = mkOption { - type = types.package; - description = lib.mdDoc - '' - The `treefmt` package to use. - - Should include all the formatters configured by treefmt. - - For example: - ```nix - pkgs.writeShellApplication { - name = "treefmt"; - runtimeInputs = [ - pkgs.treefmt - pkgs.nixpkgs-fmt - pkgs.black - ]; - text = - ''' - exec treefmt "$@" - '''; - } - ``` - ''; - }; - }; - }; - }; + # TODO: how do we provide a default package for this? + # treefmt = mkOption { + # description = ""; + # type = types.submodule { + # imports = hookModule; + # options.settings = { + # package = mkOption { + # type = types.package; + # description = lib.mdDoc + # '' + # The `treefmt` package to use. + # + # Should include all the formatters configured by treefmt. + # + # For example: + # ```nix + # pkgs.writeShellApplication { + # name = "treefmt"; + # runtimeInputs = [ + # pkgs.treefmt + # pkgs.nixpkgs-fmt + # pkgs.black + # ]; + # text = + # ''' + # exec treefmt "$@" + # '''; + # } + # ``` + # ''; + # }; + # }; + # }; + # }; typos = mkOption { description = ""; type = types.submodule { From 22683d3fc907e18cfd5a174d84cd131a16175e41 Mon Sep 17 00:00:00 2001 From: Sander Date: Sun, 11 Feb 2024 14:33:45 +0000 Subject: [PATCH 17/26] Remove `package` from the raw options --- modules/hook.nix | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/hook.nix b/modules/hook.nix index 739e6683..2c5fb315 100644 --- a/modules/hook.nix +++ b/modules/hook.nix @@ -158,7 +158,7 @@ in config = { raw = { - inherit (config) name package entry language files types types_or pass_filenames fail_fast require_serial stages verbose always_run; + inherit (config) name entry language files types types_or pass_filenames fail_fast require_serial stages verbose always_run; id = config.name; exclude = mergeExcludes config.excludes; }; From 87a3853010a80090362d9246e138ef0c445edf06 Mon Sep 17 00:00:00 2001 From: Sander Date: Sun, 11 Feb 2024 14:35:38 +0000 Subject: [PATCH 18/26] Fix option remap --- modules/hooks.nix | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/hooks.nix b/modules/hooks.nix index b33909c9..da4fbfb4 100644 --- a/modules/hooks.nix +++ b/modules/hooks.nix @@ -32,7 +32,7 @@ in # Rename `settings..package` to `hooks..package` map (name: mkRenamedOptionModule [ "settings" name "package" ] [ "hooks" name "package" ]) [ "alejandra" "eclint" "flynt" "mdl" "treefmt" ] # Manually rename options that had a package option - ++ flatten (mapAttrsToList (name: map (o: mkRenamedOptionModule [ "settings" name o ] [ "hooks" name o ])) { + ++ flatten (mapAttrsToList (name: map (o: mkRenamedOptionModule [ "settings" name o ] [ "hooks" name "settings" o ])) { "alejandra" = [ "check" "exclude" "threads" "verbosity" ]; "eclint" = [ "fix" "summary" "color" "exclude" "verbosity" ]; "flynt" = [ "aggressive" "binPath" "dry-run" "exclude" "fail-on-change" "line-length" "no-multiline" "quiet" "string" "transform-concats" "verbose" ]; From 8af5964b74f112edd6bdafaa07924842e1e27eec Mon Sep 17 00:00:00 2001 From: Sander Date: Sun, 11 Feb 2024 14:46:39 +0000 Subject: [PATCH 19/26] Add a description to each hook --- modules/hooks.nix | 86 +++++++++++++++++++++++------------------------ 1 file changed, 43 insertions(+), 43 deletions(-) diff --git a/modules/hooks.nix b/modules/hooks.nix index da4fbfb4..099d938d 100644 --- a/modules/hooks.nix +++ b/modules/hooks.nix @@ -55,7 +55,7 @@ in options.hooks = { alejandra = mkOption { - description = ""; + description = lib.mdDoc "Additional alejandra settings"; type = types.submodule { imports = hookModule; options.settings = { @@ -91,7 +91,7 @@ in }; }; ansible-lint = mkOption { - description = ""; + description = lib.mdDoc "Additional ansible-lint settings"; type = types.submodule { imports = hookModule; options.settings = { @@ -111,7 +111,7 @@ in }; }; autoflake = mkOption { - description = ""; + description = lib.mdDoc "Additional autoflake settings"; type = types.submodule { imports = hookModule; options.settings = { @@ -135,7 +135,7 @@ in }; }; clippy = mkOption { - description = ""; + description = lib.mdDoc "Additional clippy settings"; type = types.submodule { imports = hookModule; options.settings = { @@ -158,7 +158,7 @@ in }; }; cmake-format = mkOption { - description = ""; + description = lib.mdDoc "Additional cmake-format settings"; type = types.submodule { imports = hookModule; options.settings = { @@ -172,7 +172,7 @@ in }; }; credo = mkOption { - description = ""; + description = lib.mdDoc "Additional credo settings"; type = types.submodule { imports = hookModule; options.settings = { @@ -186,7 +186,7 @@ in }; }; deadnix = mkOption { - description = ""; + description = lib.mdDoc "Additional deadnix settings"; type = types.submodule { imports = hookModule; options.settings = { @@ -242,7 +242,7 @@ in }; }; denofmt = mkOption { - description = ""; + description = lib.mdDoc "Additional denofmt settings"; type = types.submodule { imports = hookModule; options.settings = { @@ -264,7 +264,7 @@ in }; }; denolint = mkOption { - description = ""; + description = lib.mdDoc "Additional denolint settings"; type = types.submodule { imports = hookModule; options.settings = { @@ -287,7 +287,7 @@ in }; }; dune-fmt = mkOption { - description = ""; + description = lib.mdDoc "Additional dune-fmt settings"; type = types.submodule { imports = hookModule; options.settings = { @@ -308,7 +308,7 @@ in }; }; eclint = mkOption { - description = ""; + description = lib.mdDoc "Additional eclint settings"; type = types.submodule { imports = hookModule; options.settings = { @@ -346,7 +346,7 @@ in }; }; eslint = mkOption { - description = ""; + description = lib.mdDoc "Additional eslint settings"; type = types.submodule { imports = hookModule; options.settings = { @@ -370,7 +370,7 @@ in }; }; flake8 = mkOption { - description = ""; + description = lib.mdDoc "Additional flake8 settings"; type = types.submodule { imports = hookModule; options.settings = { @@ -400,7 +400,7 @@ in }; }; flynt = mkOption { - description = ""; + description = lib.mdDoc "Additional flynt settings"; type = types.submodule { imports = hookModule; options.settings = { @@ -475,7 +475,7 @@ in }; }; headache = mkOption { - description = ""; + description = lib.mdDoc "Additional headache settings"; type = types.submodule { imports = hookModule; options.settings = { @@ -488,7 +488,7 @@ in }; }; hlint = mkOption { - description = ""; + description = lib.mdDoc "Additional hlint settings"; type = types.submodule { imports = hookModule; options.settings = { @@ -502,7 +502,7 @@ in }; }; hpack = mkOption { - description = ""; + description = lib.mdDoc "Additional hpack settings"; type = types.submodule { imports = hookModule; options.settings = { @@ -516,7 +516,7 @@ in }; }; isort = mkOption { - description = ""; + description = lib.mdDoc "Additional isort settings"; type = types.submodule { imports = hookModule; options.settings = { @@ -536,7 +536,7 @@ in }; }; latexindent = mkOption { - description = ""; + description = lib.mdDoc "Additional latexindent settings"; type = types.submodule { imports = hookModule; options.settings = { @@ -550,7 +550,7 @@ in }; }; lua-ls = mkOption { - description = ""; + description = lib.mdDoc "Additional lua-ls settings"; type = types.submodule { imports = hookModule; options.settings = { @@ -570,7 +570,7 @@ in }; }; lychee = mkOption { - description = ""; + description = lib.mdDoc "Additional lychee settings"; type = types.submodule { imports = hookModule; options.settings = { @@ -590,7 +590,7 @@ in }; }; markdownlint = mkOption { - description = ""; + description = lib.mdDoc "Additional markdownlint settings"; type = types.submodule { imports = hookModule; options.settings = { @@ -605,7 +605,7 @@ in }; }; mdl = mkOption { - description = ""; + description = lib.mdDoc "Additional mdl settings"; type = types.submodule { imports = hookModule; options.settings = { @@ -685,7 +685,7 @@ in }; }; mkdocs-linkcheck = mkOption { - description = ""; + description = lib.mdDoc "Additional mkdocs-linkcheck settings"; type = types.submodule { imports = hookModule; options.settings = { @@ -737,7 +737,7 @@ in }; }; mypy = mkOption { - description = ""; + description = lib.mdDoc "Additional mypy settings"; type = types.submodule { imports = hookModule; options.settings = { @@ -754,7 +754,7 @@ in }; }; nixfmt = mkOption { - description = ""; + description = lib.mdDoc "Additional nixfmt settings"; type = types.submodule { imports = hookModule; options.settings = { @@ -768,7 +768,7 @@ in }; }; ormolu = mkOption { - description = ""; + description = lib.mdDoc "Additional ormolu settings"; type = types.submodule { imports = hookModule; options.settings = { @@ -788,7 +788,7 @@ in }; }; php-cs-fixer = mkOption { - description = ""; + description = lib.mdDoc "Additional php-cs-fixer settings"; type = types.submodule { imports = hookModule; options.settings = { @@ -805,7 +805,7 @@ in }; }; phpcbf = mkOption { - description = ""; + description = lib.mdDoc "Additional phpcbf settings"; type = types.submodule { imports = hookModule; options.settings = { @@ -822,7 +822,7 @@ in }; }; phpcs = mkOption { - description = ""; + description = lib.mdDoc "Additional phpcs settings"; type = types.submodule { imports = hookModule; options.settings = { @@ -839,7 +839,7 @@ in }; }; phpstan = mkOption { - description = ""; + description = lib.mdDoc "Additional phpstan settings"; type = types.submodule { imports = hookModule; options.settings = { @@ -858,7 +858,7 @@ in # See all CLI flags for prettier [here](https://prettier.io/docs/en/cli.html). # See all options for prettier [here](https://prettier.io/docs/en/options.html). prettier = mkOption { - description = ""; + description = lib.mdDoc "Additional prettier settings"; type = types.submodule { imports = hookModule; options.settings = { @@ -1101,7 +1101,7 @@ in }; }; psalm = mkOption { - description = ""; + description = lib.mdDoc "Additional psalm settings"; type = types.submodule { imports = hookModule; options.settings = { @@ -1118,7 +1118,7 @@ in }; }; pylint = mkOption { - description = ""; + description = lib.mdDoc "Additional pylint settings"; type = types.submodule { imports = hookModule; options.settings = { @@ -1147,7 +1147,7 @@ in }; }; pyright = mkOption { - description = ""; + description = lib.mdDoc "Additional pyright settings"; type = types.submodule { imports = hookModule; options.settings = { @@ -1164,7 +1164,7 @@ in }; }; pyupgrade = mkOption { - description = ""; + description = lib.mdDoc "Additional pyupgrade settings"; type = types.submodule { imports = hookModule; options.settings = { @@ -1181,7 +1181,7 @@ in }; }; revive = mkOption { - description = ""; + description = lib.mdDoc "Additional revive settings"; type = types.submodule { imports = hookModule; options.settings = { @@ -1197,7 +1197,7 @@ in }; }; rome = mkOption { - description = ""; + description = lib.mdDoc "Additional rome settings"; type = types.submodule { imports = hookModule; options.settings = { @@ -1227,7 +1227,7 @@ in }; }; statix = mkOption { - description = ""; + description = lib.mdDoc "Additional statix settings"; type = types.submodule { imports = hookModule; options.settings = { @@ -1250,7 +1250,7 @@ in }; # TODO: how do we provide a default package for this? # treefmt = mkOption { - # description = ""; + # description = lib.mdDoc "Additional treefmt settings"; # type = types.submodule { # imports = hookModule; # options.settings = { @@ -1283,7 +1283,7 @@ in # }; # }; typos = mkOption { - description = ""; + description = lib.mdDoc "Additional typos settings"; type = types.submodule { imports = hookModule; options.settings = { @@ -1418,7 +1418,7 @@ in }; }; vale = mkOption { - description = ""; + description = lib.mdDoc "Additional vale settings"; type = types.submodule { imports = hookModule; options.settings = { @@ -1449,7 +1449,7 @@ in }; }; yamllint = mkOption { - description = ""; + description = lib.mdDoc "Additional yamllint settings"; type = types.submodule { imports = hookModule; options.settings = { From 6b2bed05a2dd0844b3cc12a2d0adf41abf40633e Mon Sep 17 00:00:00 2001 From: Sander Date: Sat, 9 Mar 2024 23:43:20 +0000 Subject: [PATCH 20/26] Add assertions and warnings to the pre-commit module --- modules/pre-commit.nix | 78 +++++++++++++++++++++++++++++++++--------- 1 file changed, 61 insertions(+), 17 deletions(-) diff --git a/modules/pre-commit.nix b/modules/pre-commit.nix index ab65bb3f..1c58447f 100644 --- a/modules/pre-commit.nix +++ b/modules/pre-commit.nix @@ -33,23 +33,25 @@ let mapAttrsToList (id: value: value.raw // { inherit id; }) enabledHooks; configFile = - runCommand "pre-commit-config.json" - { - buildInputs = [ - pkgs.jq - # needs to be an input so we regenerate the config and reinstall the hooks - # when the package changes - cfg.package - ]; - passAsFile = [ "rawJSON" ]; - rawJSON = builtins.toJSON cfg.rawConfig; - } '' - { - echo '# DO NOT MODIFY'; - echo '# This file was generated by pre-commit-hooks.nix'; - jq . <"$rawJSONPath" - } >$out - ''; + performAssertions ( + runCommand "pre-commit-config.json" + { + buildInputs = [ + pkgs.jq + # needs to be an input so we regenerate the config and reinstall the hooks + # when the package changes + cfg.package + ]; + passAsFile = [ "rawJSON" ]; + rawJSON = builtins.toJSON cfg.rawConfig; + } '' + { + echo '# DO NOT MODIFY'; + echo '# This file was generated by pre-commit-hooks.nix'; + jq . <"$rawJSONPath" + } >$out + '' + ); run = runCommand "pre-commit-run" { buildInputs = [ git ]; } '' @@ -80,6 +82,24 @@ let touch $out [ $? -eq 0 ] && exit $exitcode ''; + + failedAssertions = builtins.map (x: x.message) (builtins.filter (x: !x.assertion) config.assertions); + + performAssertions = + let + formatAssertionMessage = message: + let + lines = lib.splitString "\n" message; + in + "- ${lib.concatStringsSep "\n " lines}"; + in + if failedAssertions != [ ] + then + throw '' + Failed assertions: + ${lib.concatStringsSep "\n" (builtins.map formatAssertionMessage failedAssertions)} + '' + else lib.trivial.showWarnings config.warnings; in { options = @@ -243,6 +263,30 @@ in ''; internal = true; }; + + assertions = lib.mkOption { + type = types.listOf types.unspecified; + internal = true; + default = [ ]; + example = [{ assertion = false; message = "you can't enable this for that reason"; }]; + description = '' + This option allows modules to express conditions that must + hold for the evaluation of the configuration to succeed, + along with associated error messages for the user. + ''; + }; + + warnings = lib.mkOption { + type = types.listOf types.str; + internal = true; + default = [ ]; + example = [ "you should fix this or that" ]; + description = '' + This option allows modules to express warnings about the + configuration. For example, `lib.mkRenamedOptionModule` uses this to + display a warning message when a renamed option is used. + ''; + }; }; config = From bf780cc3809df61370c5c8ab42a6b8fa61704b40 Mon Sep 17 00:00:00 2001 From: Sander Date: Sun, 10 Mar 2024 02:30:06 +0000 Subject: [PATCH 21/26] Migrate binPath to use the package option by default --- modules/hook.nix | 4 +- modules/hooks.nix | 156 +++++++++++++++++++++++++--------------------- 2 files changed, 87 insertions(+), 73 deletions(-) diff --git a/modules/hook.nix b/modules/hook.nix index 2c5fb315..fa30af1f 100644 --- a/modules/hook.nix +++ b/modules/hook.nix @@ -45,10 +45,10 @@ in }; package = mkOption { - type = types.package; + type = types.nullOr types.package; description = lib.mdDoc '' - The package that provides the hook. + An optional package that provides the hook's dependencies. ''; }; diff --git a/modules/hooks.nix b/modules/hooks.nix index 099d938d..dee5cf76 100644 --- a/modules/hooks.nix +++ b/modules/hooks.nix @@ -26,6 +26,10 @@ let [ ] predActionList); + migrateBinPathToPackage = hook: binPath: + if hook.settings.binPath == null + then "${hook.package}${binPath}" + else hook.settings.binPath; in { imports = @@ -117,9 +121,9 @@ in options.settings = { binPath = mkOption { - type = types.str; + type = types.nullOr types.str; description = lib.mdDoc "Path to autoflake binary."; - default = "${tools.autoflake}/bin/autoflake"; + default = null; defaultText = lib.literalExpression '' "''${tools.autoflake}/bin/autoflake" ''; @@ -352,10 +356,10 @@ in options.settings = { binPath = mkOption { - type = types.path; + type = types.nullOr types.path; description = lib.mdDoc "`eslint` binary path. E.g. if you want to use the `eslint` in `node_modules`, use `./node_modules/.bin/eslint`."; - default = "${tools.eslint}/bin/eslint"; + default = null; defaultText = lib.literalExpression "\${tools.eslint}/bin/eslint"; }; @@ -376,9 +380,9 @@ in options.settings = { binPath = mkOption { - type = types.str; + type = types.nullOr types.str; description = lib.mdDoc "flake8 binary path. Should be used to specify flake8 binary from your Nix-managed Python environment."; - default = "${tools.flake8}/bin/flake8"; + default = null; defaultText = lib.literalExpression '' "''${tools.flake8}/bin/flake8" ''; @@ -412,9 +416,9 @@ in }; binPath = mkOption { - type = types.str; + type = types.nullOr types.str; description = lib.mdDoc "flynt binary path. Can be used to specify the flynt binary from an existing Python environment."; - default = "${hooks.flynt.package}/bin/flynt"; + default = null; defaultText = "\${hooks.flynt.package}/bin/flynt"; }; dry-run = @@ -691,9 +695,9 @@ in options.settings = { binPath = mkOption { - type = types.path; + type = types.nullOr types.path; description = lib.mdDoc "mkdocs-linkcheck binary path. Should be used to specify the mkdocs-linkcheck binary from your Nix-managed Python environment."; - default = "${tools.mkdocs-linkcheck}/bin/mkdocs-linkcheck"; + default = null; defaultText = lib.literalExpression '' "''${tools.mkdocs-linkcheck}/bin/mkdocs-linkcheck" ''; @@ -743,9 +747,9 @@ in options.settings = { binPath = mkOption { - type = types.str; + type = types.nullOr types.str; description = lib.mdDoc "Mypy binary path. Should be used to specify the mypy executable in an environment containing your typing stubs."; - default = "${tools.mypy}/bin/mypy"; + default = null; defaultText = lib.literalExpression '' "''${tools.mypy}/bin/mypy" ''; @@ -794,9 +798,9 @@ in options.settings = { binPath = mkOption { - type = types.str; + type = types.nullOr types.str; description = lib.mdDoc "PHP-CS-Fixer binary path."; - default = "${tools.php-cs-fixer}/bin/php-cs-fixer"; + default = null; defaultText = lib.literalExpression '' "''${tools.php-cs-fixer}/bin/php-cs-fixer" ''; @@ -811,9 +815,9 @@ in options.settings = { binPath = mkOption { - type = types.str; + type = types.nullOr types.str; description = lib.mdDoc "PHP_CodeSniffer binary path."; - default = "${tools.phpcbf}/bin/phpcbf"; + default = null; defaultText = lib.literalExpression '' "''${tools.phpcbf}/bin/phpcbf" ''; @@ -828,9 +832,9 @@ in options.settings = { binPath = mkOption { - type = types.str; + type = types.nullOr types.str; description = lib.mdDoc "PHP_CodeSniffer binary path."; - default = "${tools.phpcs}/bin/phpcs"; + default = null; defaultText = lib.literalExpression '' "''${tools.phpcs}/bin/phpcs" ''; @@ -845,9 +849,9 @@ in options.settings = { binPath = mkOption { - type = types.str; + type = types.nullOr types.str; description = lib.mdDoc "PHPStan binary path."; - default = "${tools.phpstan}/bin/phpstan"; + default = null; defaultText = lib.literalExpression '' "''${tools.phpstan}/bin/phpstan" ''; @@ -866,8 +870,8 @@ in mkOption { description = lib.mdDoc "`prettier` binary path. E.g. if you want to use the `prettier` in `node_modules`, use `./node_modules/.bin/prettier`."; - type = types.path; - default = "${tools.prettier}/bin/prettier"; + type = types.nullOr types.path; + default = null; defaultText = lib.literalExpression '' "''${tools.prettier}/bin/prettier" ''; @@ -1107,9 +1111,9 @@ in options.settings = { binPath = mkOption { - type = types.str; + type = types.nullOr types.str; description = lib.mdDoc "Psalm binary path."; - default = "${tools.psalm}/bin/psalm"; + default = null; defaultText = lib.literalExpression '' "''${tools.psalm}/bin/psalm" ''; @@ -1124,9 +1128,9 @@ in options.settings = { binPath = mkOption { - type = types.str; + type = types.nullOr types.str; description = lib.mdDoc "Pylint binary path. Should be used to specify Pylint binary from your Nix-managed Python environment."; - default = "${tools.pylint}/bin/pylint"; + default = null; defaultText = lib.literalExpression '' "''${tools.pylint}/bin/pylint" ''; @@ -1153,9 +1157,9 @@ in options.settings = { binPath = mkOption { - type = types.str; + type = types.nullOr types.str; description = lib.mdDoc "Pyright binary path. Should be used to specify the pyright executable in an environment containing your typing stubs."; - default = "${tools.pyright}/bin/pyright"; + default = null; defaultText = lib.literalExpression '' "''${tools.pyright}/bin/pyright" ''; @@ -1170,9 +1174,9 @@ in options.settings = { binPath = mkOption { - type = types.str; + type = types.nullOr types.str; description = lib.mdDoc "pyupgrade binary path. Should be used to specify the pyupgrade binary from your Nix-managed Python environment."; - default = "${tools.pyupgrade}/bin/pyupgrade"; + default = null; defaultText = lib.literalExpression '' "''${tools.pyupgrade}/bin/pyupgrade" ''; @@ -1203,9 +1207,9 @@ in options.settings = { binPath = mkOption { - type = types.path; + type = types.nullOr types.path; description = lib.mdDoc "`rome` binary path. E.g. if you want to use the `rome` in `node_modules`, use `./node_modules/.bin/rome`."; - default = "${tools.biome}/bin/biome"; + default = null; defaultText = "\${tools.biome}/bin/biome"; }; @@ -1527,9 +1531,12 @@ in { name = "autoflake"; description = "Remove unused imports and variables from Python code"; - # TODO: unused. see binPath. package = tools.autoflake; - entry = "${hooks.autoflake.settings.binPath} ${hooks.autoflake.settings.flags}"; + entry = + let + binPath = migrateBinPathToPackage hooks.autoflake "/bin/autoflake"; + in + "${binPath} ${hooks.autoflake.settings.flags}"; types = [ "python" ]; }; bats = @@ -1884,9 +1891,12 @@ in { name = "eslint"; description = "Find and fix problems in your JavaScript code."; - # TODO: unused. see binPath. package = tools.eslint; - entry = "${hooks.eslint.settings.binPath} --fix"; + entry = + let + binPath = migrateBinPathToPackage hooks.eslint "/bin/eslint"; + in + "${binPath} --fix"; files = "${hooks.eslint.settings.extensions}"; }; flake8 = @@ -1899,19 +1909,22 @@ in { name = "flake8"; description = "Check the style and quality of Python files."; - # unused. see binPath. package = tools.flake8; - entry = "${hooks.flake8.settings.binPath} --format ${hooks.flake8.settings.format} ${extendIgnoreStr}"; + entry = + let + binPath = migrateBinPathToPackage hooks.flake8 "/bin/flake8"; + in + "${binPath} --format ${hooks.flake8.settings.format} ${extendIgnoreStr}"; types = [ "python" ]; }; flynt = { name = "flynt"; description = "CLI tool to convert a python project's %-formatted strings to f-strings."; - # unused. see binPath. package = tools.flynt; entry = let + binPath = migrateBinPathToPackage hooks.flynt "/bin/flynt"; cmdArgs = mkCmdArgs (with hooks.flynt.settings; [ [ aggressive "--aggressive" ] @@ -1926,7 +1939,7 @@ in [ verbose "--verbose" ] ]); in - "${hooks.flynt.settings.binPath} ${cmdArgs}"; + "${binPath} ${cmdArgs}"; types = [ "python" ]; }; fourmolu = @@ -2317,10 +2330,10 @@ in mkdocs-linkcheck = { name = "mkdocs-linkcheck"; description = "Validate links associated with markdown-based, statically generated websites."; - # TODO: unused. see binPath. package = tools.mkdocs-linkcheck; entry = let + binPath = migrateBinPathToPackage hooks.mkdocs-linkcheck "/bin/mkdocs-linkcheck"; cmdArgs = mkCmdArgs (with hooks.mkdocs-linkcheck.settings; [ @@ -2331,17 +2344,15 @@ in [ (path != "") " ${path}" ] ]); in - # TODO: missing space? check cmdArgs - "${hooks.mkdocs-linkcheck.settings.binPath}${cmdArgs}"; + "${binPath}${cmdArgs}"; types = [ "text" "markdown" ]; }; mypy = { name = "mypy"; description = "Static type checker for Python"; - # TODO: unused. see binPath. package = tools.mypy; - entry = hooks.mypy.settings.binPath; + entry = migrateBinPathToPackage hooks.mypy "/bin/mypy"; files = "\\.py$"; }; nil = @@ -2422,9 +2433,11 @@ in { name = "php-cs-fixer"; description = "Lint PHP files."; - # TODO: unused. see binPath. package = tools.php-cs-fixer; - entry = with hooks.php-cs-fixer.settings; + entry = + let + binPath = migrateBinPathToPackage hooks.php-cs-fixer "/bin/php-cs-fixer"; + in "${binPath} fix"; types = [ "php" ]; }; @@ -2432,29 +2445,27 @@ in { name = "phpcbf"; description = "Lint PHP files."; - # TODO: unused. see binPath. package = tools.phpcbf; - entry = with hooks.phpcbf.settings; - "${binPath}"; + entry = migrateBinPathToPackage hooks.phpcbf "/bin/phpcbf"; types = [ "php" ]; }; phpcs = { name = "phpcs"; description = "Lint PHP files."; - # TODO: unused. see binPath. package = tools.phpcs; - entry = with hooks.phpcs.settings; - "${binPath}"; + entry = migrateBinPathToPackage hooks.phpcs "/bin/phpcs"; types = [ "php" ]; }; phpstan = { name = "phpstan"; description = "Static Analysis of PHP files."; - # TODO: unused. see binPath. package = tools.phpstan; - entry = with hooks.phpstan.settings; + entry = + let + binPath = migrateBinPathToPackage hooks.phpstan "/bin/phpstan"; + in "${binPath} analyse"; types = [ "php" ]; }; @@ -2480,10 +2491,10 @@ in name = "prettier"; description = "Opinionated multi-language code formatter."; types = [ "text" ]; - # TODO: unused. see binPath. package = tools.prettier; entry = let + binPath = migrateBinPathToPackage hooks.prettier "/bin/prettier"; cmdArgs = mkCmdArgs (with hooks.prettier.settings; [ @@ -2526,16 +2537,14 @@ in [ write "--write" ] ]); in - "${hooks.prettier.settings.binPath} ${cmdArgs}"; + "${binPath} ${cmdArgs}"; }; psalm = { name = "psalm"; description = "Static Analysis of PHP files."; - # TODO: unused. see binPath. package = tools.psalm; - entry = with hooks.psalm.settings; - "${binPath}"; + entry = migrateBinPathToPackage hooks.psalm "/bin/psalm"; types = [ "php" ]; }; purs-tidy = @@ -2558,29 +2567,34 @@ in { name = "pylint"; description = "Lint Python files."; - # TODO: unused. see binPath. package = tools.pylint; - entry = with hooks.pylint.settings; - "${binPath} ${lib.optionalString reports "-ry"} ${lib.optionalString (! score) "-sn"}"; + entry = + let + binPath = migrateBinPathToPackage hooks.pylint "/bin/pylint"; + cmdArgs = + mkCmdArgs + (with hooks.pylint.settings; [ + [ reports "-ry" ] + [ (! score) "-sn" ] + ]); + in + "${binPath} ${cmdArgs}"; types = [ "python" ]; }; pyright = { name = "pyright"; description = "Static type checker for Python"; - # TODO: unused. see binPath. package = tools.pyright; - entry = hooks.pyright.settings.binPath; + entry = migrateBinPathToPackage hooks.pyright "/bin/pyright"; files = "\\.py$"; }; pyupgrade = { name = "pyupgrade"; description = "Automatically upgrade syntax for newer versions."; - # TODO: unused. see binPath. package = tools.pyupgrade; - entry = with hooks.pyupgrade.settings; - "${binPath}"; + entry = migrateBinPathToPackage hooks.pyupgrade "/bin/pyupgrade"; types = [ "python" ]; }; revive = @@ -2617,17 +2631,17 @@ in name = "rome"; description = "Unified developer tools for JavaScript, TypeScript, and the web"; types_or = [ "javascript" "jsx" "ts" "tsx" "json" ]; - # TODO: unused. see binPath. - package = tools.rome; + package = tools.biome; entry = let + binPath = migrateBinPathToPackage hooks.rome "/bin/biome"; cmdArgs = mkCmdArgs [ [ (hooks.rome.settings.write) "--apply" ] [ (hooks.rome.settings.configPath != "") "--config-path ${hooks.rome.settings.configPath}" ] ]; in - "${hooks.rome.settings.binPath} check ${cmdArgs}"; + "${binPath} check ${cmdArgs}"; }; ruff = { From 6b4052594b3428b20e8085d41c23555e11de807f Mon Sep 17 00:00:00 2001 From: Sander Date: Sun, 10 Mar 2024 02:38:19 +0000 Subject: [PATCH 22/26] Add a todo for treefmt --- modules/hooks.nix | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/modules/hooks.nix b/modules/hooks.nix index dee5cf76..b51765ad 100644 --- a/modules/hooks.nix +++ b/modules/hooks.nix @@ -1252,7 +1252,8 @@ in }; }; }; - # TODO: how do we provide a default package for this? + # TODO: should this be an option like `packages` or `formatters`? + # A list of packages to wrap in an env with treefmt. # treefmt = mkOption { # description = lib.mdDoc "Additional treefmt settings"; # type = types.submodule { From 0b32cd7a293c325be07f88a33568d50271521132 Mon Sep 17 00:00:00 2001 From: Sander Date: Fri, 15 Mar 2024 00:19:13 +0000 Subject: [PATCH 23/26] Add packageInputs to allow overriding complex wrapper hooks --- modules/hook.nix | 13 +++++- modules/hooks.nix | 107 +++++++++++++++++++++++++++------------------- 2 files changed, 76 insertions(+), 44 deletions(-) diff --git a/modules/hook.nix b/modules/hook.nix index fa30af1f..04a2d4c3 100644 --- a/modules/hook.nix +++ b/modules/hook.nix @@ -48,7 +48,18 @@ in type = types.nullOr types.package; description = lib.mdDoc '' - An optional package that provides the hook's dependencies. + The package that provides the hook. + ''; + }; + + packageInputs = mkOption { + type = types.submodule { + freeformType = types.attrsOf types.package; + }; + default = { }; + description = lib.mdDoc + '' + Additional inputs required to construct the hook package. ''; }; diff --git a/modules/hooks.nix b/modules/hooks.nix index b51765ad..d08c42c5 100644 --- a/modules/hooks.nix +++ b/modules/hooks.nix @@ -1,9 +1,7 @@ { config, lib, pkgs, ... }: let - inherit (config) tools; + inherit (config) hooks tools settings; cfg = config; - hooks = config.hooks; - settings = config.settings; inherit (lib) flatten mapAttrs mapAttrsToList mkDefault mkOption mkRenamedOptionModule types; hookModule = @@ -142,6 +140,16 @@ in description = lib.mdDoc "Additional clippy settings"; type = types.submodule { imports = hookModule; + options.packageInputs = { + cargo = mkOption { + type = types.package; + description = lib.mdDoc "The cargo package to use for clippy"; + }; + clippy = mkOption { + type = types.package; + description = lib.mdDoc "The clippy package to use for clippy"; + }; + }; options.settings = { denyWarnings = mkOption { type = types.bool; @@ -1230,6 +1238,22 @@ in }; }; }; + rustfmt = mkOption { + description = lib.mdDoc "Additional rustfmt settings"; + type = types.submodule { + imports = hookModule; + options.packageInputs = { + cargo = mkOption { + type = types.package; + description = lib.mdDoc "The cargo package to use."; + }; + rustfmt = mkOption { + type = types.package; + description = lib.mdDoc "The rustfmt package to use."; + }; + }; + }; + }; statix = mkOption { description = lib.mdDoc "Additional statix settings"; type = types.submodule { @@ -1252,41 +1276,18 @@ in }; }; }; - # TODO: should this be an option like `packages` or `formatters`? - # A list of packages to wrap in an env with treefmt. - # treefmt = mkOption { - # description = lib.mdDoc "Additional treefmt settings"; - # type = types.submodule { - # imports = hookModule; - # options.settings = { - # package = mkOption { - # type = types.package; - # description = lib.mdDoc - # '' - # The `treefmt` package to use. - # - # Should include all the formatters configured by treefmt. - # - # For example: - # ```nix - # pkgs.writeShellApplication { - # name = "treefmt"; - # runtimeInputs = [ - # pkgs.treefmt - # pkgs.nixpkgs-fmt - # pkgs.black - # ]; - # text = - # ''' - # exec treefmt "$@" - # '''; - # } - # ``` - # ''; - # }; - # }; - # }; - # }; + treefmt = mkOption { + description = lib.mdDoc "Additional treefmt settings"; + type = types.submodule { + imports = hookModule; + options.packageInputs = { + treefmt = mkOption { + type = types.package; + description = lib.mdDoc "The treefmt package to use."; + }; + }; + }; + }; typos = mkOption { description = lib.mdDoc "Additional typos settings"; type = types.submodule { @@ -1640,13 +1641,14 @@ in }; clippy = let + inherit (hooks.clippy) packageInputs; wrapper = pkgs.symlinkJoin { name = "clippy-wrapped"; - paths = [ tools.clippy ]; + paths = [ packageInputs.clippy ]; nativeBuildInputs = [ pkgs.makeWrapper ]; postBuild = '' wrapProgram $out/bin/cargo-clippy \ - --prefix PATH : ${lib.makeBinPath [ tools.cargo ]} + --prefix PATH : ${lib.makeBinPath [ packageInputs.cargo ]} ''; }; in @@ -1654,6 +1656,7 @@ in name = "clippy"; description = "Lint Rust code."; package = wrapper; + packageInputs = { cargo = tools.cargo; clippy = tools.clippy; }; entry = "${hooks.clippy.package}/bin/cargo-clippy clippy ${cargoManifestPathArg} ${lib.optionalString hooks.clippy.settings.offline "--offline"} ${lib.optionalString hooks.clippy.settings.allFeatures "--all-features"} -- ${lib.optionalString hooks.clippy.settings.denyWarnings "-D warnings"}"; files = "\\.rs$"; pass_filenames = false; @@ -2654,13 +2657,14 @@ in }; rustfmt = let + inherit (hooks.rustfmt) packageInputs; wrapper = pkgs.symlinkJoin { name = "rustfmt-wrapped"; - paths = [ tools.rustfmt ]; + paths = [ packageInputs.rustfmt ]; nativeBuildInputs = [ pkgs.makeWrapper ]; postBuild = '' wrapProgram $out/bin/cargo-fmt \ - --prefix PATH : ${lib.makeBinPath [ tools.cargo tools.rustfmt ]} + --prefix PATH : ${lib.makeBinPath [ packageInputs.cargo packageInputs.rustfmt ]} ''; }; in @@ -2668,6 +2672,7 @@ in name = "rustfmt"; description = "Format Rust code."; package = wrapper; + packageInputs = { cargo = tools.cargo; rustfmt = tools.rustfmt; }; entry = "${hooks.rustfmt.package}/bin/cargo-fmt fmt ${cargoManifestPathArg} -- --color always"; files = "\\.rs$"; pass_filenames = false; @@ -2803,12 +2808,28 @@ in files = "(\\.json$)|(\\.toml$)|(\\.mli?$)"; }; treefmt = + let + inherit (hooks.treefmt) packageInputs; + wrapper = + pkgs.writeShellApplication { + name = "treefmt"; + runtimeInputs = [ + packageInputs.treefmt + ] ++ builtins.attrValues (builtins.removeAttrs packageInputs [ "treefmt" ]); + + text = + '' + exec treefmt "$@" + ''; + }; + in { name = "treefmt"; description = "One CLI to format the code tree."; types = [ "file" ]; pass_filenames = true; - package = tools.treefmt; + package = wrapper; + packageInputs = { treefmt = tools.treefmt; }; entry = "${hooks.treefmt.package}/bin/treefmt --fail-on-change"; }; typos = From df4a2111ffded723a6fe466b218d22d1ddca5d28 Mon Sep 17 00:00:00 2001 From: Sander Date: Mon, 18 Mar 2024 22:45:23 +0000 Subject: [PATCH 24/26] Implement packageOverrides and add formatters to treefmt --- modules/hook.nix | 24 ++++++++++++---- modules/hooks.nix | 73 ++++++++++++++++++++++++++++++++++------------- 2 files changed, 72 insertions(+), 25 deletions(-) diff --git a/modules/hook.nix b/modules/hook.nix index 04a2d4c3..3c353e46 100644 --- a/modules/hook.nix +++ b/modules/hook.nix @@ -31,7 +31,7 @@ in default = name; description = lib.mdDoc '' - The name of the hook - shown during hook execution. + The name of the hook. Shown during hook execution. ''; }; @@ -39,7 +39,7 @@ in type = types.str; description = lib.mdDoc '' - Description of the hook. used for metadata purposes only. + Description of the hook. Used for metadata purposes only. ''; default = ""; }; @@ -48,18 +48,32 @@ in type = types.nullOr types.package; description = lib.mdDoc '' - The package that provides the hook. + An optional package that provides the hook. + + For most hooks, the package name matches the name of the hook and can be overriden directly. + + ``` + hooks.nixfmt.package = pkgs.nixfmt; + ``` + + Some hooks may require multiple packages or a wrapper script to function correctly. + Such hooks can expose additional named packages as `packageOverrides`. + + ``` + hooks.rustfmt.packageOverrides.cargo = pkgs.cargo; + hooks.rustfmt.packageOverrides.rustfmt = pkgs.rustfmt; + ``` ''; }; - packageInputs = mkOption { + packageOverrides = mkOption { type = types.submodule { freeformType = types.attrsOf types.package; }; default = { }; description = lib.mdDoc '' - Additional inputs required to construct the hook package. + Additional packages required to construct the hook package. ''; }; diff --git a/modules/hooks.nix b/modules/hooks.nix index d08c42c5..1625a62e 100644 --- a/modules/hooks.nix +++ b/modules/hooks.nix @@ -140,14 +140,14 @@ in description = lib.mdDoc "Additional clippy settings"; type = types.submodule { imports = hookModule; - options.packageInputs = { + options.packageOverrides = { cargo = mkOption { type = types.package; - description = lib.mdDoc "The cargo package to use for clippy"; + description = lib.mdDoc "The cargo package to use"; }; clippy = mkOption { type = types.package; - description = lib.mdDoc "The clippy package to use for clippy"; + description = lib.mdDoc "The clippy package to use"; }; }; options.settings = { @@ -1239,10 +1239,19 @@ in }; }; rustfmt = mkOption { - description = lib.mdDoc "Additional rustfmt settings"; + description = lib.mdDoc '' + Additional rustfmt settings + + Override the `rustfmt` and `cargo` packages by setting `hooks.rustfmt.packageOverrides`. + + ``` + hooks.rustfmt.packageOverrides.cargo = pkgs.cargo; + hooks.rustfmt.packageOverrides.rustfmt = pkgs.rustfmt; + ``` + ''; type = types.submodule { imports = hookModule; - options.packageInputs = { + options.packageOverrides = { cargo = mkOption { type = types.package; description = lib.mdDoc "The cargo package to use."; @@ -1277,13 +1286,37 @@ in }; }; treefmt = mkOption { - description = lib.mdDoc "Additional treefmt settings"; + description = lib.mdDoc '' + Treefmt hook. + + Include any additional formatters configured by treefmt as `hooks.treefmt.settings.formatters`. + + ``` + hooks.treefmt.settings.formatters = [ + pkgs.nixpkgs-fmt + pkgs.black + ]; + ``` + + Override `treefmt` itself by setting `hooks.treefmt.packageOverrides.treefmt`. + + ``` + hooks.treefmt.packageOverrides.treefmt = pkgs.treefmt; + ``` + ''; type = types.submodule { imports = hookModule; - options.packageInputs = { + options.packageOverrides = { treefmt = mkOption { type = types.package; - description = lib.mdDoc "The treefmt package to use."; + description = lib.mdDoc "The treefmt package to use"; + }; + }; + options.settings = { + formatters = mkOption { + type = types.listOf types.package; + description = lib.mdDoc "The formatter packages configured by treefmt"; + default = [ ]; }; }; }; @@ -1641,14 +1674,14 @@ in }; clippy = let - inherit (hooks.clippy) packageInputs; + inherit (hooks.clippy) packageOverrides; wrapper = pkgs.symlinkJoin { name = "clippy-wrapped"; - paths = [ packageInputs.clippy ]; + paths = [ packageOverrides.clippy ]; nativeBuildInputs = [ pkgs.makeWrapper ]; postBuild = '' wrapProgram $out/bin/cargo-clippy \ - --prefix PATH : ${lib.makeBinPath [ packageInputs.cargo ]} + --prefix PATH : ${lib.makeBinPath [ packageOverrides.cargo ]} ''; }; in @@ -1656,7 +1689,7 @@ in name = "clippy"; description = "Lint Rust code."; package = wrapper; - packageInputs = { cargo = tools.cargo; clippy = tools.clippy; }; + packageOverrides = { cargo = tools.cargo; clippy = tools.clippy; }; entry = "${hooks.clippy.package}/bin/cargo-clippy clippy ${cargoManifestPathArg} ${lib.optionalString hooks.clippy.settings.offline "--offline"} ${lib.optionalString hooks.clippy.settings.allFeatures "--all-features"} -- ${lib.optionalString hooks.clippy.settings.denyWarnings "-D warnings"}"; files = "\\.rs$"; pass_filenames = false; @@ -2657,14 +2690,14 @@ in }; rustfmt = let - inherit (hooks.rustfmt) packageInputs; + inherit (hooks.rustfmt) packageOverrides; wrapper = pkgs.symlinkJoin { name = "rustfmt-wrapped"; - paths = [ packageInputs.rustfmt ]; + paths = [ packageOverrides.rustfmt ]; nativeBuildInputs = [ pkgs.makeWrapper ]; postBuild = '' wrapProgram $out/bin/cargo-fmt \ - --prefix PATH : ${lib.makeBinPath [ packageInputs.cargo packageInputs.rustfmt ]} + --prefix PATH : ${lib.makeBinPath [ packageOverrides.cargo packageOverrides.rustfmt ]} ''; }; in @@ -2672,7 +2705,7 @@ in name = "rustfmt"; description = "Format Rust code."; package = wrapper; - packageInputs = { cargo = tools.cargo; rustfmt = tools.rustfmt; }; + packageOverrides = { cargo = tools.cargo; rustfmt = tools.rustfmt; }; entry = "${hooks.rustfmt.package}/bin/cargo-fmt fmt ${cargoManifestPathArg} -- --color always"; files = "\\.rs$"; pass_filenames = false; @@ -2809,13 +2842,13 @@ in }; treefmt = let - inherit (hooks.treefmt) packageInputs; + inherit (hooks.treefmt) packageOverrides settings; wrapper = pkgs.writeShellApplication { name = "treefmt"; runtimeInputs = [ - packageInputs.treefmt - ] ++ builtins.attrValues (builtins.removeAttrs packageInputs [ "treefmt" ]); + packageOverrides.treefmt + ] ++ settings.formatters; text = '' @@ -2829,7 +2862,7 @@ in types = [ "file" ]; pass_filenames = true; package = wrapper; - packageInputs = { treefmt = tools.treefmt; }; + packageOverrides = { treefmt = tools.treefmt; }; entry = "${hooks.treefmt.package}/bin/treefmt --fail-on-change"; }; typos = From b9fb64c31a82d2b681a561db8c9e09c0a13ca594 Mon Sep 17 00:00:00 2001 From: Sander Date: Mon, 18 Mar 2024 22:47:23 +0000 Subject: [PATCH 25/26] Update hook descriptions --- modules/hooks.nix | 84 +++++++++++++++++++++++------------------------ 1 file changed, 42 insertions(+), 42 deletions(-) diff --git a/modules/hooks.nix b/modules/hooks.nix index 1625a62e..36204179 100644 --- a/modules/hooks.nix +++ b/modules/hooks.nix @@ -57,7 +57,7 @@ in options.hooks = { alejandra = mkOption { - description = lib.mdDoc "Additional alejandra settings"; + description = lib.mdDoc "alejandra hook"; type = types.submodule { imports = hookModule; options.settings = { @@ -93,7 +93,7 @@ in }; }; ansible-lint = mkOption { - description = lib.mdDoc "Additional ansible-lint settings"; + description = lib.mdDoc "ansible-lint hook"; type = types.submodule { imports = hookModule; options.settings = { @@ -113,7 +113,7 @@ in }; }; autoflake = mkOption { - description = lib.mdDoc "Additional autoflake settings"; + description = lib.mdDoc "autoflake hook"; type = types.submodule { imports = hookModule; options.settings = { @@ -137,7 +137,7 @@ in }; }; clippy = mkOption { - description = lib.mdDoc "Additional clippy settings"; + description = lib.mdDoc "clippy hook"; type = types.submodule { imports = hookModule; options.packageOverrides = { @@ -170,7 +170,7 @@ in }; }; cmake-format = mkOption { - description = lib.mdDoc "Additional cmake-format settings"; + description = lib.mdDoc "cmake-format hook"; type = types.submodule { imports = hookModule; options.settings = { @@ -184,7 +184,7 @@ in }; }; credo = mkOption { - description = lib.mdDoc "Additional credo settings"; + description = lib.mdDoc "credo hook"; type = types.submodule { imports = hookModule; options.settings = { @@ -198,7 +198,7 @@ in }; }; deadnix = mkOption { - description = lib.mdDoc "Additional deadnix settings"; + description = lib.mdDoc "deadnix hook"; type = types.submodule { imports = hookModule; options.settings = { @@ -254,7 +254,7 @@ in }; }; denofmt = mkOption { - description = lib.mdDoc "Additional denofmt settings"; + description = lib.mdDoc "denofmt hook"; type = types.submodule { imports = hookModule; options.settings = { @@ -276,7 +276,7 @@ in }; }; denolint = mkOption { - description = lib.mdDoc "Additional denolint settings"; + description = lib.mdDoc "denolint hook"; type = types.submodule { imports = hookModule; options.settings = { @@ -299,7 +299,7 @@ in }; }; dune-fmt = mkOption { - description = lib.mdDoc "Additional dune-fmt settings"; + description = lib.mdDoc "dune-fmt hook"; type = types.submodule { imports = hookModule; options.settings = { @@ -320,7 +320,7 @@ in }; }; eclint = mkOption { - description = lib.mdDoc "Additional eclint settings"; + description = lib.mdDoc "eclint hook"; type = types.submodule { imports = hookModule; options.settings = { @@ -358,7 +358,7 @@ in }; }; eslint = mkOption { - description = lib.mdDoc "Additional eslint settings"; + description = lib.mdDoc "eslint hook"; type = types.submodule { imports = hookModule; options.settings = { @@ -382,7 +382,7 @@ in }; }; flake8 = mkOption { - description = lib.mdDoc "Additional flake8 settings"; + description = lib.mdDoc "flake8 hook"; type = types.submodule { imports = hookModule; options.settings = { @@ -412,7 +412,7 @@ in }; }; flynt = mkOption { - description = lib.mdDoc "Additional flynt settings"; + description = lib.mdDoc "flynt hook"; type = types.submodule { imports = hookModule; options.settings = { @@ -487,7 +487,7 @@ in }; }; headache = mkOption { - description = lib.mdDoc "Additional headache settings"; + description = lib.mdDoc "headache hook"; type = types.submodule { imports = hookModule; options.settings = { @@ -500,7 +500,7 @@ in }; }; hlint = mkOption { - description = lib.mdDoc "Additional hlint settings"; + description = lib.mdDoc "hlint hook"; type = types.submodule { imports = hookModule; options.settings = { @@ -514,7 +514,7 @@ in }; }; hpack = mkOption { - description = lib.mdDoc "Additional hpack settings"; + description = lib.mdDoc "hpack hook"; type = types.submodule { imports = hookModule; options.settings = { @@ -528,7 +528,7 @@ in }; }; isort = mkOption { - description = lib.mdDoc "Additional isort settings"; + description = lib.mdDoc "isort hook"; type = types.submodule { imports = hookModule; options.settings = { @@ -548,7 +548,7 @@ in }; }; latexindent = mkOption { - description = lib.mdDoc "Additional latexindent settings"; + description = lib.mdDoc "latexindent hook"; type = types.submodule { imports = hookModule; options.settings = { @@ -562,7 +562,7 @@ in }; }; lua-ls = mkOption { - description = lib.mdDoc "Additional lua-ls settings"; + description = lib.mdDoc "lua-ls hook"; type = types.submodule { imports = hookModule; options.settings = { @@ -582,7 +582,7 @@ in }; }; lychee = mkOption { - description = lib.mdDoc "Additional lychee settings"; + description = lib.mdDoc "lychee hook"; type = types.submodule { imports = hookModule; options.settings = { @@ -602,7 +602,7 @@ in }; }; markdownlint = mkOption { - description = lib.mdDoc "Additional markdownlint settings"; + description = lib.mdDoc "markdownlint hook"; type = types.submodule { imports = hookModule; options.settings = { @@ -617,7 +617,7 @@ in }; }; mdl = mkOption { - description = lib.mdDoc "Additional mdl settings"; + description = lib.mdDoc "mdl hook"; type = types.submodule { imports = hookModule; options.settings = { @@ -697,7 +697,7 @@ in }; }; mkdocs-linkcheck = mkOption { - description = lib.mdDoc "Additional mkdocs-linkcheck settings"; + description = lib.mdDoc "mkdocs-linkcheck hook"; type = types.submodule { imports = hookModule; options.settings = { @@ -749,7 +749,7 @@ in }; }; mypy = mkOption { - description = lib.mdDoc "Additional mypy settings"; + description = lib.mdDoc "mypy hook"; type = types.submodule { imports = hookModule; options.settings = { @@ -766,7 +766,7 @@ in }; }; nixfmt = mkOption { - description = lib.mdDoc "Additional nixfmt settings"; + description = lib.mdDoc "nixfmt hook"; type = types.submodule { imports = hookModule; options.settings = { @@ -780,7 +780,7 @@ in }; }; ormolu = mkOption { - description = lib.mdDoc "Additional ormolu settings"; + description = lib.mdDoc "ormolu hook"; type = types.submodule { imports = hookModule; options.settings = { @@ -800,7 +800,7 @@ in }; }; php-cs-fixer = mkOption { - description = lib.mdDoc "Additional php-cs-fixer settings"; + description = lib.mdDoc "php-cs-fixer hook"; type = types.submodule { imports = hookModule; options.settings = { @@ -817,7 +817,7 @@ in }; }; phpcbf = mkOption { - description = lib.mdDoc "Additional phpcbf settings"; + description = lib.mdDoc "phpcbf hook"; type = types.submodule { imports = hookModule; options.settings = { @@ -834,7 +834,7 @@ in }; }; phpcs = mkOption { - description = lib.mdDoc "Additional phpcs settings"; + description = lib.mdDoc "phpcs hook"; type = types.submodule { imports = hookModule; options.settings = { @@ -851,7 +851,7 @@ in }; }; phpstan = mkOption { - description = lib.mdDoc "Additional phpstan settings"; + description = lib.mdDoc "phpstan hook"; type = types.submodule { imports = hookModule; options.settings = { @@ -870,7 +870,7 @@ in # See all CLI flags for prettier [here](https://prettier.io/docs/en/cli.html). # See all options for prettier [here](https://prettier.io/docs/en/options.html). prettier = mkOption { - description = lib.mdDoc "Additional prettier settings"; + description = lib.mdDoc "prettier hook"; type = types.submodule { imports = hookModule; options.settings = { @@ -1113,7 +1113,7 @@ in }; }; psalm = mkOption { - description = lib.mdDoc "Additional psalm settings"; + description = lib.mdDoc "psalm hook"; type = types.submodule { imports = hookModule; options.settings = { @@ -1130,7 +1130,7 @@ in }; }; pylint = mkOption { - description = lib.mdDoc "Additional pylint settings"; + description = lib.mdDoc "pylint hook"; type = types.submodule { imports = hookModule; options.settings = { @@ -1159,7 +1159,7 @@ in }; }; pyright = mkOption { - description = lib.mdDoc "Additional pyright settings"; + description = lib.mdDoc "pyright hook"; type = types.submodule { imports = hookModule; options.settings = { @@ -1176,7 +1176,7 @@ in }; }; pyupgrade = mkOption { - description = lib.mdDoc "Additional pyupgrade settings"; + description = lib.mdDoc "pyupgrade hook"; type = types.submodule { imports = hookModule; options.settings = { @@ -1193,7 +1193,7 @@ in }; }; revive = mkOption { - description = lib.mdDoc "Additional revive settings"; + description = lib.mdDoc "revive hook"; type = types.submodule { imports = hookModule; options.settings = { @@ -1209,7 +1209,7 @@ in }; }; rome = mkOption { - description = lib.mdDoc "Additional rome settings"; + description = lib.mdDoc "rome hook"; type = types.submodule { imports = hookModule; options.settings = { @@ -1264,7 +1264,7 @@ in }; }; statix = mkOption { - description = lib.mdDoc "Additional statix settings"; + description = lib.mdDoc "statix hook"; type = types.submodule { imports = hookModule; options.settings = { @@ -1322,7 +1322,7 @@ in }; }; typos = mkOption { - description = lib.mdDoc "Additional typos settings"; + description = lib.mdDoc "typos hook"; type = types.submodule { imports = hookModule; options.settings = { @@ -1457,7 +1457,7 @@ in }; }; vale = mkOption { - description = lib.mdDoc "Additional vale settings"; + description = lib.mdDoc "vale hook"; type = types.submodule { imports = hookModule; options.settings = { @@ -1488,7 +1488,7 @@ in }; }; yamllint = mkOption { - description = lib.mdDoc "Additional yamllint settings"; + description = lib.mdDoc "yamllint hook"; type = types.submodule { imports = hookModule; options.settings = { From fc79a53eceac62d582fd0f4a098aae065106f619 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Domen=20Ko=C5=BEar?= Date: Tue, 19 Mar 2024 03:46:37 +0000 Subject: [PATCH 26/26] README: refresh --- README.md | 105 ++++++++++++++++++++++++++++++------------------------ 1 file changed, 58 insertions(+), 47 deletions(-) diff --git a/README.md b/README.md index 07468ab8..5bb86123 100644 --- a/README.md +++ b/README.md @@ -2,16 +2,17 @@ ![pre-commit.png](pre-commit.png) -The goal is to **manage commit hooks with Nix** and solve the following: +## Features - **Trivial integration for Nix projects** (wires up a few things behind the scenes) - Provide a low-overhead build of all the tooling available for the hooks to use (naive implementation of calling nix-shell does bring some latency when committing) -- **Common hooks for languages** like Python, Haskell, Elm, etc. +- **Common hooks for languages** like Python, Haskell, Elm, etc. [see all hook options](https://devenv.sh/?q=pre-commit.hooks) + +- Run hooks **as part of development** and **on during CI** -- Run hooks **as part of development** and **on your CI** # Getting started @@ -19,6 +20,50 @@ The goal is to **manage commit hooks with Nix** and solve the following: https://devenv.sh/pre-commit-hooks/ +## Flakes support + +Given the following `flake.nix` example: + +```nix +{ + description = "An example project."; + + inputs.pre-commit-hooks.url = "github:cachix/pre-commit-hooks.nix"; + inputs.flake-utils.url = "github:numtide/flake-utils"; + + outputs = { self, nixpkgs, pre-commit-hooks, flake-utils }: + flake-utils.lib.eachDefaultSystem (system: + { + checks = { + pre-commit-check = pre-commit-hooks.lib.${system}.run { + src = ./.; + hooks = { + nixpkgs-fmt.enable = true; + }; + }; + }; + devShell = nixpkgs.legacyPackages.${system}.mkShell { + inherit (self.checks.${system}.pre-commit-check) shellHook; + }; + } + ); +} +``` + +Add `/.pre-commit-config.yaml` to the `.gitignore`. + +To run the all the hooks on CI: + +```bash +nix flake check +``` + +To install pre-commit hooks developers would run: + +```bash +nix develop +``` + ## Nix 1. (optional) Use binary caches to avoid compilation: @@ -41,8 +86,17 @@ https://devenv.sh/pre-commit-hooks/ # default_stages = ["manual" "push"]; hooks = { elm-format.enable = true; + + # override a package with a different version ormolu.enable = true; - shellcheck.enable = true; + ormolu.package = pkgs.haskellPackages.ormolu; + + # some hooks have more than one package, like clippy: + clippy.enable = true; + clippy.packageOverrides.cargo = pkgs.cargo; + clippy.packageOverrides.clippy = tools.clippy; + # some hooks provide settings + clippy.settings.allFeatures = true; }; # Set the pkgs to get the tools for the hooks from. @@ -331,49 +385,6 @@ Example configuration: Custom hooks are defined with the same schema as [pre-defined hooks](modules/pre-commit.nix). -# Nix Flakes support - -Given the following `flake.nix` example: - -```nix -{ - description = "An example project."; - - inputs.pre-commit-hooks.url = "github:cachix/pre-commit-hooks.nix"; - inputs.flake-utils.url = "github:numtide/flake-utils"; - - outputs = { self, nixpkgs, pre-commit-hooks, flake-utils }: - flake-utils.lib.eachDefaultSystem (system: - { - checks = { - pre-commit-check = pre-commit-hooks.lib.${system}.run { - src = ./.; - hooks = { - nixpkgs-fmt.enable = true; - }; - }; - }; - devShell = nixpkgs.legacyPackages.${system}.mkShell { - inherit (self.checks.${system}.pre-commit-check) shellHook; - }; - } - ); -} -``` - -Add `/.pre-commit-config.yaml` to the `.gitignore`. - -To run the all the hooks on CI: - -```bash -nix flake check -``` - -To install pre-commit hooks developers would run: - -```bash -nix develop -``` # Contributing hooks