The world in a Shell

Everyone starts using shell environments, where custom variables are available, custom bash functions are enabled, special commands are available, maybe even some additional programs are installed.

Projects on github pop up for handling these things, installing bash “environments” and so on. And I have to ask: Why?

Why would you do that?

I tell you, there’s a solution to all of your problems. It is called “nix”. It is a package manager which provides you opportunities, you’ve never dreamed of!

Yes, you could hack the functionality of these project-environment-manager things yourself (that’s what people did, then they put it on github and now you see it and decide to write your own becaues you can do it better). You could use this piece of clusterbash and suffer from impurities you’d never expect. Or, you could just use the purity of the nix package manager to deploy the world in a shell.

With the nix package manager, you can use custom project-based environments to install packages neither globally nor in your user package environment:

nix-shell -p haskellPackages.pandoc

for example installs “Pandoc” and starts a shell where it is available. The executable is not available anymore after you type exit. It is not installed in your system, it is not even installed in you user package set. It was available in this shell and only will be available again after you entered this shell via nix-shell.

I have a lot of packages…

… so have I. Normally, I install one or two packages via commandline in my nix-shell environment. If there are more packages or I need the packages on multiple systems (when developing something, for example), I add a default.nix file to the repository:

{ stdenv, pkgs ? (import <nixpkgs> {}) }:

let
  env = with pkgs; [ racket ];
in

stdenv.mkDerivation rec {
    name        = "blog";
    src         = ./.;
    version     = "0.0.0";
    buildInputs = [ env ];
}

The I only have to type nix-shell to enter the environment.

Another idea would be to install the packages “persistent”, so after a call to nix-collect-garbage won’t remove the packages from the ominous store where the packages live:

nix-instantiate . --indirect --add-root $PWD/shell.drv
nix-shell $PWD/shell.drv

(copy-pasted from the nixos-wiki)