1{
2 pins ? import ../.npins,
3 pkgs ? import (import ../.npins).nixpkgs { },
4 lib ? pkgs.lib,
5 excludes ? [ ],
6 src ? (
7 pkgs.nix-gitignore.gitignoreRecursiveSource [
8 ../.gitignore
9 ../webui/.gitignore
10 ../webui/src/.gitignore
11 ] ../.
12 ),
13}:
14let
15 checksDir = ./checks;
16
17 fmt =
18 let
19 treefmtEval = (import pins.treefmt).evalModule pkgs {
20 projectRootFile = ".git-blame-ignore-revs";
21
22 # be a little more verbsoe to see progress
23 settings.verbose = 1;
24
25 # be a little more quiet if unmatched files are encountered (by default
26 # this is set to info, which always emits every single unmatched file)
27 settings.on-unmatched = "debug";
28
29 # files and directories that should be excluded
30 settings.global.excludes =
31 lib.lists.unique [
32 "*.graphql"
33 "*.png"
34 "*.svg"
35 "*.txt"
36 ".npins/*"
37 "Makefile"
38 "misc/completion/*/*"
39 "webui/node_modules/*"
40 "webui/build"
41
42 # generated files
43 "CHANGELOG.md"
44 "doc/man/*.1" # via //doc:generate.go
45 "doc/md/*" # via //doc:generate.go
46 ]
47 ++ excludes;
48
49 # FORMATTERS
50 #######################################################################
51
52 programs.gofmt.enable = true;
53 programs.shfmt.enable = true;
54 programs.zizmor.enable = true;
55 programs.nixf-diagnose.enable = true;
56 programs.statix.enable = true;
57
58 programs.mdformat = {
59 enable = true;
60
61 plugins =
62 ps: with ps; [
63 # add support for github flavored markdown
64 mdformat-gfm
65 mdformat-gfm-alerts
66
67 # add the following comment before running the formatter to
68 # generate a table of contents in markdown files:
69 # <!-- mdformat-toc start -->
70 mdformat-toc
71 ];
72
73 settings = {
74 end-of-line = "lf";
75 number = true;
76 wrap = 80;
77 };
78 };
79
80 programs.nixfmt = {
81 enable = true;
82 strict = true;
83 };
84
85 # programs.biome = {
86 # enable = true;
87 # settings.formatter = {
88 # useEditorconfig = true;
89 # };
90 # settings.javascript.formatter = {
91 # quoteStyle = "single";
92 # semicolons = "always";
93 # };
94 # settings.json.formatter.enabled = false;
95 # };
96 # settings.formatter.biome.excludes = [ "*.min.js" ];
97
98 programs.keep-sorted.enable = true;
99
100 programs.yamlfmt = {
101 enable = true;
102
103 settings.formatter = {
104 eof_newline = true;
105 include_document_start = true;
106 retain_line_breaks_single = true;
107 trim_trailing_whitespace = true;
108 };
109 };
110
111 settings.formatter.markdown-code-runner = {
112 command = lib.getExe pkgs.markdown-code-runner;
113 options =
114 let
115 config = pkgs.writers.writeTOML "markdown-code-runner-config" {
116 presets.nixfmt = {
117 language = "nix";
118 command = [ (lib.getExe pkgs.nixfmt) ];
119 };
120
121 presets.go = {
122 language = "go";
123 command = [
124 "${pkgs.go}/bin/gofmt"
125 "{file}"
126 ];
127 input_mode = "file";
128 };
129
130 presets.bash = {
131 language = "bash";
132 command = [
133 (lib.getExe pkgs.shfmt)
134 "--binary-next-line"
135 "--case-indent"
136 "--simplify"
137 "--space-redirects"
138 "-"
139 ];
140 };
141 };
142 in
143 [ "--config=${config}" ];
144 includes = [ "*.md" ];
145 excludes = [ "doc/md/*" ];
146 };
147 };
148
149 fs = lib.fileset;
150 checkFiles = fs.toSource {
151 root = ../.;
152 fileset = fs.difference ../. (fs.maybeMissing ../.git);
153 };
154 in
155 {
156 shell = treefmtEval.config.build.devShell;
157 check = treefmtEval.config.build.check checkFiles;
158 };
159in
160{
161 # the treefmt shell is exported because the treefmt package is added to the
162 # development shell via //:shell.nix
163 inherit (fmt) shell;
164
165 # checks is an attrset built from aggregating all of the non-golang tests
166 # (defined in //ci/checks). these are tests for things like formatting and
167 # spelling.
168 checks = {
169 fmt = fmt.check;
170 }
171 // lib.listToAttrs (
172 map
173 (file: {
174 name = lib.removeSuffix ".nix" file;
175 value = import (checksDir + "/${file}") { inherit pkgs src; };
176 })
177 (
178 builtins.attrNames (
179 lib.filterAttrs (name: type: type == "regular" && lib.hasSuffix ".nix" name) (
180 builtins.readDir checksDir
181 )
182 )
183 )
184 );
185}