1{
2 lib,
3 writeText,
4 writeCBin,
5 writeShellScript,
6 makeWrapper,
7 runCommand,
8 which,
9 ...
10}:
11
12let
13 # Testfiles
14 foofile = writeText "foofile" "foo";
15 barfile = writeText "barfile" "bar";
16
17 # Wrapped binaries
18 wrappedArgv0 = writeCBin "wrapped-argv0" ''
19 #include <stdio.h>
20 #include <stdlib.h>
21
22 void main(int argc, char** argv) {
23 printf("argv0=%s", argv[0]);
24 exit(0);
25 }
26 '';
27 wrappedBinaryVar = writeShellScript "wrapped-var" ''
28 echo "VAR=$VAR"
29 '';
30 wrappedBinaryArgs = writeShellScript "wrapped-args" ''
31 printf '%s\n' "$@"
32 '';
33
34 mkWrapperBinary =
35 {
36 name,
37 args,
38 wrapped ? wrappedBinaryVar,
39 }:
40 runCommand name
41 {
42 nativeBuildInputs = [ makeWrapper ];
43 }
44 ''
45 mkdir -p $out/bin
46 makeWrapper "${wrapped}" "$out/bin/${name}" ${lib.escapeShellArgs args}
47 '';
48
49 mkArgTest = cmd: toExpect: mkTest cmd (builtins.concatStringsSep "\n" toExpect);
50 mkTest = cmd: toExpect: ''
51 output="$(${cmd})"
52 if [[ "$output" != ${lib.escapeShellArg toExpect} ]]; then
53 echo "test failed: the output of ${cmd} was '$output', expected ${lib.escapeShellArg toExpect}"
54 echo "the wrapper contents:"
55 for i in ${cmd}; do
56 if [[ $i =~ ^test- ]]; then
57 cat $(which $i)
58 fi
59 done
60 exit 1
61 fi
62 '';
63in
64runCommand "make-wrapper-test"
65 {
66 nativeBuildInputs = [
67 which
68 (mkWrapperBinary {
69 name = "test-argv0";
70 args = [
71 "--argv0"
72 "foo"
73 ];
74 wrapped = "${wrappedArgv0}/bin/wrapped-argv0";
75 })
76 (mkWrapperBinary {
77 name = "test-set";
78 args = [
79 "--set"
80 "VAR"
81 "abc"
82 ];
83 })
84 (mkWrapperBinary {
85 name = "test-set-default";
86 args = [
87 "--set-default"
88 "VAR"
89 "abc"
90 ];
91 })
92 (mkWrapperBinary {
93 name = "test-unset";
94 args = [
95 "--unset"
96 "VAR"
97 ];
98 })
99 (mkWrapperBinary {
100 name = "test-run";
101 args = [
102 "--run"
103 "echo bar"
104 ];
105 })
106 (mkWrapperBinary {
107 name = "test-run-and-set";
108 args = [
109 "--run"
110 "export VAR=foo"
111 "--set"
112 "VAR"
113 "bar"
114 ];
115 })
116 (mkWrapperBinary {
117 name = "test-args";
118 args = [
119 "--add-flags"
120 "abc"
121 "--append-flags"
122 "xyz"
123 ];
124 wrapped = wrappedBinaryArgs;
125 })
126 (mkWrapperBinary {
127 name = "test-arg";
128 args = [
129 "--add-flag"
130 "abc 'aaaaa' jkhhjk"
131 "--append-flag"
132 "xyz ggg"
133 ];
134 wrapped = wrappedBinaryArgs;
135 })
136 (mkWrapperBinary {
137 name = "test-prefix";
138 args = [
139 "--prefix"
140 "VAR"
141 ":"
142 "abc"
143 ];
144 })
145 (mkWrapperBinary {
146 name = "test-prefix-noglob";
147 args = [
148 "--prefix"
149 "VAR"
150 ":"
151 "./*"
152 ];
153 })
154 (mkWrapperBinary {
155 name = "test-suffix";
156 args = [
157 "--suffix"
158 "VAR"
159 ":"
160 "abc"
161 ];
162 })
163 (mkWrapperBinary {
164 name = "test-prefix-and-suffix";
165 args = [
166 "--prefix"
167 "VAR"
168 ":"
169 "foo"
170 "--suffix"
171 "VAR"
172 ":"
173 "bar"
174 ];
175 })
176 (mkWrapperBinary {
177 name = "test-prefix-multi";
178 args = [
179 "--prefix"
180 "VAR"
181 ":"
182 "abc:foo:foo"
183 ];
184 })
185 (mkWrapperBinary {
186 name = "test-suffix-each";
187 args = [
188 "--suffix-each"
189 "VAR"
190 ":"
191 "foo bar:def"
192 ];
193 })
194 (mkWrapperBinary {
195 name = "test-prefix-each";
196 args = [
197 "--prefix-each"
198 "VAR"
199 ":"
200 "foo bar:def"
201 ];
202 })
203 (mkWrapperBinary {
204 name = "test-suffix-contents";
205 args = [
206 "--suffix-contents"
207 "VAR"
208 ":"
209 "${foofile} ${barfile}"
210 ];
211 })
212 (mkWrapperBinary {
213 name = "test-prefix-contents";
214 args = [
215 "--prefix-contents"
216 "VAR"
217 ":"
218 "${foofile} ${barfile}"
219 ];
220 })
221 ];
222 }
223 (
224 # --argv0 works
225 mkTest "test-argv0" "argv0=foo"
226
227 # --set works
228 + mkTest "test-set" "VAR=abc"
229 # --set overwrites the variable
230 + mkTest "VAR=foo test-set" "VAR=abc"
231 # --set-default works
232 + mkTest "test-set-default" "VAR=abc"
233 # --set-default doesn"t overwrite the variable
234 + mkTest "VAR=foo test-set-default" "VAR=foo"
235 # --unset works
236 + mkTest "VAR=foo test-unset" "VAR="
237
238 # --add-flags and --append-flags work
239 + mkArgTest "test-args" [
240 "abc"
241 "xyz"
242 ]
243 # --add-flag and --append-flag work
244 + mkArgTest "test-arg" [
245 "abc 'aaaaa' jkhhjk"
246 "xyz ggg"
247 ]
248 # given flags are kept
249 + mkArgTest "test-args foo" [
250 "abc"
251 "foo"
252 "xyz"
253 ]
254
255 # --run works
256 + mkTest "test-run" "bar\nVAR="
257 # --run & --set works
258 + mkTest "test-run-and-set" "VAR=bar"
259
260 # --prefix works
261 + mkTest "VAR=foo test-prefix" "VAR=abc:foo"
262 # sets variable if not set yet
263 + mkTest "test-prefix" "VAR=abc"
264 # prepends value only once
265 + mkTest "VAR=abc test-prefix" "VAR=abc"
266 # Moves value to the front if it already existed
267 + mkTest "VAR=foo:abc test-prefix" "VAR=abc:foo"
268 + mkTest "VAR=abc:foo:bar test-prefix-multi" "VAR=abc:foo:bar"
269 # Doesn't overwrite parts of the string
270 + mkTest "VAR=test:abcde:test test-prefix" "VAR=abc:test:abcde:test"
271 # Only append the value once when given multiple times in a parameter
272 # to makeWrapper
273 + mkTest "test-prefix" "VAR=abc"
274 # --prefix doesn't expand globs
275 + mkTest "VAR=f?oo test-prefix-noglob" "VAR=./*:f?oo"
276
277 # --suffix works
278 + mkTest "VAR=foo test-suffix" "VAR=foo:abc"
279 # sets variable if not set yet
280 + mkTest "test-suffix" "VAR=abc"
281 # adds the same value only once
282 + mkTest "VAR=abc test-suffix" "VAR=abc"
283 + mkTest "VAR=abc:foo test-suffix" "VAR=abc:foo"
284 # --prefix in combination with --suffix
285 + mkTest "VAR=abc test-prefix-and-suffix" "VAR=foo:abc:bar"
286
287 # --suffix-each works
288 + mkTest "VAR=abc test-suffix-each" "VAR=abc:foo:bar:def"
289 # --prefix-each works
290 + mkTest "VAR=abc test-prefix-each" "VAR=bar:def:foo:abc"
291 # --suffix-contents works
292 + mkTest "VAR=abc test-suffix-contents" "VAR=abc:foo:bar"
293 # --prefix-contents works
294 + mkTest "VAR=abc test-prefix-contents" "VAR=bar:foo:abc"
295 + "touch $out"
296 )