Command Line Interface
nix-shell
When Nix builds a package, it builds it in an isolated environment. It does this by creating a clean, child shell, then adding only the dependencies the package declares. After setting up the dependencies, it runs the build script, moves the built app into the Nix store, and sets up the environment to point to it. Finally, it destroys this child shell.
But we can ask Nix to not destroy the child shell, and instead let us use it for working iteratively on the app. This is what the nix-shell is about: it will build the dependencies of the specified derivation, but not the derivation itself.
nix-shell '<nixpkgs>' -p ruby haskellPackages.stack (1)
1 | p and -A are mutually exclusive |
If a path is not given, nix-shell defaults to shell.nix
if it exists, and default.nix
otherwise.[1]
This allows for a nice trick. We can decribe a virtual dev environment (of any sort for any language) by decribing a derivation in default.nix
like so:
with import <nixpkgs> {};
let henv = haskellPackages.ghcWithPackages (p: with p; [shake]);
in
stdenv.mkDerivation {
name = "haskell-env";
buildInputs = [ henv pythonPackages.pyyaml];
}
nix-shell will use the
|
You can force any script file to run in a nix-shell as such:
#! /usr/bin/env nix-shell
#! nix-shell -i bash
or without a default.nix file:
#! /usr/bin/env nix-shell
#! nix-shell --pure
#! nix-shell -p asciidoctor -p pythonPackages.pygments
#! nix-shell -p "haskellPackages.ghcWithPackages(p: with p; [shake])" (1)
#! nix-shell -i bash
#! /usr/bin/env nix-shell
1 | Double quotes are required. Don’t add -p ghc as you will end up with two different ghcs ! |
In Haskell, we need the --attr env to tell shell.nix
|
nix-build
nix-build tool does two main jobs:
-
nix-instantiate: parse the
.nix
file and return the .drv file (the evaluation step) -
nix-store -r: realise the build product from the input .drv derivation
nix-pull is deprecated and replaced by the use of binary caches
|
nix-env
nix-env is the command to use to search, install, remove packages locally in user space (or profile). These packages are installed in the nix-store
but are only accessible inside one environment (aka user/profile).
|
-
-q list installed derivations within a profile
-
-qaP list available package with the path
When searching for packages, it is usually more efficient to specify a namespace attribute using the -A
option.
# in nixos:
→ nix-env -qaP -A nixos.haskellPackages
→ nix-env -qaP -A nixos.pythonPackages
# outside nixos:
→ nix-env -qaP -A nixpkgs.pythonPackages
You can also omit the channel namespace and specify the input for nixpkgs
explicitly with the -f
option:
→ nix-env -f '<nixpkgs>' -qaP -A haskellPackages.shake --description
-
-i install derivations
→ nix-env -f '<nixpkgs>' -iA pythonPackages.pyyaml (1) → nix-env -f '<nixpkgs>' -i brackets -I nixpkgs=https://github.com/NixOS/nixpkgs/archive/master.tar.gz’ (2)
1 on nixos, you might use nix-env -iA nixos.pythonPackages.pyyaml
2 install from master directly -
-e erase
→ nix-env -e python2.7-PyYAML-3.11
-
-u update
→ nix-env -u
Niv
Niv is an handy tool to manage sources:
niv add cicd-shell -v '3.7.2' -t 'https://github.com/PierreR/cicd-shell/archive/v<version>.tar.gz'
niv update -v 3.7.3 cicd-shell
<nixpkgs>