Skip to content

Commit 1273fa2

Browse files
committed
typos: fix unexpected behaviour
Use excludes from .typos.toml when running `pre-commit run typos --all-files`. Since we don't set "pass_filenames = false" for typos (see upstream discussions [0]), we must ensure that pre-commit never passes the files specified as excludes in `.typos.toml` to `typos` as argument, if possible. Otherwise, `$ pre-commit run typos --all-files` has another behaviour than `$ typos .`, which is confusing and wrong. To not break anything, and to be compliant with the existing API, we encourage users to provide the `.typos.toml` as Nix path, so the excludes can be read via evaluation time. The `configAsFile` variable is the path where the configuration file can be found by the `typos` utility when it executes in the user environment. Not necessarily in Nix store. [0]: #387 (comment)
1 parent e8dc1b4 commit 1273fa2

File tree

1 file changed

+72
-3
lines changed

1 file changed

+72
-3
lines changed

modules/hooks.nix

+72-3
Original file line numberDiff line numberDiff line change
@@ -1340,10 +1340,11 @@ in
13401340
default = "auto";
13411341
};
13421342

1343+
# It is recommended to use `configFile`.
13431344
config =
13441345
mkOption {
13451346
type = types.str;
1346-
description = lib.mdDoc "Multiline-string configuration passed as config file. If set, config set in `typos.settings.configPath` gets ignored.";
1347+
description = lib.mdDoc "Multiline-string configuration passed as config file. If set, config set in `typos.settings.config{File|Path}` gets ignored.";
13471348
default = "";
13481349
example = ''
13491350
[files]
@@ -1357,6 +1358,22 @@ in
13571358
'';
13581359
};
13591360

1361+
# Recommended way to specifcy a config, as this way, exludes can be
1362+
# taken into account by pre-commit when running
1363+
# `$ pre-commit run --all-files`.
1364+
# We provide configFile and configPath for API compatibility with
1365+
# previous versions and coherence with other hooks defined here.
1366+
configFile =
1367+
mkOption {
1368+
type = types.nullOr types.path;
1369+
description = lib.mdDoc "Path to a typos config file (in Nix store).";
1370+
default = null;
1371+
example = "./.typos.toml";
1372+
};
1373+
1374+
# It is recommended to use `configFile` instead, as it provides more
1375+
# flexibility and a more correct/expected behaviour to what
1376+
# `$ typos .` does.
13601377
configPath =
13611378
mkOption {
13621379
type = types.str;
@@ -2866,6 +2883,57 @@ in
28662883
entry = "${hooks.treefmt.package}/bin/treefmt --fail-on-change";
28672884
};
28682885
typos =
2886+
let
2887+
# Since we don't set "pass_filenames = false" for typos (see
2888+
# upstream discussions [0]), we must ensure that pre-commit never
2889+
# passes the files specified as excludes in `.typos.toml` to
2890+
# `typos` as argument, if possible.
2891+
#
2892+
# Otherwise, `$ pre-commit run typos --all-files` has another
2893+
# behaviour than `$ typos .`, which is confusing and wrong.
2894+
#
2895+
# To not break anything, and to be compliant with the existing
2896+
# API, we encourage users to provide the `.typos.toml` as Nix
2897+
# path, so the excludes can be read via evaluation time.
2898+
#
2899+
# The `configAsFile` variable is the path where the configuration
2900+
# file can be found by the `typos` utility when it executes in the
2901+
# user environment. Not necessarily in Nix store.
2902+
#
2903+
# [0]: https://github.com/cachix/pre-commit-hooks.nix/pull/387#issuecomment-1893600631
2904+
configAsFile =
2905+
# Highest precedence.
2906+
if hooks.typos.settings.configFile != null
2907+
then (toString hooks.typos.settings.configFile)
2908+
# Secondary precedence.
2909+
else if hooks.typos.settings.configPath != ""
2910+
then hooks.typos.settings.configPath
2911+
# Lowest precedence.
2912+
else
2913+
builtins.toFile "config.toml"
2914+
# Concatenate config in config file with section for ignoring words
2915+
# generated from list of words to ignore
2916+
("${hooks.typos.settings.config}" +
2917+
lib.strings.optionalString (hooks.typos.settings.ignored-words != [ ]) "\n\[default.extend-words\]" +
2918+
lib.strings.concatMapStrings (x: "\n${x} = \"${x}\"") hooks.typos.settings.ignored-words
2919+
)
2920+
;
2921+
# If the config file path is passed as Nix string and not as Nix
2922+
# Path, we can't read it from Nix, unfortunately.
2923+
excludesFromConfig =
2924+
if hooks.typos.settings.configPath == "" # passed directly or as Path
2925+
then
2926+
(
2927+
let
2928+
toml = builtins.fromTOML (builtins.readFile configAsFile);
2929+
in
2930+
# The "files.extend-exclude" key comes from
2931+
# https://github.com/crate-ci/typos/blob/master/docs/reference.md
2932+
(toml.files or { }).extend-exclude or [ ]
2933+
)
2934+
else
2935+
[ ];
2936+
in
28692937
{
28702938
name = "typos";
28712939
description = "Source code spell checker";
@@ -2880,8 +2948,8 @@ in
28802948
(with hooks.typos.settings; [
28812949
[ binary "--binary" ]
28822950
[ (color != "auto") "--color ${color}" ]
2883-
[ (config != "") "--config ${configFile}" ]
2884-
[ (configPath != "" && config == "") "--config ${configPath}" ]
2951+
# Config file always exists (we generate one if not).
2952+
[ true "--config ${configAsFile}" ]
28852953
[ diff "--diff" ]
28862954
[ (exclude != "") "--exclude ${exclude} --force-exclude" ]
28872955
[ (format != "long") "--format ${format}" ]
@@ -2897,6 +2965,7 @@ in
28972965
in
28982966
"${hooks.typos.package}/bin/typos ${cmdArgs}";
28992967
types = [ "text" ];
2968+
excludes = excludesFromConfig;
29002969
};
29012970
typstfmt = {
29022971
name = "typstfmt";

0 commit comments

Comments
 (0)