blob: ddd5dc050752556f7be3dbfc421c80db1e2fc233 (
plain) (
blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
|
# Check that overriding works for trivial-builders like
# `writeShellScript` via `overrideAttrs`. This is useful
# to override the `checkPhase`, e. g. when you want
# to enable extglob in `writeShellScript`.
#
# Run using `nix-build -A tests.trivial-overriding`.
{ lib
, runtimeShell
, runCommand
, callPackage
, writeShellScript
, writeTextFile
, writeShellScriptBin
}:
let
extglobScript = ''
shopt -s extglob
touch success
echo @(success|failure)
rm success
'';
# Reuse the old `checkPhase` of `writeShellScript`, but enable extglob.
allowExtglob = old: {
checkPhase = ''
# make sure we don't change the settings for
# the rest of the derivation's build
(
export BASHOPTS
shopt -s extglob
${old.checkPhase}
)
'';
};
# 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 = old: {
# write old checkPhase into a shell script, so we can check for
# the phase to fail even though we have `set -e`.
checkPhase = ''
if source ${writeShellScript "old-check-phase" old.checkPhase} 2>/dev/null; then
exit 1
fi
'';
};
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;
};
mkCase = f: type: isBin:
let
drv = (f type).overrideAttrs
(if type == "succ" then allowExtglob else assertFail);
in if isBin then "${drv}/bin/${drv.name}" else drv;
writeTextOverrides = {
# Enabling globbing in checkPhase
simpleSucc = mkCase simpleCase "succ" false;
# Ensure it's possible to fail; in this case globbing 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 ${script}"
exit 1
fi
'';
in
runCommand "test-writeShellScript-overriding" {
passthru = { inherit writeTextOverrides; };
} ''
${lib.concatMapStrings (test: ''
${runTest test}
'') (lib.attrValues writeTextOverrides)}
touch "$out"
''
|