This repository has no description
2.7 kB
105 lines
1{ lib, pkgs, ... }:
2{
3 /**
4 Create a wrapped application that preserves all original outputs (man pages, completions, etc.)
5
6 # Arguments
7
8 - `package`: The package to wrap
9 - `runtimeInputs`: List of packages to add to PATH (optional)
10 - `env`: Attribute set of environment variables to export (optional)
11 - `flags`: Attribute set of command-line flags to add (optional)
12 - `wrapper`: Custom wrapper function (optional, defaults to exec'ing the original binary with flags)
13 - Called with { env, flags, envString, flagsString, exePath }
14
15 # Example
16
17 ```nix
18 makeWrapper pkgs.curl {
19 runtimeInputs = [ pkgs.jq ];
20 env = {
21 CURL_CA_BUNDLE = "${pkgs.cacert}/etc/ssl/certs/ca-bundle.crt";
22 };
23 flags = {
24 "--silent" = { }; # becomes --silent
25 "--connect-timeout" = "30"; # becomes --connect-timeout 30
26 };
27 wrapper = { exePath, flagsString, envString, ... }: ''
28 ${envString}
29 echo "Making request..." >&2
30 exec ${exePath} ${flagsString} "$@"
31 '';
32 }
33 ```
34 */
35 makeWrapper =
36 package:
37 {
38 runtimeInputs ? [ ],
39 env ? { },
40 flags ? { },
41 wrapper ? (
42 {
43 exePath,
44 flagsString,
45 envString,
46 ...
47 }:
48 ''
49 ${envString}
50 exec ${exePath}${flagsString} "$@"
51 ''
52 ),
53 }:
54 let
55 # Extract binary name from the exe path
56 exePath = lib.getExe package;
57 binName = baseNameOf exePath;
58
59 # Generate environment variable exports
60 envString =
61 if env == { } then
62 ""
63 else
64 lib.concatStringsSep "\n" (
65 lib.mapAttrsToList (name: value: ''export ${name}="${toString value}"'') env
66 )
67 + "\n";
68
69 # Generate flag arguments with proper line breaks and indentation
70 flagsString =
71 if flags == { } then
72 ""
73 else
74 " \\\n "
75 + lib.concatStringsSep " \\\n " (
76 lib.mapAttrsToList (
77 name: value: if value == { } then "${name}" else "${name} ${lib.escapeShellArg (toString value)}"
78 ) flags
79 );
80
81 finalWrapper = wrapper {
82 inherit
83 env
84 flags
85 envString
86 flagsString
87 exePath
88 ;
89 };
90 in
91 pkgs.symlinkJoin {
92 name = package.pname or package.name;
93 paths = [
94 (pkgs.writeShellApplication {
95 name = binName;
96 runtimeInputs = runtimeInputs;
97 text = finalWrapper;
98 })
99 package
100 ];
101 passthru = (package.passthru or { }) // {
102 inherit env flags;
103 };
104 };
105}