versionCheckHook: init

This commit is contained in:
Doron Behar 2024-06-16 17:08:57 +03:00
parent 3b97a2e9ba
commit eb49fb355e
4 changed files with 108 additions and 0 deletions

View File

@ -29,6 +29,7 @@ scons.section.md
tetex-tex-live.section.md
unzip.section.md
validatePkgConfig.section.md
versionCheckHook.section.md
waf.section.md
zig.section.md
xcbuild.section.md

View File

@ -0,0 +1,35 @@
# versionCheckHook {#versioncheckhook}
This hook adds a `versionCheckPhase` to the [`preInstallCheckHooks`](#ssec-installCheck-phase) that runs the main program of the derivation with a `--help` or `--version` argument, and checks that the `${version}` string is found in that output. You use it like this:
```nix
{
lib,
stdenv,
versionCheckHook,
# ...
}:
stdenv.mkDerivation (finalAttrs: {
# ...
nativeInstallCheckInputs = [
versionCheckHook
];
doInstallCheck = true;
# ...
})
```
Note that for [`buildPythonPackage`](#buildpythonpackage-function) and [`buildPythonApplication`](#buildpythonapplication-function), `doInstallCheck` is enabled by default.
It does so in a clean environment (using `env --ignore-environment`), and it checks for the `${version}` string in both the `stdout` and the `stderr` of the command. It will report to you in the build log the output it received and it will fail the build if it failed to find `${version}`.
The variables that this phase control are:
- `dontVersionCheck`: Disable adding this hook to the [`preDistPhases`](#var-stdenv-preDist). Useful if you do want to load the bash functions of the hook, but run them differently.
- `versionCheckProgram`: The full path to the program that should print the `${version}` string. Defaults roughly to `${placeholder "out"}/bin/${pname}`. Using `$out` in the value of this variable won't work, as environment variables from this variable are not expanded by the hook. Hence using `placeholder` is unavoidable.
- `versionCheckProgramArg`: The argument that needs to be passed to `versionCheckProgram`. If undefined the hook tries first `--help` and then `--version`. Examples: `version`, `-V`, `-v`.
- `preVersionCheck`: A hook to run before the check is done.
- `postVersionCheck`: A hook to run after the check is done.

View File

@ -0,0 +1,60 @@
_handleCmdOutput(){
local versionOutput
versionOutput="$(env --chdir=/ --argv0="$(basename "$1")" --ignore-environment "$@" 2>&1 || true)"
if [[ "$versionOutput" =~ "$version" ]]; then
echoPrefix="Successfully managed to"
else
echoPrefix="Did not"
fi
# The return value of this function is this variable:
echo "$echoPrefix"
# And in anycase we want these to be printed in the build log, useful for
# debugging, so we print these to stderr.
echo "$echoPrefix" find version "$version" in the output of the command \
"$@" >&2
echo "$versionOutput" >&2
}
versionCheckHook(){
runHook preVersionCheck
echo Executing versionCheckPhase
local cmdProgram cmdArg echoPrefix
if [[ -z "${versionCheckProgram-}" ]]; then
if [[ -z "${pname-}" ]]; then
echo "both \$pname and \$versionCheckProgram are empty, so" \
"we don't know which program to run the versionCheckPhase" \
"upon" >&2
exit 2
else
cmdProgram="${!outputBin}/bin/$pname"
fi
else
cmdProgram="$versionCheckProgram"
fi
if [[ ! -x "$cmdProgram" ]]; then
echo "versionCheckHook: $cmdProgram was not found, or is not an executable" >&2
exit 2
fi
if [[ -z "${versionCheckProgramArg}" ]]; then
for cmdArg in "--help" "--version"; do
echoPrefix="$(_handleCmdOutput "$cmdProgram" "$cmdArg")"
if [[ "$echoPrefix" == "Successfully managed to" ]]; then
break
fi
done
else
cmdArg="$versionCheckProgramArg"
echoPrefix="$(_handleCmdOutput "$cmdProgram" "$cmdArg")"
fi
if [[ "$echoPrefix" == "Did not" ]]; then
exit 2
fi
runHook postVersionCheck
echo Finished versionCheckPhase
}
if [[ -z "${dontVersionCheck-}" ]]; then
echo "Using versionCheckHook"
preInstallCheckHooks+=(versionCheckHook)
fi

View File

@ -0,0 +1,12 @@
{
lib,
makeSetupHook,
}:
makeSetupHook {
name = "version-check-hook";
meta = {
description = "Lookup for $version in the output of --help and --version";
maintainers = with lib.maintainers; [ doronbehar ];
};
} ./hook.sh