Skip to content

Commit 71c5ffb

Browse files
committed
separate wrapper build helper
1 parent 8ad2484 commit 71c5ffb

File tree

7 files changed

+333
-241
lines changed

7 files changed

+333
-241
lines changed

default.nix

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,21 @@ let
99
lib.evalModules {
1010
modules = [
1111
./modules/many-wrappers.nix
12-
] ++ modules;
12+
]
13+
++ modules;
1314
specialArgs = {
14-
inherit pkgs;
15-
} // specialArgs;
15+
pkgs = extendPkgs pkgs;
16+
}
17+
// specialArgs;
1618
};
19+
20+
getPkgs =
21+
pkgs:
22+
pkgs.lib.packagesFromDirectoryRecursive {
23+
inherit (pkgs) callPackage newScope;
24+
directory = ./pkgs;
25+
};
26+
extendPkgs = pkgs: pkgs.extend (_: prev: getPkgs prev);
1727
in
1828
{
1929
lib = {
@@ -27,8 +37,9 @@ in
2737
module
2838
];
2939
specialArgs = {
30-
inherit pkgs;
40+
pkgs = extendPkgs pkgs;
3141
};
3242
}).config.wrapped;
3343
};
44+
inherit getPkgs;
3445
}

docs/readme.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -172,6 +172,11 @@ https://github.com/viperML/wrapper-manager/issues
172172

173173
## Changelog
174174

175+
- 2025-07-27
176+
- Separate wrapper build helper from module system
177+
- Add `helpers` output, currently has `mkWrapper`
178+
- `wrapFlags` now read-only for access to final flags
179+
175180
- 2025-06-19
176181
- Full rewrite
177182
- `flags` has been removed in favor of `prependFlags`
Lines changed: 31 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -12,13 +12,9 @@ in
1212
{
1313
options = {
1414
wrapFlags = mkOption {
15-
type = flagsType;
16-
default = [ ];
17-
description = "Structured flags passed to makeWrapper.";
18-
example = [
19-
"--argv0"
20-
"myprog"
21-
];
15+
type = with types; separatedString " ";
16+
readOnly = true;
17+
description = "(Read-only) Final flags to wrap with";
2218
};
2319
appendFlags = mkOption {
2420
type = flagsType;
@@ -90,31 +86,34 @@ in
9086

9187
config = {
9288
wrapFlags =
93-
(flatten (
94-
map (f: [
95-
"--add-flag"
96-
f
97-
]) config.prependFlags
98-
))
99-
# Force the eval of config.flags to trigger throw
100-
++ (flatten (
101-
map (f: [
102-
"--add-flag"
103-
f
104-
]) config.flags
105-
))
106-
++ (flatten (
107-
map (f: [
108-
"--append-flag"
109-
f
110-
]) config.appendFlags
89+
(lib.escapeShellArgs (
90+
(flatten (
91+
map (f: [
92+
"--add-flag"
93+
f
94+
]) config.prependFlags
95+
))
96+
# Force the eval of config.flags to trigger throw
97+
++ (flatten (
98+
map (f: [
99+
"--add-flag"
100+
f
101+
]) config.flags
102+
))
103+
++ (flatten (
104+
map (f: [
105+
"--append-flag"
106+
f
107+
]) config.appendFlags
108+
))
109+
++ (lib.optionals (config.pathAdd != [ ]) [
110+
"--prefix"
111+
"PATH"
112+
":"
113+
(lib.makeBinPath config.pathAdd)
114+
])
115+
++ (flatten (map (e: e.asFlags) (attrValues config.env)))
111116
))
112-
++ (lib.optionals (config.pathAdd != [ ]) [
113-
"--prefix"
114-
"PATH"
115-
":"
116-
(lib.makeBinPath config.pathAdd)
117-
])
118-
++ (flatten (map (e: e.asFlags) (attrValues config.env)));
117+
+ config.extraWrapperFlags;
119118
};
120119
}

modules/wrapper-args.nix

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
{
2+
pkgs,
3+
lib,
4+
config,
5+
...
6+
}:
7+
let
8+
inherit (lib) mkOption types;
9+
10+
in
11+
{
12+
imports = [
13+
./common-wrapper-args.nix
14+
];
15+
16+
options = {
17+
basePackage = mkOption {
18+
type = with types; package;
19+
description = "Program to be wrapped";
20+
};
21+
22+
extraPackages = mkOption {
23+
type = with types; listOf package;
24+
default = [ ];
25+
description = "Optional extra packages to also wrap";
26+
};
27+
28+
programs = mkOption {
29+
default = { };
30+
description = "Wrap specific binaries with specific options. You may use it to skip wrapping some program.";
31+
example = lib.literalExpression ''
32+
{
33+
supervim = {
34+
target = "neovim";
35+
};
36+
37+
git = {
38+
env.GIT_CONFIG.value = ./gitconfig;
39+
};
40+
41+
# Don't wrap scalar
42+
scalar = {};
43+
}
44+
'';
45+
type = types.attrsOf (
46+
types.submoduleWith {
47+
modules = [
48+
./common-wrapper-args.nix
49+
(
50+
{ name, ... }:
51+
{
52+
options = {
53+
name = mkOption {
54+
type = types.str;
55+
default = name;
56+
description = "Name of the program";
57+
};
58+
59+
target = mkOption {
60+
type = with types; nullOr str;
61+
default = null;
62+
description = "Target of the program";
63+
};
64+
};
65+
66+
config = {
67+
wrapperType = lib.mkDefault config.wrapperType;
68+
};
69+
}
70+
)
71+
];
72+
}
73+
);
74+
};
75+
};
76+
}

modules/wrapper-impl.nix

Lines changed: 13 additions & 138 deletions
Original file line numberDiff line numberDiff line change
@@ -6,14 +6,6 @@
66
}:
77
let
88
inherit (lib) mkOption types;
9-
inherit (builtins) attrValues;
10-
11-
printAndRun = cmd: ''
12-
echo ":: ${cmd}"
13-
eval "${cmd}"
14-
'';
15-
16-
hasMan = builtins.any (builtins.hasAttr "man") ([ config.basePackage ] ++ config.extraPackages);
179
in
1810
{
1911
options = {
@@ -51,137 +43,20 @@ in
5143
config = {
5244
wrapped =
5345
(
54-
(pkgs.symlinkJoin {
55-
# inherit (config.basePackage) name;
56-
pname = lib.getName config.basePackage;
57-
version = lib.getVersion config.basePackage;
58-
__intentionallyOverridingVersion = true;
59-
paths = [ config.basePackage ] ++ config.extraPackages;
60-
nativeBuildInputs = [
61-
pkgs.makeBinaryWrapper
62-
pkgs.makeWrapper
63-
];
64-
passthru = (config.basePackage.passthru or { }) // {
65-
unwrapped = config.basePackage;
66-
};
67-
outputs = [
68-
"out"
69-
] ++ (lib.optional hasMan "man");
70-
meta = (config.basePackage.meta or { }) // {
71-
outputsToInstall = [
72-
"out"
73-
] ++ (lib.optional hasMan "man");
74-
};
75-
postBuild = ''
76-
pushd "$out/bin" > /dev/null
77-
78-
echo "::: Wrapping explicit .programs ..."
79-
already_wrapped=()
80-
${lib.concatMapStringsSep "\n" (
81-
program:
82-
let
83-
name = program.name;
84-
target = if program.target == null then "" else program.target;
85-
wrapProgram = if program.wrapperType == "shell" then "wrapProgramShell" else "wrapProgramBinary";
86-
makeWrapper = if program.wrapperType == "shell" then "makeShellWrapper" else "makeBinaryWrapper";
87-
in
88-
# bash
89-
''
90-
already_wrapped+="${program.name}"
91-
92-
# If target is empty, use makeWrapper
93-
# If target is not empty, but the same as name, use makeWrapper
94-
# If target is not empty, is different from name, and doesn't exist, use wrapProgram
95-
# If target is not empty, is different from name, and exists, error out
96-
97-
cmd=()
98-
if [[ -z "${target}" ]]; then
99-
cmd=(${wrapProgram} "$out/bin/${name}")
100-
elif [[ -e "$out/bin/${name}" ]]; then
101-
echo ":: Error: Target '${name}' already exists"
102-
exit 1
103-
else
104-
cmd=(${makeWrapper} "$out/bin/${target}" '${name}')
105-
fi
106-
107-
${
108-
if program.wrapFlags == [ ] && program.extraWrapperFlags == "" then
109-
"echo ':: (${name} skipped: no wrapper configuration)'"
110-
else
111-
printAndRun "\${cmd[@]} ${lib.escapeShellArgs program.wrapFlags} ${program.extraWrapperFlags}"
112-
}
113-
''
114-
) (attrValues config.programs)}
115-
116-
echo "::: Wrapping packages in out/bin ..."
117-
118-
for file in "$out/bin/"*; do
119-
# check if $file is in $already_wrapped
120-
prog="$(basename "$file")"
121-
if [[ " ''${already_wrapped[@]} " =~ " $prog " ]]; then
122-
continue
123-
fi
124-
125-
${
126-
if config.wrapFlags == [ ] && config.extraWrapperFlags == "" then
127-
"echo \":: ($prog skipped: no wrapper configuration)\""
128-
else
129-
printAndRun (
130-
let
131-
wrapProgram = if config.wrapperType == "shell" then "wrapProgramShell" else "wrapProgramBinary";
132-
in
133-
''${wrapProgram} "$file" ${lib.escapeShellArgs config.wrapFlags} ${config.extraWrapperFlags}''
134-
)
135-
}
136-
done
137-
popd > /dev/null
138-
139-
## Fix desktop files
140-
141-
# Some derivations have nested symlinks here
142-
if [[ -d $out/share/applications && ! -w $out/share/applications ]]; then
143-
echo "Detected nested symlink, fixing"
144-
temp=$(mktemp -d)
145-
cp -v $out/share/applications/* $temp
146-
rm -vf $out/share/applications
147-
mkdir -pv $out/share/applications
148-
cp -v $temp/* $out/share/applications
149-
fi
150-
151-
pushd "$out/bin" > /dev/null
152-
for exe in *; do
153-
# Fix .desktop files
154-
# This list of fixes might not be exhaustive
155-
for file in $out/share/applications/*; do
156-
trap "set +x" ERR
157-
set -x
158-
sed -i "s#/nix/store/.*/bin/$exe #$out/bin/$exe #" "$file"
159-
sed -i -E "s#Exec=$exe([[:space:]]*)#Exec=$out/bin/$exe\1#g" "$file"
160-
sed -i -E "s#TryExec=$exe([[:space:]]*)#TryExec=$out/bin/$exe\1#g" "$file"
161-
set +x
162-
done
163-
done
164-
popd > /dev/null
165-
166-
${lib.optionalString hasMan ''
167-
mkdir -p ''${!outputMan}
168-
${lib.concatMapStringsSep "\n" (
169-
p:
170-
if p ? "man" then
171-
"${lib.getExe pkgs.xorg.lndir} -silent ${p.man} \${!outputMan}"
172-
else
173-
"echo \"No man output for ${lib.getName p}\""
174-
) ([ config.basePackage ] ++ config.extraPackages)}
175-
''}
176-
177-
${config.postBuild}
178-
'';
46+
(pkgs.mkWrapper {
47+
inherit (config)
48+
basePackage
49+
extraPackages
50+
prependFlags
51+
appendFlags
52+
pathAdd
53+
env
54+
extraWrapperFlags
55+
wrapperType
56+
programs
57+
;
17958
}).overrideAttrs
180-
(
181-
final: prev: {
182-
name = "${final.pname}-${final.version}";
183-
}
184-
)
59+
(_: prev: { buildCommand = prev.buildCommand + config.postBuild; })
18560
).overrideAttrs
18661
config.overrideAttrs;
18762
};

0 commit comments

Comments
 (0)