diff --git a/doc/builders/special.xml b/doc/builders/special.xml index 8902ce5c81329..7c052db223a0d 100644 --- a/doc/builders/special.xml +++ b/doc/builders/special.xml @@ -7,4 +7,5 @@ + diff --git a/doc/builders/special/mkshellMinimal.section.md b/doc/builders/special/mkshellMinimal.section.md new file mode 100644 index 0000000000000..667b65006248e --- /dev/null +++ b/doc/builders/special/mkshellMinimal.section.md @@ -0,0 +1,38 @@ +# pkgs.mkShellMinimal {#sec-pkgs-mkShellMinimal} + +`pkgs.mkShellMinimal` is similar to `mkShell` but does not rely on the +`stdenv` or even `bash`. It has a much smaller footprint and feature-set than +`mkShell` and is useful if you care about your closure size or being very explicit +about the dependencies (i.e. coreutils vs. busybox). + +## Usage {#sec-pkgs-mkShellMinimal-usage} + +```nix +let + nixpkgs = import { }; +in +with nixpkgs; +mkShellMinimal { + name = "my-minimal-shell"; + + # Place your dependencies here + packages = [ ]; + + # You can do typical environment variable setting + FOO = "bar"; +} +``` + +This shell can be started with `nix-shell` and has zero dependencies. + +```bash +❯ nix path-info -rSsh $(nix-build shell.nix) +This derivation is not meant to be built, unless you want to capture the dependency closure. + +/nix/store/8ka1hnlf06z3h2rpd00b4d9w5yxh0n39-setup 376.0 376.0 +/nix/store/nprykggfqhdkn4r5lxxknjvlqc4qm1yl-builder.sh 280.0 280.0 +/nix/store/xd8d72ccrxhaz3sxlmiqjnn1z0zwfhm8-my-minimal-shell 744.0 1.4K +``` + +`mkShellMinimal` is buildable as opposed to `mkShell`. This is useful if you want to upload the +transitive closure of the shell to a remote nix-store. diff --git a/pkgs/build-support/mkshell/minimal.nix b/pkgs/build-support/mkshell/minimal.nix new file mode 100644 index 0000000000000..b630a0aa22ee1 --- /dev/null +++ b/pkgs/build-support/mkshell/minimal.nix @@ -0,0 +1,59 @@ +{ writeTextFile, writeScript, system }: + +# A special kind of derivation that is only meant to be consumed by the +# nix-shell. This differs from the traditional `mkShell` in that: +# It does not come with traditional stdenv (i.e. coreutils). +# Its only dependency is essentially bash. +{ +# a list of packages to add to the shell environment +# we simplify here rather than `native` or `propagated` since +# this is only ever used to be in a nix-shell; which is by default +# the current system +packages ? [ ], ... }@attrs: +derivation ({ + inherit system; + + name = "minimal-nix-shell"; + + # Nix checks if the stdenv attribute exists and sources that + # We use it here to setup the pure enviroment and do to clear envs like PATH + # reference: https://github.com/NixOS/nix/blob/94ec9e47030c2a7280503d338f0dca7ad92811f5/src/nix-build/nix-build.cc#L494 + "stdenv" = writeTextFile rec { + name = "setup"; + executable = true; + destination = "/${name}"; + text = '' + set -e + + # This is needed for `--pure` to work as expected. + # https://github.com/NixOS/nix/issues/5092 + PATH= + + for p in $packages; do + export PATH=$p/bin:$PATH + done + ''; + }; + + # Typically `mkShell` is not buildable. This has made it in practice, difficult to upload + # the dependency closure to a binary cache. Rather than add a confusing attribute to capture this + # let's just make the nix-shell buildable but message to the user that it doesn't make much sense. + # + # + # The builtin `export` dumps all current environment variables, + # which is where all build input references end up (e.g. $PATH for + # binaries). By writing this to $out, Nix can find and register + # them as runtime dependencies (since Nix greps for store paths + # through $out to find them) + # https://github.com/NixOS/nixpkgs/pull/95536/files#diff-282a02cc3871874f16401347d8fadc90d59d7ab11f6a99eaa5173c3867e1a160R358 + # + # For purity you generally don't want to rely on /bin/sh but since this derivation is *strictly* for a nix-shell + # we can rely on the fact that the underlying system is POSIX compliant. + builder = writeScript "builder.sh" '' + #!/bin/sh + echo + echo "This derivation is not meant to be built, unless you want to capture the dependency closure."; + echo + export > $out + ''; +} // attrs) diff --git a/pkgs/top-level/all-packages.nix b/pkgs/top-level/all-packages.nix index 1e3d3178ea0b3..b8391f30223bc 100644 --- a/pkgs/top-level/all-packages.nix +++ b/pkgs/top-level/all-packages.nix @@ -623,6 +623,7 @@ in mkShell = callPackage ../build-support/mkshell { }; mkShellNoCC = mkShell.override { stdenv = stdenvNoCC; }; + mkShellMinimal = callPackage ../build-support/mkshell/minimal.nix { }; nixBufferBuilders = import ../build-support/emacs/buffer.nix { inherit (pkgs) lib writeText; inherit (emacs.pkgs) inherit-local; };