Skip to content

Commit fc6d9b7

Browse files
committed
lib.modules.wrapper: move "$@" into args at order 1001
Instead of hardcoding "$@" in the wrapper template, inject it into the args list at order 1001 (just after the default flag order of 1000). This makes passthrough argument positioning controllable via the ordering system — flags with order > 1001 appear after "$@". The wrapper module passes a custom wrapper function to wrapPackage that omits the hardcoded "$@" since it's now part of args. Add flags-order check verifying: --early (500) < --greeting (1000) < "$@" (1001) < --late (1500).
1 parent 5f5ea69 commit fc6d9b7

File tree

2 files changed

+93
-0
lines changed

2 files changed

+93
-0
lines changed

checks/flags-order.nix

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
{
2+
pkgs,
3+
self,
4+
}:
5+
6+
let
7+
helloModule = self.lib.wrapModule (
8+
{ config, ... }:
9+
{
10+
config.package = config.pkgs.hello;
11+
config.flags = {
12+
# default order 1000: before "$@" (which is 1001)
13+
"--greeting" = "hello";
14+
# explicit early order: should come first
15+
"--early" = {
16+
value = true;
17+
order = 500;
18+
};
19+
# explicit late order: should come after "$@"
20+
"--late" = {
21+
value = true;
22+
order = 1500;
23+
};
24+
};
25+
}
26+
);
27+
28+
wrappedPackage = (helloModule.apply { inherit pkgs; }).wrapper;
29+
30+
in
31+
pkgs.runCommand "flags-order-test" { } ''
32+
echo "Testing flag ordering with priorities..."
33+
34+
wrapperScript="${wrappedPackage}/bin/hello"
35+
if [ ! -f "$wrapperScript" ]; then
36+
echo "FAIL: Wrapper script not found"
37+
exit 1
38+
fi
39+
40+
cat "$wrapperScript"
41+
42+
# Flatten the script to a single line for position comparison
43+
flat=$(cat "$wrapperScript" | tr -d '\n' | tr -s ' ')
44+
45+
# --early (500) should come before --greeting (1000)
46+
# --greeting (1000) should come before "$@" (1001)
47+
# "$@" (1001) should come before --late (1500)
48+
earlyPos=$(echo "$flat" | grep -bo -- '--early' | head -1 | cut -d: -f1)
49+
greetingPos=$(echo "$flat" | grep -bo -- '--greeting' | head -1 | cut -d: -f1)
50+
passthruPos=$(echo "$flat" | grep -bo '"\$@"' | head -1 | cut -d: -f1)
51+
latePos=$(echo "$flat" | grep -bo -- '--late' | head -1 | cut -d: -f1)
52+
53+
echo "Positions: early=$earlyPos greeting=$greetingPos passthru=$passthruPos late=$latePos"
54+
55+
if [ "$earlyPos" -ge "$greetingPos" ]; then
56+
echo "FAIL: --early should come before --greeting"
57+
exit 1
58+
fi
59+
if [ "$greetingPos" -ge "$passthruPos" ]; then
60+
echo "FAIL: --greeting should come before \"\$@\""
61+
exit 1
62+
fi
63+
if [ "$passthruPos" -ge "$latePos" ]; then
64+
echo "FAIL: \"\$@\" should come before --late"
65+
exit 1
66+
fi
67+
68+
echo "SUCCESS: Flag ordering test passed"
69+
touch $out
70+
''

lib/modules/wrapper.nix

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,13 @@
3131
Shell script that runs after patchPhase to modify the wrapper package files.
3232
'';
3333
};
34+
35+
# Inject "$@" (passthrough of user arguments) into args at order 1001,
36+
# so it comes just after the default flag order (1000).
37+
# Use mkOrder on args to position it; other flags can use order > 1001
38+
# to appear after "$@" if needed.
39+
config.args = lib.mkOrder 1001 [ "$@" ];
40+
3441
options.outputs.wrapper = lib.mkOption {
3542
type = lib.types.package;
3643
readOnly = true;
@@ -58,6 +65,22 @@
5865
configuration = config;
5966
}
6067
// config.passthru;
68+
# Custom wrapper function: "$@" is already in args, so don't add it again
69+
wrapper =
70+
{
71+
exePath,
72+
flagsString,
73+
envString,
74+
preHook,
75+
postHook,
76+
...
77+
}:
78+
''
79+
${envString}
80+
${preHook}
81+
${lib.optionalString (postHook == "") "exec"} ${exePath}${flagsString}
82+
${postHook}
83+
'';
6184
};
6285
};
6386
options.wrapper = lib.mkOption {

0 commit comments

Comments
 (0)