{ lib, stdenv, buildEnv }: # A special kind of derivation that is only meant to be consumed by the # nix-shell. { name ? "nix-shell" , # a list of packages to add to the shell environment packages ? [ ] , # propagate all the inputs from the given derivations inputsFrom ? [ ] , buildInputs ? [ ] , nativeBuildInputs ? [ ] , propagatedBuildInputs ? [ ] , propagatedNativeBuildInputs ? [ ] , ... }@attrs: let mergeInputs = name: (attrs.${name} or [ ]) ++ (lib.subtractLists inputsFrom (lib.flatten (lib.catAttrs name inputsFrom))); rest = builtins.removeAttrs attrs [ "name" "packages" "inputsFrom" "buildInputs" "nativeBuildInputs" "propagatedBuildInputs" "propagatedNativeBuildInputs" "shellHook" ]; in stdenv.mkDerivation ({ inherit name; buildInputs = mergeInputs "buildInputs"; nativeBuildInputs = packages ++ (mergeInputs "nativeBuildInputs"); propagatedBuildInputs = mergeInputs "propagatedBuildInputs"; propagatedNativeBuildInputs = mergeInputs "propagatedNativeBuildInputs"; shellHook = lib.concatStringsSep "\n" (lib.catAttrs "shellHook" (lib.reverseList inputsFrom ++ [ attrs ])); phases = [ "buildPhase" ]; buildPhase = '' { echo "------------------------------------------------------------"; echo " WARNING: the existence of this path is not guaranteed."; echo " It is an internal implementation detail for pkgs.mkShell."; echo "------------------------------------------------------------"; echo; # Record all build inputs as runtime dependencies export; } >> "$out" ''; preferLocalBuild = true; } // rest)