diff options
author | Doron Behar | 2024-06-16 17:08:57 +0300 |
---|---|---|
committer | Doron Behar | 2024-06-28 18:03:59 +0300 |
commit | eb49fb355e8269690bb100fae060af50138b2de3 (patch) | |
tree | b3a5b2f871f55131c43e756323ec642e41b9ada4 | |
parent | 3b97a2e9ba4dd6abb8dc624941220a40d12ebe64 (diff) |
versionCheckHook: init
-rw-r--r-- | doc/hooks/index.md | 1 | ||||
-rw-r--r-- | doc/hooks/versionCheckHook.section.md | 35 | ||||
-rw-r--r-- | pkgs/by-name/ve/versionCheckHook/hook.sh | 60 | ||||
-rw-r--r-- | pkgs/by-name/ve/versionCheckHook/package.nix | 12 |
4 files changed, 108 insertions, 0 deletions
diff --git a/doc/hooks/index.md b/doc/hooks/index.md index 1534ef85ccb9..6d01c6cbcbe5 100644 --- a/doc/hooks/index.md +++ b/doc/hooks/index.md @@ -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 diff --git a/doc/hooks/versionCheckHook.section.md b/doc/hooks/versionCheckHook.section.md new file mode 100644 index 000000000000..55b9fa916c40 --- /dev/null +++ b/doc/hooks/versionCheckHook.section.md @@ -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. diff --git a/pkgs/by-name/ve/versionCheckHook/hook.sh b/pkgs/by-name/ve/versionCheckHook/hook.sh new file mode 100644 index 000000000000..cd417493e6c2 --- /dev/null +++ b/pkgs/by-name/ve/versionCheckHook/hook.sh @@ -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 diff --git a/pkgs/by-name/ve/versionCheckHook/package.nix b/pkgs/by-name/ve/versionCheckHook/package.nix new file mode 100644 index 000000000000..ed35384d7960 --- /dev/null +++ b/pkgs/by-name/ve/versionCheckHook/package.nix @@ -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 |