Skip to content

Commit 9ae53ff

Browse files
authored
nixfmt-tree: init (NixOS#384857)
2 parents fe274fe + 82ab779 commit 9ae53ff

File tree

1 file changed

+133
-0
lines changed

1 file changed

+133
-0
lines changed
+133
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,133 @@
1+
{
2+
lib,
3+
runCommand,
4+
buildEnv,
5+
makeWrapper,
6+
writers,
7+
treefmt2,
8+
nixfmt-rfc-style,
9+
nixfmt-tree,
10+
11+
settings ? {
12+
# The default is warn, which would be too annoying for people who just care about Nix
13+
on-unmatched = "info";
14+
# Assumes the user is using Git, fails if it's not
15+
tree-root-file = ".git/index";
16+
17+
formatter.nixfmt = {
18+
command = "nixfmt";
19+
includes = [ "*.nix" ];
20+
};
21+
},
22+
runtimePackages ? [
23+
nixfmt-rfc-style
24+
],
25+
}:
26+
buildEnv {
27+
name = "nixfmt-tree";
28+
29+
# Allows this derivation to be used as a shell providing both treefmt and nixfmt
30+
paths = [ treefmt2 ] ++ runtimePackages;
31+
pathsToLink = [ "/bin" ];
32+
33+
nativeBuildInputs = [
34+
makeWrapper
35+
];
36+
37+
postBuild = ''
38+
wrapProgram $out/bin/treefmt \
39+
--prefix PATH : $out/bin \
40+
--add-flags "--config-file ${writers.writeTOML "treefmt.toml" settings}"
41+
'';
42+
43+
meta = {
44+
mainProgram = "treefmt";
45+
description = "Official Nix formatter zero-setup starter using treefmt";
46+
longDescription = ''
47+
A zero-setup [treefmt](https://treefmt.com/) starter to get started using the [official Nix formatter](https://github.com/NixOS/nixfmt).
48+
49+
- For `nix fmt` to format all Nix files, add this to the `flake.nix` outputs:
50+
51+
```nix
52+
formatter.''${system} = nixpkgs.legacyPackages.''${system}.nixfmt-tree;
53+
```
54+
55+
- The same can be done more efficiently with the `treefmt` command,
56+
which you can get in `nix-shell`/`nix develop` by extending `mkShell` using
57+
58+
```nix
59+
mkShell {
60+
packages = [ pkgs.nixfmt-tree ];
61+
}
62+
```
63+
64+
You can then also use `treefmt` in a pre-commit/pre-push [Git hook](https://git-scm.com/docs/githooks)
65+
and `nixfmt` with your editors format-on-save feature.
66+
67+
- To check formatting in CI, run the following in a checkout of your Git repository:
68+
```
69+
treefmt --ci
70+
```
71+
72+
For more flexibility, you can customise this package using
73+
```nix
74+
nixfmt-tree.override {
75+
settings = { /* treefmt config */ };
76+
runtimePackages = [ /* List any formatters here */ ];
77+
}
78+
```
79+
80+
Alternatively you can switch to the more fully-featured [treefmt-nix](https://github.com/numtide/treefmt-nix).
81+
'';
82+
# All the code is in this file, so same license as Nixpkgs
83+
license = lib.licenses.mit;
84+
maintainers = lib.teams.formatter.members;
85+
platforms = lib.platforms.all;
86+
};
87+
88+
passthru.tests.simple = runCommand "nixfmt-tree-test-simple" { } ''
89+
export XDG_CACHE_HOME=$(mktemp -d)
90+
cat > unformatted.nix <<EOF
91+
let to = "be formatted"; in to
92+
EOF
93+
94+
cat > formatted.nix <<EOF
95+
let
96+
to = "be formatted";
97+
in
98+
to
99+
EOF
100+
101+
mkdir -p repo
102+
(
103+
cd repo
104+
mkdir .git dir
105+
touch .git/index
106+
cp ../unformatted.nix a.nix
107+
cp ../unformatted.nix dir/b.nix
108+
109+
${lib.getExe nixfmt-tree} dir
110+
if [[ "$(<dir/b.nix)" != "$(<../formatted.nix)" ]]; then
111+
echo "File dir/b.nix was not formatted properly after dir was requested to be formatted"
112+
exit 1
113+
elif [[ "$(<a.nix)" != "$(<../unformatted.nix)" ]]; then
114+
echo "File a.nix was formatted when only dir was requested to be formatted"
115+
exit 1
116+
fi
117+
118+
(
119+
cd dir
120+
${lib.getExe nixfmt-tree}
121+
)
122+
123+
if [[ "$(<a.nix)" != "$(<../formatted.nix)" ]]; then
124+
echo "File a.nix was not formatted properly after running treefmt without arguments in dir"
125+
exit 1
126+
fi
127+
)
128+
129+
echo "Success!"
130+
131+
touch $out
132+
'';
133+
}

0 commit comments

Comments
 (0)