testers.shfmt: init (#385939)

Changed files
+149
doc
pkgs
build-support
+58
doc/build-helpers/testers.chapter.md
···
A derivation that runs `shellcheck` on the given script(s).
The build will fail if `shellcheck` finds any issues.
+
## `shfmt` {#tester-shfmt}
+
+
Run files through `shfmt`, a shell script formatter, failing if any files are reformatted.
+
+
:::{.example #ex-shfmt}
+
# Run `testers.shfmt`
+
+
A single script
+
+
```nix
+
testers.shfmt {
+
name = "script";
+
src = ./script.sh;
+
}
+
```
+
+
Multiple files
+
+
```nix
+
let
+
inherit (lib) fileset;
+
in
+
testers.shfmt {
+
name = "nixbsd";
+
src = fileset.toSource {
+
root = ./.;
+
fileset = fileset.unions [
+
./lib.sh
+
./nixbsd-activate
+
];
+
};
+
}
+
```
+
+
:::
+
+
### Inputs {#tester-shfmt-inputs}
+
+
`name` (string)
+
: The name of the test.
+
`name` is required because it massively improves traceability of test failures.
+
The name of the derivation produced by the tester is `shfmt-${name}`.
+
+
`src` (path-like)
+
: The path to the shell script(s) to check.
+
This can be a single file or a directory containing shell files.
+
All files in `src` will be checked, so you may want to provide `fileset`-based source instead of a whole directory.
+
+
`indent` (integer, optional)
+
: The number of spaces to use for indentation.
+
Defaults to `2`.
+
A value of `0` indents with tabs.
+
+
### Return value {#tester-shfmt-return}
+
+
A derivation that runs `shfmt` on the given script(s), producing an empty output upon success.
+
The build will fail if `shfmt` reformats anything.
+
## `testVersion` {#tester-testVersion}
Checks that the output from running a command contains the specified version string in it as a whole word.
+12
doc/redirects.json
···
"ex-build-helpers-extendMkDerivation": [
"index.html#ex-build-helpers-extendMkDerivation"
],
+
"ex-shfmt": [
+
"index.html#ex-shfmt"
+
],
"ex-testBuildFailurePrime-doc-example": [
"index.html#ex-testBuildFailurePrime-doc-example"
],
···
],
"footnote-stdenv-find-inputs-location.__back.0": [
"index.html#footnote-stdenv-find-inputs-location.__back.0"
+
],
+
"tester-shfmt": [
+
"index.html#tester-shfmt"
+
],
+
"tester-shfmt-inputs": [
+
"index.html#tester-shfmt-inputs"
+
],
+
"tester-shfmt-return": [
+
"index.html#tester-shfmt-return"
],
"tester-testBuildFailurePrime": [
"index.html#tester-testBuildFailurePrime"
+2
pkgs/build-support/testers/default.nix
···
testMetaPkgConfig = callPackage ./testMetaPkgConfig/tester.nix { };
shellcheck = callPackage ./shellcheck/tester.nix { };
+
+
shfmt = callPackage ./shfmt { };
}
+29
pkgs/build-support/testers/shfmt/default.nix
···
+
{
+
lib,
+
shfmt,
+
stdenvNoCC,
+
}:
+
# See https://nixos.org/manual/nixpkgs/unstable/#tester-shfmt
+
# or doc/build-helpers/testers.chapter.md
+
{
+
name,
+
src,
+
indent ? 2,
+
}:
+
stdenvNoCC.mkDerivation (finalAttrs: {
+
__structuredAttrs = true;
+
strictDeps = true;
+
inherit src indent;
+
name = "shfmt-${name}";
+
dontUnpack = true; # Unpack phase tries to extract archive
+
nativeBuildInputs = [ shfmt ];
+
doCheck = true;
+
dontConfigure = true;
+
dontBuild = true;
+
checkPhase = ''
+
shfmt --diff --indent $indent --simplify "$src"
+
'';
+
installPhase = ''
+
touch "$out"
+
'';
+
})
+3
pkgs/build-support/testers/shfmt/src/indent2.sh
···
+
hello() {
+
echo "hello"
+
}
+43
pkgs/build-support/testers/shfmt/tests.nix
···
+
{ lib, testers }:
+
lib.recurseIntoAttrs {
+
# Positive tests
+
indent2 = testers.shfmt {
+
name = "indent2";
+
indent = 2;
+
src = ./src/indent2.sh;
+
};
+
indent2Bin = testers.shfmt {
+
name = "indent2Bin";
+
indent = 2;
+
src = ./src;
+
};
+
# Negative tests
+
indent2With0 = testers.testBuildFailure' {
+
drv = testers.shfmt {
+
name = "indent2";
+
indent = 0;
+
src = ./src/indent2.sh;
+
};
+
};
+
indent2BinWith0 = testers.testBuildFailure' {
+
drv = testers.shfmt {
+
name = "indent2Bin";
+
indent = 0;
+
src = ./src;
+
};
+
};
+
indent2With4 = testers.testBuildFailure' {
+
drv = testers.shfmt {
+
name = "indent2";
+
indent = 4;
+
src = ./src/indent2.sh;
+
};
+
};
+
indent2BinWith4 = testers.testBuildFailure' {
+
drv = testers.shfmt {
+
name = "indent2Bin";
+
indent = 4;
+
src = ./src;
+
};
+
};
+
}
+2
pkgs/build-support/testers/test/default.nix
···
shellcheck = pkgs.callPackage ../shellcheck/tests.nix { };
+
shfmt = pkgs.callPackages ../shfmt/tests.nix { };
+
runCommand = lib.recurseIntoAttrs {
bork = pkgs.python3Packages.bork.tests.pytest-network;