Running the following expression with nix-shell: let pkgs = import <nixpkgs> {}; shell1 = pkgs.mkShell { shellHook = '' echo shell1 ''; }; shell2 = pkgs.mkShell { shellHook = '' echo shell2 ''; }; shell3 = pkgs.mkShell { inputsFrom = [ shell1 shell2 ]; shellHook = '' echo shell3 ''; }; in shell3 Will now results in: shell2 shell1 shell3 Note that packages in the front of inputsFrom have precedence over packages in the back. The outermost mkShell has precedence over all.
51 lines
1.2 KiB
Nix
51 lines
1.2 KiB
Nix
{ lib, stdenv }:
|
|
|
|
# A special kind of derivation that is only meant to be consumed by the
|
|
# nix-shell.
|
|
{
|
|
inputsFrom ? [], # a list of derivations whose inputs will be made available to the environment
|
|
buildInputs ? [],
|
|
nativeBuildInputs ? [],
|
|
propagatedBuildInputs ? [],
|
|
propagatedNativeBuildInputs ? [],
|
|
...
|
|
}@attrs:
|
|
let
|
|
mergeInputs = name:
|
|
let
|
|
op = item: sum: sum ++ item."${name}" or [];
|
|
nul = [];
|
|
list = [attrs] ++ inputsFrom;
|
|
in
|
|
lib.foldr op nul list;
|
|
|
|
rest = builtins.removeAttrs attrs [
|
|
"inputsFrom"
|
|
"buildInputs"
|
|
"nativeBuildInputs"
|
|
"propagatedBuildInputs"
|
|
"propagatedNativeBuildInputs"
|
|
"shellHook"
|
|
];
|
|
in
|
|
|
|
stdenv.mkDerivation ({
|
|
name = "nix-shell";
|
|
phases = ["nobuildPhase"];
|
|
|
|
buildInputs = mergeInputs "buildInputs";
|
|
nativeBuildInputs = mergeInputs "nativeBuildInputs";
|
|
propagatedBuildInputs = mergeInputs "propagatedBuildInputs";
|
|
propagatedNativeBuildInputs = mergeInputs "propagatedNativeBuildInputs";
|
|
|
|
shellHook = lib.concatStringsSep "\n" (lib.catAttrs "shellHook"
|
|
(lib.reverseList inputsFrom ++ [attrs]));
|
|
|
|
nobuildPhase = ''
|
|
echo
|
|
echo "This derivation is not meant to be built, aborting";
|
|
echo
|
|
exit 1
|
|
'';
|
|
} // rest)
|