5 packageName ? package.meta.mainProgram or (pkgs.lib.getName package),
6 paths ? [ "bin/${packageName}" ],
7 name ? package.name + "-firejailed",
9 firejail ? "/run/wrappers/bin/firejail",
12 # FlexibilityNote: for tweaking the jail in a direnv or without a system rebuild
13 # this wrapper allows extra firejail flags at runtime
14 # from envvars FIREJAIL_FLAGS and FIREJAIL_FLAGS_${packageNameEscaped}
15 packageNameEscaped = pkgs.lib.concatMapStrings (s: if builtins.isList s then "_" else s) (
16 builtins.split "[^a-zA-Z0-9_]+" packageName
19 pkgs.lib.makeOverridable (
20 # CompatibilityNote: if .override(overrideArgs) is used
21 # on the wrapping package (eg. if used on programs.firefox.package),
22 # overrideArgs is passed to the wrapped package.
24 # DesignExplanation: using symlinkJoin instead of package.overrideAttrs
25 # enables to get the wrapped package from the cache as usual.
26 # The main drawback is that the user may have to inherit more attributes.
27 # eg. programs.neovim.package = pkgs.firejailWrap { … } // { inherit (pkgs.neovim-unwrapped) lua; };
30 meta = package.meta or { };
31 passthru = package.passthru or { };
32 paths = [ (package.override overrideArgs) ];
33 nativeBuildInputs = [ pkgs.makeShellWrapper ];
35 # ExplanationNote: /run/wrappers/ is not yet available
36 # hence disable that check in makeShellWrapper.
37 assertExecutable () { true; }
38 for path in ${pkgs.lib.escapeShellArgs paths}; do
40 # CorrectnessNote: in case the wrapping package is called
41 # when building a derivation (eg. in neovim: Generating remote plugin manifest)
42 # /run/wrappers/ does not exist, hence just bypass firejail using a --run.
46 --run "[ -x ${firejail} ] || exec \"${package}/$path\" \"\$@\"" \
47 --add-flags "\''${FIREJAIL_FLAGS:-}" \
48 --add-flags "\''${FIREJAIL_FLAGS_${packageNameEscaped}:-}" \
49 --add-flags "${pkgs.lib.escapeShellArgs args}" \
50 --add-flags "${package}/$path" \