Skip to content

Instantly share code, notes, and snippets.

@icetan
Last active February 12, 2025 10:41
Show Gist options
  • Save icetan/9eb02ec117ed41c2d24aaf4efd228505 to your computer and use it in GitHub Desktop.
Save icetan/9eb02ec117ed41c2d24aaf4efd228505 to your computer and use it in GitHub Desktop.
# Smooll the small nix shell
{ pkgs, ... }:
{
name,
system ? pkgs.system,
packages ? [ ],
shellHook ? "",
env ? { },
coreutils ? pkgs.coreutils,
}:
let
inherit (builtins)
toJSON
placeholder
mapAttrs
concatStringsSep
attrNames
isList
;
listToStr = ls: if (isList ls) then concatStringsSep " " ls else ls;
inputs = [ coreutils ] ++ packages;
binPaths = pkgs.lib.makeBinPath inputs;
unsetScript = concatStringsSep "\n" (
map (name: "unset ${name}") ((attrNames requiredVariables) ++ (attrNames drvAttrs))
);
shellHook' = ''
export PATH="''${PATH}''${PATH:+:}${binPaths}"
${shellHook}
${unsetScript}
'';
requiredVariables = {
out = placeholder "out";
outputs = "out";
shellHook = shellHook';
};
variables = mapAttrs (_: value: {
type = "exported";
inherit value;
}) ((mapAttrs (_: listToStr) env) // requiredVariables);
drvAttrs = {
inherit name system;
builder = pkgs.stdenv.shell;
args = [
"-c"
''{ export; } >> "$out"''
];
varsJSON = toJSON { inherit variables; };
};
drv = derivation (
drvAttrs
// env
// {
# Create a minimal stdenv setup script
# - try to write metadata as JSON `$out`
# - if `$out` can't be written to assume that `nix-shell` is being used
# and eval shellHook
stdenv = pkgs.writeTextDir "setup" ''
writeOut() { echo "$varsJSON" > "$out"; }
if { writeOut 2>&1; } >/dev/null; then :
else
${shellHook'}
fi
'';
}
);
in
drv
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment