nixpkgs/pkgs/build-support/trivial-builders/test-overriding.nix

111 lines
3.2 KiB
Nix
Raw Normal View History

trivial-builders: refactor writeTextFile to be overridable This fixes #126344, specifically with the goal of enabling overriding the checkPhase argument. See `design notes` at the end for details. This allows among other things, enabling bash extension for the `checkPhase`. Previously using such bash extensions was prohibited by the `writeShellScript` code because there was no way to enable the extension in the checker. As an example: ```nix (writeShellScript "foo" '' shopt -s extglob echo @(foo|bar) '').overrideAttrs (old: { checkPhase = '' # use subshell to preserve outer environment ( export BASHOPTS shopt -s extglob ${old.checkPhase} ) ''; }) ``` This commit also adds tests for this feature to `pkgs/tests/default.nix`, under `trivial-overriding`. The test code is located at `pkgs/build-support/trivial-builders/test-overriding.nix`. Design notes: ------------- Per discussion with @sternenseemann, the original approach of just wrapping `writeTextFile` in `makeOverridable` had the issue that combined with `callPackage` in the following form, would shadow the `.override` attribute of the `writeTextFile`: ```nix with import <nixpkgs>; callPackage ({writeShellScript}: writeShellScript "foo" "echo foo") ``` A better approach can be seen in this commit, where `checkPhase` is moved from an argument of `writeTextFile`, which is substituted into `buildCommand`, into an `mkDerivation` argument, which is substituted from the environment and `eval`-ed. (see the source) This way we can simple use `.overideAttrs` as usual, and this also makes `checkPhase` a bit more conformant to `mkDerivation` naming, with respect to phases generally being overridable attrs. Co-authored-by: sterni <sternenseemann@systemli.org> Co-authored-by: Naïm Favier <n@monade.li>
2021-06-14 15:06:23 +02:00
# Check that overriding works for trivial-builders like
# `writeShellScript` via `overrideAttrs`. This is useful
# to override the `checkPhase`, e. g. if you want
# to disable extglob in `writeShellScript`.
trivial-builders: refactor writeTextFile to be overridable This fixes #126344, specifically with the goal of enabling overriding the checkPhase argument. See `design notes` at the end for details. This allows among other things, enabling bash extension for the `checkPhase`. Previously using such bash extensions was prohibited by the `writeShellScript` code because there was no way to enable the extension in the checker. As an example: ```nix (writeShellScript "foo" '' shopt -s extglob echo @(foo|bar) '').overrideAttrs (old: { checkPhase = '' # use subshell to preserve outer environment ( export BASHOPTS shopt -s extglob ${old.checkPhase} ) ''; }) ``` This commit also adds tests for this feature to `pkgs/tests/default.nix`, under `trivial-overriding`. The test code is located at `pkgs/build-support/trivial-builders/test-overriding.nix`. Design notes: ------------- Per discussion with @sternenseemann, the original approach of just wrapping `writeTextFile` in `makeOverridable` had the issue that combined with `callPackage` in the following form, would shadow the `.override` attribute of the `writeTextFile`: ```nix with import <nixpkgs>; callPackage ({writeShellScript}: writeShellScript "foo" "echo foo") ``` A better approach can be seen in this commit, where `checkPhase` is moved from an argument of `writeTextFile`, which is substituted into `buildCommand`, into an `mkDerivation` argument, which is substituted from the environment and `eval`-ed. (see the source) This way we can simple use `.overideAttrs` as usual, and this also makes `checkPhase` a bit more conformant to `mkDerivation` naming, with respect to phases generally being overridable attrs. Co-authored-by: sterni <sternenseemann@systemli.org> Co-authored-by: Naïm Favier <n@monade.li>
2021-06-14 15:06:23 +02:00
#
# Run using `nix-build -A tests.trivial-builders.overriding`.
trivial-builders: refactor writeTextFile to be overridable This fixes #126344, specifically with the goal of enabling overriding the checkPhase argument. See `design notes` at the end for details. This allows among other things, enabling bash extension for the `checkPhase`. Previously using such bash extensions was prohibited by the `writeShellScript` code because there was no way to enable the extension in the checker. As an example: ```nix (writeShellScript "foo" '' shopt -s extglob echo @(foo|bar) '').overrideAttrs (old: { checkPhase = '' # use subshell to preserve outer environment ( export BASHOPTS shopt -s extglob ${old.checkPhase} ) ''; }) ``` This commit also adds tests for this feature to `pkgs/tests/default.nix`, under `trivial-overriding`. The test code is located at `pkgs/build-support/trivial-builders/test-overriding.nix`. Design notes: ------------- Per discussion with @sternenseemann, the original approach of just wrapping `writeTextFile` in `makeOverridable` had the issue that combined with `callPackage` in the following form, would shadow the `.override` attribute of the `writeTextFile`: ```nix with import <nixpkgs>; callPackage ({writeShellScript}: writeShellScript "foo" "echo foo") ``` A better approach can be seen in this commit, where `checkPhase` is moved from an argument of `writeTextFile`, which is substituted into `buildCommand`, into an `mkDerivation` argument, which is substituted from the environment and `eval`-ed. (see the source) This way we can simple use `.overideAttrs` as usual, and this also makes `checkPhase` a bit more conformant to `mkDerivation` naming, with respect to phases generally being overridable attrs. Co-authored-by: sterni <sternenseemann@systemli.org> Co-authored-by: Naïm Favier <n@monade.li>
2021-06-14 15:06:23 +02:00
{ lib
, stdenv
trivial-builders: refactor writeTextFile to be overridable This fixes #126344, specifically with the goal of enabling overriding the checkPhase argument. See `design notes` at the end for details. This allows among other things, enabling bash extension for the `checkPhase`. Previously using such bash extensions was prohibited by the `writeShellScript` code because there was no way to enable the extension in the checker. As an example: ```nix (writeShellScript "foo" '' shopt -s extglob echo @(foo|bar) '').overrideAttrs (old: { checkPhase = '' # use subshell to preserve outer environment ( export BASHOPTS shopt -s extglob ${old.checkPhase} ) ''; }) ``` This commit also adds tests for this feature to `pkgs/tests/default.nix`, under `trivial-overriding`. The test code is located at `pkgs/build-support/trivial-builders/test-overriding.nix`. Design notes: ------------- Per discussion with @sternenseemann, the original approach of just wrapping `writeTextFile` in `makeOverridable` had the issue that combined with `callPackage` in the following form, would shadow the `.override` attribute of the `writeTextFile`: ```nix with import <nixpkgs>; callPackage ({writeShellScript}: writeShellScript "foo" "echo foo") ``` A better approach can be seen in this commit, where `checkPhase` is moved from an argument of `writeTextFile`, which is substituted into `buildCommand`, into an `mkDerivation` argument, which is substituted from the environment and `eval`-ed. (see the source) This way we can simple use `.overideAttrs` as usual, and this also makes `checkPhase` a bit more conformant to `mkDerivation` naming, with respect to phases generally being overridable attrs. Co-authored-by: sterni <sternenseemann@systemli.org> Co-authored-by: Naïm Favier <n@monade.li>
2021-06-14 15:06:23 +02:00
, runtimeShell
, runCommand
, callPackage
, writeShellScript
, writeTextFile
, writeShellScriptBin
}:
let
extglobScript = ''
shopt -s extglob
touch success
echo @(success|failure)
rm success
'';
simpleCase = case:
writeShellScript "test-trivial-overriding-${case}" extglobScript;
callPackageCase = case: callPackage (
{ writeShellScript }:
writeShellScript "test-trivial-callpackage-overriding-${case}" extglobScript
) { };
binCase = case:
writeShellScriptBin "test-trivial-overriding-bin-${case}" extglobScript;
# building this derivation would fail without overriding
textFileCase = writeTextFile {
name = "test-trivial-overriding-text-file";
checkPhase = "false";
text = ''
#!${runtimeShell}
echo success
'';
executable = true;
};
disallowExtglob = x: x.overrideAttrs (_: {
checkPhase = ''
${stdenv.shell} -n "$target"
'';
});
# Run old checkPhase, but only succeed if it fails.
# This HACK is required because we can't introspect build failures
# in nix: With `assertFail` we want to make sure that the default
# `checkPhase` would fail if extglob was used in the script.
assertFail = x: x.overrideAttrs (old: {
checkPhase = ''
if
${old.checkPhase}
then exit 1; fi
'';
});
mkCase = case: outcome: isBin:
trivial-builders: refactor writeTextFile to be overridable This fixes #126344, specifically with the goal of enabling overriding the checkPhase argument. See `design notes` at the end for details. This allows among other things, enabling bash extension for the `checkPhase`. Previously using such bash extensions was prohibited by the `writeShellScript` code because there was no way to enable the extension in the checker. As an example: ```nix (writeShellScript "foo" '' shopt -s extglob echo @(foo|bar) '').overrideAttrs (old: { checkPhase = '' # use subshell to preserve outer environment ( export BASHOPTS shopt -s extglob ${old.checkPhase} ) ''; }) ``` This commit also adds tests for this feature to `pkgs/tests/default.nix`, under `trivial-overriding`. The test code is located at `pkgs/build-support/trivial-builders/test-overriding.nix`. Design notes: ------------- Per discussion with @sternenseemann, the original approach of just wrapping `writeTextFile` in `makeOverridable` had the issue that combined with `callPackage` in the following form, would shadow the `.override` attribute of the `writeTextFile`: ```nix with import <nixpkgs>; callPackage ({writeShellScript}: writeShellScript "foo" "echo foo") ``` A better approach can be seen in this commit, where `checkPhase` is moved from an argument of `writeTextFile`, which is substituted into `buildCommand`, into an `mkDerivation` argument, which is substituted from the environment and `eval`-ed. (see the source) This way we can simple use `.overideAttrs` as usual, and this also makes `checkPhase` a bit more conformant to `mkDerivation` naming, with respect to phases generally being overridable attrs. Co-authored-by: sterni <sternenseemann@systemli.org> Co-authored-by: Naïm Favier <n@monade.li>
2021-06-14 15:06:23 +02:00
let
drv = lib.pipe outcome ([ case ] ++ lib.optionals (outcome == "fail") [ disallowExtglob assertFail ]);
trivial-builders: refactor writeTextFile to be overridable This fixes #126344, specifically with the goal of enabling overriding the checkPhase argument. See `design notes` at the end for details. This allows among other things, enabling bash extension for the `checkPhase`. Previously using such bash extensions was prohibited by the `writeShellScript` code because there was no way to enable the extension in the checker. As an example: ```nix (writeShellScript "foo" '' shopt -s extglob echo @(foo|bar) '').overrideAttrs (old: { checkPhase = '' # use subshell to preserve outer environment ( export BASHOPTS shopt -s extglob ${old.checkPhase} ) ''; }) ``` This commit also adds tests for this feature to `pkgs/tests/default.nix`, under `trivial-overriding`. The test code is located at `pkgs/build-support/trivial-builders/test-overriding.nix`. Design notes: ------------- Per discussion with @sternenseemann, the original approach of just wrapping `writeTextFile` in `makeOverridable` had the issue that combined with `callPackage` in the following form, would shadow the `.override` attribute of the `writeTextFile`: ```nix with import <nixpkgs>; callPackage ({writeShellScript}: writeShellScript "foo" "echo foo") ``` A better approach can be seen in this commit, where `checkPhase` is moved from an argument of `writeTextFile`, which is substituted into `buildCommand`, into an `mkDerivation` argument, which is substituted from the environment and `eval`-ed. (see the source) This way we can simple use `.overideAttrs` as usual, and this also makes `checkPhase` a bit more conformant to `mkDerivation` naming, with respect to phases generally being overridable attrs. Co-authored-by: sterni <sternenseemann@systemli.org> Co-authored-by: Naïm Favier <n@monade.li>
2021-06-14 15:06:23 +02:00
in if isBin then "${drv}/bin/${drv.name}" else drv;
writeTextOverrides = {
# Make sure extglob works by default
trivial-builders: refactor writeTextFile to be overridable This fixes #126344, specifically with the goal of enabling overriding the checkPhase argument. See `design notes` at the end for details. This allows among other things, enabling bash extension for the `checkPhase`. Previously using such bash extensions was prohibited by the `writeShellScript` code because there was no way to enable the extension in the checker. As an example: ```nix (writeShellScript "foo" '' shopt -s extglob echo @(foo|bar) '').overrideAttrs (old: { checkPhase = '' # use subshell to preserve outer environment ( export BASHOPTS shopt -s extglob ${old.checkPhase} ) ''; }) ``` This commit also adds tests for this feature to `pkgs/tests/default.nix`, under `trivial-overriding`. The test code is located at `pkgs/build-support/trivial-builders/test-overriding.nix`. Design notes: ------------- Per discussion with @sternenseemann, the original approach of just wrapping `writeTextFile` in `makeOverridable` had the issue that combined with `callPackage` in the following form, would shadow the `.override` attribute of the `writeTextFile`: ```nix with import <nixpkgs>; callPackage ({writeShellScript}: writeShellScript "foo" "echo foo") ``` A better approach can be seen in this commit, where `checkPhase` is moved from an argument of `writeTextFile`, which is substituted into `buildCommand`, into an `mkDerivation` argument, which is substituted from the environment and `eval`-ed. (see the source) This way we can simple use `.overideAttrs` as usual, and this also makes `checkPhase` a bit more conformant to `mkDerivation` naming, with respect to phases generally being overridable attrs. Co-authored-by: sterni <sternenseemann@systemli.org> Co-authored-by: Naïm Favier <n@monade.li>
2021-06-14 15:06:23 +02:00
simpleSucc = mkCase simpleCase "succ" false;
# Ensure it's possible to fail; in this case extglob is not enabled
trivial-builders: refactor writeTextFile to be overridable This fixes #126344, specifically with the goal of enabling overriding the checkPhase argument. See `design notes` at the end for details. This allows among other things, enabling bash extension for the `checkPhase`. Previously using such bash extensions was prohibited by the `writeShellScript` code because there was no way to enable the extension in the checker. As an example: ```nix (writeShellScript "foo" '' shopt -s extglob echo @(foo|bar) '').overrideAttrs (old: { checkPhase = '' # use subshell to preserve outer environment ( export BASHOPTS shopt -s extglob ${old.checkPhase} ) ''; }) ``` This commit also adds tests for this feature to `pkgs/tests/default.nix`, under `trivial-overriding`. The test code is located at `pkgs/build-support/trivial-builders/test-overriding.nix`. Design notes: ------------- Per discussion with @sternenseemann, the original approach of just wrapping `writeTextFile` in `makeOverridable` had the issue that combined with `callPackage` in the following form, would shadow the `.override` attribute of the `writeTextFile`: ```nix with import <nixpkgs>; callPackage ({writeShellScript}: writeShellScript "foo" "echo foo") ``` A better approach can be seen in this commit, where `checkPhase` is moved from an argument of `writeTextFile`, which is substituted into `buildCommand`, into an `mkDerivation` argument, which is substituted from the environment and `eval`-ed. (see the source) This way we can simple use `.overideAttrs` as usual, and this also makes `checkPhase` a bit more conformant to `mkDerivation` naming, with respect to phases generally being overridable attrs. Co-authored-by: sterni <sternenseemann@systemli.org> Co-authored-by: Naïm Favier <n@monade.li>
2021-06-14 15:06:23 +02:00
simpleFail = mkCase simpleCase "fail" false;
# Do the same checks after wrapping with callPackage
# to make sure callPackage doesn't mess with the override
callpSucc = mkCase callPackageCase "succ" false;
callpFail = mkCase callPackageCase "fail" false;
# Do the same check using `writeShellScriptBin`
binSucc = mkCase binCase "succ" true;
binFail = mkCase binCase "fail" true;
# Check that we can also override plain writeTextFile
textFileSuccess = textFileCase.overrideAttrs (_: {
checkPhase = "true";
});
};
# `runTest` forces nix to build the script of our test case and
# run its `checkPhase` which is our main interest. Additionally
# it executes the script and thus makes sure that extglob also
# works at run time.
runTest = script:
let
name = script.name or (builtins.baseNameOf script);
in writeShellScript "run-${name}" ''
if [ "$(${script})" != "success" ]; then
echo "Failed in ${name}"
trivial-builders: refactor writeTextFile to be overridable This fixes #126344, specifically with the goal of enabling overriding the checkPhase argument. See `design notes` at the end for details. This allows among other things, enabling bash extension for the `checkPhase`. Previously using such bash extensions was prohibited by the `writeShellScript` code because there was no way to enable the extension in the checker. As an example: ```nix (writeShellScript "foo" '' shopt -s extglob echo @(foo|bar) '').overrideAttrs (old: { checkPhase = '' # use subshell to preserve outer environment ( export BASHOPTS shopt -s extglob ${old.checkPhase} ) ''; }) ``` This commit also adds tests for this feature to `pkgs/tests/default.nix`, under `trivial-overriding`. The test code is located at `pkgs/build-support/trivial-builders/test-overriding.nix`. Design notes: ------------- Per discussion with @sternenseemann, the original approach of just wrapping `writeTextFile` in `makeOverridable` had the issue that combined with `callPackage` in the following form, would shadow the `.override` attribute of the `writeTextFile`: ```nix with import <nixpkgs>; callPackage ({writeShellScript}: writeShellScript "foo" "echo foo") ``` A better approach can be seen in this commit, where `checkPhase` is moved from an argument of `writeTextFile`, which is substituted into `buildCommand`, into an `mkDerivation` argument, which is substituted from the environment and `eval`-ed. (see the source) This way we can simple use `.overideAttrs` as usual, and this also makes `checkPhase` a bit more conformant to `mkDerivation` naming, with respect to phases generally being overridable attrs. Co-authored-by: sterni <sternenseemann@systemli.org> Co-authored-by: Naïm Favier <n@monade.li>
2021-06-14 15:06:23 +02:00
exit 1
fi
'';
in
runCommand "test-writeShellScript-overriding" {
passthru = { inherit writeTextOverrides; };
} ''
${lib.concatMapStrings (test: ''
${runTest test}
'') (lib.attrValues writeTextOverrides)}
touch "$out"
''