testers.shfmt: init

This commit is contained in:
Connor Baker 2025-02-28 23:21:38 +00:00 committed by Connor Baker
parent fc3e47d102
commit 6f52f21ad2
7 changed files with 149 additions and 0 deletions

View file

@ -165,6 +165,64 @@ testers.shellcheck {
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.

View file

@ -8,6 +8,9 @@
"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"
],
@ -335,6 +338,15 @@
"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"
],

View file

@ -190,4 +190,6 @@
testMetaPkgConfig = callPackage ./testMetaPkgConfig/tester.nix { };
shellcheck = callPackage ./shellcheck/tester.nix { };
shfmt = callPackage ./shfmt { };
}

View file

@ -0,0 +1,29 @@
{
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"
'';
})

View file

@ -0,0 +1,3 @@
hello() {
echo "hello"
}

View file

@ -0,0 +1,43 @@
{ 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;
};
};
}

View file

@ -39,6 +39,8 @@ lib.recurseIntoAttrs {
shellcheck = pkgs.callPackage ../shellcheck/tests.nix { };
shfmt = pkgs.callPackages ../shfmt/tests.nix { };
runCommand = lib.recurseIntoAttrs {
bork = pkgs.python3Packages.bork.tests.pytest-network;