Skip to content

Commit cb26667

Browse files
authored
testers.shfmt: init (#385939)
2 parents e55dc60 + 6f52f21 commit cb26667

File tree

7 files changed

+149
-0
lines changed

7 files changed

+149
-0
lines changed

doc/build-helpers/testers.chapter.md

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -165,6 +165,64 @@ testers.shellcheck {
165165
A derivation that runs `shellcheck` on the given script(s).
166166
The build will fail if `shellcheck` finds any issues.
167167

168+
## `shfmt` {#tester-shfmt}
169+
170+
Run files through `shfmt`, a shell script formatter, failing if any files are reformatted.
171+
172+
:::{.example #ex-shfmt}
173+
# Run `testers.shfmt`
174+
175+
A single script
176+
177+
```nix
178+
testers.shfmt {
179+
name = "script";
180+
src = ./script.sh;
181+
}
182+
```
183+
184+
Multiple files
185+
186+
```nix
187+
let
188+
inherit (lib) fileset;
189+
in
190+
testers.shfmt {
191+
name = "nixbsd";
192+
src = fileset.toSource {
193+
root = ./.;
194+
fileset = fileset.unions [
195+
./lib.sh
196+
./nixbsd-activate
197+
];
198+
};
199+
}
200+
```
201+
202+
:::
203+
204+
### Inputs {#tester-shfmt-inputs}
205+
206+
`name` (string)
207+
: The name of the test.
208+
`name` is required because it massively improves traceability of test failures.
209+
The name of the derivation produced by the tester is `shfmt-${name}`.
210+
211+
`src` (path-like)
212+
: The path to the shell script(s) to check.
213+
This can be a single file or a directory containing shell files.
214+
All files in `src` will be checked, so you may want to provide `fileset`-based source instead of a whole directory.
215+
216+
`indent` (integer, optional)
217+
: The number of spaces to use for indentation.
218+
Defaults to `2`.
219+
A value of `0` indents with tabs.
220+
221+
### Return value {#tester-shfmt-return}
222+
223+
A derivation that runs `shfmt` on the given script(s), producing an empty output upon success.
224+
The build will fail if `shfmt` reformats anything.
225+
168226
## `testVersion` {#tester-testVersion}
169227

170228
Checks that the output from running a command contains the specified version string in it as a whole word.

doc/redirects.json

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,9 @@
88
"ex-build-helpers-extendMkDerivation": [
99
"index.html#ex-build-helpers-extendMkDerivation"
1010
],
11+
"ex-shfmt": [
12+
"index.html#ex-shfmt"
13+
],
1114
"ex-testBuildFailurePrime-doc-example": [
1215
"index.html#ex-testBuildFailurePrime-doc-example"
1316
],
@@ -338,6 +341,15 @@
338341
"footnote-stdenv-find-inputs-location.__back.0": [
339342
"index.html#footnote-stdenv-find-inputs-location.__back.0"
340343
],
344+
"tester-shfmt": [
345+
"index.html#tester-shfmt"
346+
],
347+
"tester-shfmt-inputs": [
348+
"index.html#tester-shfmt-inputs"
349+
],
350+
"tester-shfmt-return": [
351+
"index.html#tester-shfmt-return"
352+
],
341353
"tester-testBuildFailurePrime": [
342354
"index.html#tester-testBuildFailurePrime"
343355
],

pkgs/build-support/testers/default.nix

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -194,4 +194,6 @@
194194
testMetaPkgConfig = callPackage ./testMetaPkgConfig/tester.nix { };
195195

196196
shellcheck = callPackage ./shellcheck/tester.nix { };
197+
198+
shfmt = callPackage ./shfmt { };
197199
}
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
{
2+
lib,
3+
shfmt,
4+
stdenvNoCC,
5+
}:
6+
# See https://nixos.org/manual/nixpkgs/unstable/#tester-shfmt
7+
# or doc/build-helpers/testers.chapter.md
8+
{
9+
name,
10+
src,
11+
indent ? 2,
12+
}:
13+
stdenvNoCC.mkDerivation (finalAttrs: {
14+
__structuredAttrs = true;
15+
strictDeps = true;
16+
inherit src indent;
17+
name = "shfmt-${name}";
18+
dontUnpack = true; # Unpack phase tries to extract archive
19+
nativeBuildInputs = [ shfmt ];
20+
doCheck = true;
21+
dontConfigure = true;
22+
dontBuild = true;
23+
checkPhase = ''
24+
shfmt --diff --indent $indent --simplify "$src"
25+
'';
26+
installPhase = ''
27+
touch "$out"
28+
'';
29+
})
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
hello() {
2+
echo "hello"
3+
}
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
{ lib, testers }:
2+
lib.recurseIntoAttrs {
3+
# Positive tests
4+
indent2 = testers.shfmt {
5+
name = "indent2";
6+
indent = 2;
7+
src = ./src/indent2.sh;
8+
};
9+
indent2Bin = testers.shfmt {
10+
name = "indent2Bin";
11+
indent = 2;
12+
src = ./src;
13+
};
14+
# Negative tests
15+
indent2With0 = testers.testBuildFailure' {
16+
drv = testers.shfmt {
17+
name = "indent2";
18+
indent = 0;
19+
src = ./src/indent2.sh;
20+
};
21+
};
22+
indent2BinWith0 = testers.testBuildFailure' {
23+
drv = testers.shfmt {
24+
name = "indent2Bin";
25+
indent = 0;
26+
src = ./src;
27+
};
28+
};
29+
indent2With4 = testers.testBuildFailure' {
30+
drv = testers.shfmt {
31+
name = "indent2";
32+
indent = 4;
33+
src = ./src/indent2.sh;
34+
};
35+
};
36+
indent2BinWith4 = testers.testBuildFailure' {
37+
drv = testers.shfmt {
38+
name = "indent2Bin";
39+
indent = 4;
40+
src = ./src;
41+
};
42+
};
43+
}

pkgs/build-support/testers/test/default.nix

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,8 @@ lib.recurseIntoAttrs {
3939

4040
shellcheck = pkgs.callPackage ../shellcheck/tests.nix { };
4141

42+
shfmt = pkgs.callPackages ../shfmt/tests.nix { };
43+
4244
runCommand = lib.recurseIntoAttrs {
4345
bork = pkgs.python3Packages.bork.tests.pytest-network;
4446

0 commit comments

Comments
 (0)