nix develop
, but at build time.
Note See NixOS/nixpkgs#206915.
This is a nix expression that replicates the transformation nix develop
does on derivations, ultimately yielding a script that, when run, drops you into a nix develop
-like shell.
Mostly for nix-bundle
.
I wanted to be able to package a mkShell
derivation as a self-contained executable; you can't do this directly since mkShell
doesn't actually produce a binary that you can run (mkShell
used to actually produce derivations that you couldn't even build normally).
mkShell
instead relies on nix develop
(or nix-shell
) to extract information from the derivation and construct an environment from it. mkShellBin
does more or less the same steps to construct this environment but does so as part of building its derivation.
Sure. This repo is packaged as a flake, so:
{
# Add to your flake's inputs:
inputs.msb = github:rrbutani/nix-mk-shell-bin;
# Use `mkShellBin`, exposed under `lib`:
outputs = { msb, ... }: let
mkShellBin = msb.lib.mkShellBin;
in {
# ...
};
}
mkShellBin
takes:
{ drv
, nixpkgs
, bashPrompt ? null
, bashPromptPrefix ? null
, bashPromptSuffix ? null
}
Here's an example flake that you can run:
{
inputs = {
msb.url = github:rrbutani/nix-mk-shell-bin;
nixpkgs.url = github:nixOS/nixpkgs/22.11;
flu.url = github:numtide/flake-utils;
};
outputs = { msb, nixpkgs, flu, ... }: with msb.lib; with flu.lib; eachDefaultSystem(system: let
np = nixpkgs.legacyPackages.${system};
# Like `nix-shell`, this will build the dependencies of `pkg` but not
# `pkg` itself.
pkg = np.hello;
pkgShellBin = mkShellBin { drv = pkg; nixpkgs = np; };
# Here, `shellBin` *will* build `pkg`. This is like `nix develop`.
shell = np.mkShell { name = "example"; nativeBuildInputs = [pkg]; };
shellBin = msb.lib.mkShellBin { drv = shell; nixpkgs = np; bashPrompt = "[hello]$ "; };
in {
# You can run `nix bundle` and get a self-contained executable that, when
# run, drops you into a shell containing `pkg`.
packages.default = shellBin;
packages.pkgShellBin = pkgShellBin;
# You can run the derivations `mkShellBin` produces:
apps.default = { type = "app"; program = "${shellBin}/bin/${shellBin.name}"; };
# The above is more or less equivalent to:
devShells.default = shell;
# For more advanced usage, the env file that `mkShellBin` produces is also
# available under `.envScript`; you can source this from within your own
# scripts or pass this to bash as an `--rcfile` yourself.
packages.envScript = pkgShellBin.envScript;
});
}
This repo makes use of source code from the nix
repo and, like the nix
repo, is licensed under the LGPLv2.