yoke/nix/module.nix
2025-11-09 02:24:47 +11:00

95 lines
2.7 KiB
Nix

{
pkgs,
lib,
config,
...
}:
let
inherit (lib) mkOption mkPackageOption types;
strNotEmpty = s: lib.stringLength s != 0;
wrapperType = lib.types.submodule {
options = {
package = mkPackageOption "wrapped" { } {
nullable = false;
};
executable = mkOption {
type = types.str;
default = "";
};
args = mkOption {
type = types.listOf types.str;
default = [ ];
};
env = mkOption {
type = types.attrsOf (types.listOf types.str);
default = { };
};
retainEnv = mkOption {
type = types.bool;
default = false;
};
addPwd = mkOption {
type = types.bool;
default = false;
};
additionalPaths = mkOption {
type = types.listOf types.str;
default = [ ];
};
};
};
in
{
options = {
wrappers = mkOption {
type = types.attrsOf wrapperType;
};
wrapperPkg = mkPackageOption "wrapper" { } { nullable = false; };
};
config =
let
wrap =
name: opts:
let
envs = lib.concatStringsSep " " (
lib.mapAttrsToList (n: v: "${n}=${lib.concatStringsSep ":" v}") opts.env
);
extra = lib.concatStringsSep " " opts.additionalPaths;
sandboxArgs = pkgs.stdenvNoCC.mkDerivation {
name = "${name}-opts";
__structuredAttrs = true;
exportReferencesGraph.closure = [ opts.package ];
preferLocalBuild = true;
nativeBuildInputs = [
pkgs.coreutils
pkgs.jq
];
buildCommand = ''
echo -n "--fs rx=" > $out
jq -r '.closure[].path' < "$NIX_ATTRS_JSON_FILE" \
| tr '\n' ':' | sed 's/:$//' >> $out
${if (lib.length opts.additionalPaths != 0) then "echo -n ' ${extra}' >> $out" else ""}
${if (strNotEmpty envs) then "echo -n ' --env ${envs}' >> $out" else ""}
'';
};
command = lib.getExe' opts.package (
if (strNotEmpty opts.executable) then opts.executable else opts.package.pname
);
wrappedArgs = lib.concatStringsSep " " opts.args;
script = ''
#! /usr/bin/env bash
${lib.getExe' config.wrapperPkg "yoke"} \
${if opts.addPwd then "--fs rwx=$PWD" else ""} \
${if opts.retainEnv then "--retain-env" else ""} \
--fd-args -- \
${command} \
${wrappedArgs} $@ \
3< ${sandboxArgs}
'';
in
pkgs.writeScriptBin "${name}" script;
in
{
environment.systemPackages = lib.mapAttrsToList wrap config.wrappers;
};
}