Importing Modules

Importing Nix Modules

We have the following files in 03-nix-basics/04-import:

"foo val"
[ "bar val 1" "bar val 2" ]
let
  foo = import ./foo.nix;
  bar = import ./bar.nix;
in
{ inherit foo bar; }
nix-repl> import ./code/03-nix-basics/04-import/foo.nix
"foo val"

nix-repl> import ./code/03-nix-basics/04-import/bar.nix
[ "bar val 1" "bar val 2" ]

nix-repl> import ./code/03-nix-basics/04-import
{ bar = [ ... ]; foo = "foo val"; }

Importing Global Modules

nix-repl> nixpkgs = import <nixpkgs> {}

nix-repl> nixpkgs.lib.stringLength "hello"
5

Importing a Tarball

Let's say we have the same foo.nix now available as a gist. We can import that file by asking Nix to fetch the tarball generated by GitHub:

nix-repl> gist = builtins.fetchTarball "https://gist.github.com/soareschen/d41e9b764018da4d2336644329c915e4/archive/476c45eaba13e23316cdca781bda7ec68676397b.tar.gz"

nix-repl> foo = import (gist + "/foo.nix")

nix-repl> foo
"foo val"

Pinning a Tarball Version

We have tested our remote foo.nix hosted on GitHub Gist, expecting it to have the same content as the local foo.nix we have. But the gist can be updated, yet we want to ensure that the content remains the same. This can be done by pinning the SHA256 checksum of foo.nix to what we expect using nix-prefetch-url:

$ nix-prefetch-url --type sha256 --unpack "https://gist.github.com/soareschen/d41e9b764018da4d2336644329c915e4/archive/476c45eaba13e23316cdca781bda7ec68676397b.tar.gz"
unpacking...
[0.0 MiB DL]
path is '/nix/store/vik2vk9ifbyps9pvhqa89px0c76cvaxz-476c45eaba13e23316cdca781bda7ec68676397b.tar.gz'
1ig5g6gvys26ka11z0wx08l72h8g5rr7p4fywk905sabdknf92yx

We can then copy the SHA256 checksum to make sure that the file content at the URL never unexpectedly changes:

nix-repl> gist =  builtins.fetchTarball {
            url = "https://gist.github.com/soareschen/d41e9b764018da4d2336644329c915e4/archive/476c45eaba13e23316cdca781bda7ec68676397b.tar.gz";
            sha256 = "1ig5g6gvys26ka11z0wx08l72h8g5rr7p4fywk905sabdknf92yx";
          }

Pinning Nixpkgs

We can use the same approach to pin nixpkgs itself. By pinning nixpkgs to a specific commit ID and SHA256 checksum, we can be sure that everyone that uses our Nix module are using the exact version of nixpkgs that we have specified.

For instance, we can pin the nixpkgs version we use to commit c1e5f8723ceb684c8d501d4d4ae738fef704747e:

$ nix-prefetch-url --type sha256 --unpack \
>     "https://github.com/NixOS/nixpkgs/archive/c1e5f8723ceb684c8d501d4d4ae738fef704747e.tar.gz"
unpacking...
[19.6 MiB DL]
path is '/nix/store/7ik3kdki828cnva46vnis87ha6axjk7n-c1e5f8723ceb684c8d501d4d4ae738fef704747e.tar.gz'
02k3l9wnwpmq68xmmfy4wb2panqa1rs04p1mzh2kiwn0449hl86j

Now we can import our pinned nixpkgs:

nix-repl> nixpkgs-src =  builtins.fetchTarball {
            url = "https://github.com/NixOS/nixpkgs/archive/c1e5f8723ceb684c8d501d4d4ae738fef704747e.tar.gz";
            sha256 = "02k3l9wnwpmq68xmmfy4wb2panqa1rs04p1mzh2kiwn0449hl86j";
          }

nix-repl> nixpkgs = import nixpkgs-src {}

nix-repl> nixpkgs.lib.stringLength "hello"
5

Pinning nixpkgs is highly encouraged when developing Nix modules. Without pinning, your users may run your modules on a version of nixpkgs that is several months old.

We will go through in a later chapter on how to use niv to automate the management of pinned remote Nix packages.