# 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`. # # Run using `nix-build -A tests.trivial-builders.overriding`. { lib , stdenv , 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: let drv = lib.pipe outcome ([ case ] ++ lib.optionals (outcome == "fail") [ disallowExtglob assertFail ]); in if isBin then "${drv}/bin/${drv.name}" else drv; writeTextOverrides = { # Make sure extglob works by default simpleSucc = mkCase simpleCase "succ" false; # Ensure it's possible to fail; in this case extglob is not enabled 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}" exit 1 fi ''; in runCommand "test-writeShellScript-overriding" { passthru = { inherit writeTextOverrides; }; } '' ${lib.concatMapStrings (test: '' ${runTest test} '') (lib.attrValues writeTextOverrides)} touch "$out" ''