Skip to content

rrbutani/nix-mk-shell-bin

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

16 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

nix-mk-shell-bin

nix develop, but at build time.

Note See NixOS/nixpkgs#206915.

what

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.

but why?

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.

do you have an example?

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;
  });
}

anything else?

This repo makes use of source code from the nix repo and, like the nix repo, is licensed under the LGPLv2.

About

`nix develop`, but at build time

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published