@@ -1340,10 +1340,11 @@ in
1340
1340
default = "auto" ;
1341
1341
} ;
1342
1342
1343
+ # It is recommended to use `configFile`.
1343
1344
config =
1344
1345
mkOption {
1345
1346
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." ;
1347
1348
default = "" ;
1348
1349
example = ''
1349
1350
[files]
@@ -1357,6 +1358,22 @@ in
1357
1358
'' ;
1358
1359
} ;
1359
1360
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.
1360
1377
configPath =
1361
1378
mkOption {
1362
1379
type = types . str ;
@@ -2866,6 +2883,57 @@ in
2866
2883
entry = "${ hooks . treefmt . package } /bin/treefmt --fail-on-change" ;
2867
2884
} ;
2868
2885
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
2869
2937
{
2870
2938
name = "typos" ;
2871
2939
description = "Source code spell checker" ;
2880
2948
( with hooks . typos . settings ; [
2881
2949
[ binary "--binary" ]
2882
2950
[ ( 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 } " ]
2885
2953
[ diff "--diff" ]
2886
2954
[ ( exclude != "" ) "--exclude ${ exclude } --force-exclude" ]
2887
2955
[ ( format != "long" ) "--format ${ format } " ]
2897
2965
in
2898
2966
"${ hooks . typos . package } /bin/typos ${ cmdArgs } " ;
2899
2967
types = [ "text" ] ;
2968
+ excludes = excludesFromConfig ;
2900
2969
} ;
2901
2970
typstfmt = {
2902
2971
name = "typstfmt" ;
0 commit comments