her.esy.fun/src/drafts/XXXX-how-i-use-nix/index.org
Yann Esposito (Yogsototh) 9eb7ecb8ef
save
2020-06-15 00:02:26 +02:00

6.1 KiB

How I use nix

Have you ever written a small script and you update your system and this stop working? Have you copied your tool/script to another machine it doesn't work because some dependency is missing? Have you tried to sync your dotfiles to another env and there are a few details not working? Some missing dependency? If the answer is yes, then nix can help.

Scripts

Suppose you want to write a portable script. For example, the script I use to minify my CSS. Here it is:

#!/usr/bin/env nix-shell
#!nix-shell --pure
#!nix-shell -i bash
#!nix-shell -I nixpkgs="https://github.com/NixOS/nixpkgs/archive/19.09.tar.gz"
#!nix-shell -p bash minify

minify "$1" > "$2"

So let's analyze each line of the header block:

#!/usr/bin/env nix-shell
basic, use nix-shell to run the script.
#!nix-shell --pure
only use dependencies installed in this nix shell environment. A bit as if the PATH environment variable was emptied.
#!nix-shell -i bash
tell nix-shell to run bash
#!nix-shell -I nixpkgs="https://github.com/NixOS/nixpkgs/archive/19.09.tar.gz"
pin the nixpkgs using this archive.
#!nix-shell -p bash minify
install bash and minify in the nix shell.

Now if the script is run on a machine with nix installed you can be pretty sure it will work as expected. Even if I update my OS and I forget about this script for a few years. As long as I can install nix on the new system and I could download the tar file the script will be run the same way as the day I wrote it.

Remark: You can use any shell (like fish, zsh) but also other languages python, haskell, etc…

Temporary working env

Quite often, I need to do something, and run a specific command that need me to install a very specific command. And I'm pretty sure I will not use this tool ever again.

For those cases, what I do, is generally run my command directly with a fresh nix-shell.

> nix-shell -p httpie
[nix-shell:~]$ ... here I can use httpie ...

Home Manager

A few years ago I used brew to install the tools I need. With nix you can install a new tool with nix-env -i instead of brew install. Still recently I prefer to use home-manager.

The main advantage is that it is even more reproductible and can easily be shared accross different machines.

Mainly when I need a new binary I add it in a description list in the file ~/.config/nixpkgs/home.nix. It looks like this:

home.packages = with pkgs; [
  # emacs
  emacsMacport
  imagemagick
  gnupg
  # shell
  direnv
  ...
];

then I simply run home-manager switch and I've got all those tools in my env.

Pinning the packages

{ config, pkgs, ... }:
let
  # ...
  pkgs = import (fetchGit {
    name = "nixpkgs20";
    url = "https://github.com/NixOS/nixpkgs";
    # obtained via
    # git ls-remote https://github.com/NixOS/nixpkgs nixpkgs-20.03-darwin
    ref = "refs/heads/nixpkgs-20.03-darwin";
    rev = "58f884cd3d89f47672e649c6edfb2382d4afff6a";
  }) {};
  # ...
in {
  # ...
}

Specific tools

There are a few noticiable artifact here:

The first one is weechat is a very specify build of weechat with the plugin I need. So here is the block I use:

let
  ...
  weechat-with-weeslack = weechat.override {
      configure = { availablePlugins, ... }: {
        # plugins = with availablePlugins; [ python perl guile ];
        scripts = with pkgs.weechatScripts; [ wee-slack ];
      };
    };
  ...
in
{
  ...
  home.packages = with pkgs; [... weechat-with-wee-slack ...];
  ...
}

Even if this looks cryptic. The important detail is just that there exists a way to say to nix I'd like to use weechat (an IRC client) with the wee-slack client (which uses python). And nix handle the rest for me.

Another nice tool is sws

I use macOS so even though I'm using a darwin focused nixpkgs sometimes a few package can be broken and can't be installed.

That occurred with sws during the upgrade to 20.03 on darwin. This is a simple tool that need haskell to be compiled locally and installed. Here is how I could install it:

let
  ...
  rel19 = import (fetchGit {
    name = "nixpkgs19";
    url = "https://github.com/NixOS/nixpkgs";
    ref = "refs/heads/nixpkgs-19.09-darwin";
    rev = "2f9bafaca90acd010cccd0e79e5f27aa7537957e";
  }) {};
  ...
in
  home.packages = with pkgs; [
    ...
    ghc
    rel19.haskellPackages.sws
    ...
  ]

So I used the older version from 19.09.

1: I'm using macOS, and I have multiple macs. A laptop and two desktop machines. Using the 27″ iMac is my ultimate work station. It really enhance my productivity. Still the laptop is a superior work environment for more casual tasks. I guess I might write someday about my full work environment.

Install

First, let's start by the bad news. Recent macOS security policy made nix a bit harder to install on a mac. See macOS Installation instructions.

Once you have nix installed you should update the nix-channel. Mainly a nix-channels is where are the definitions of all the packages. See nixOS documentation.