jungle/web/content/intro-nix/ch2.md

156 lines
5.4 KiB
Markdown

---
title: "Chapter 2: Your first shell"
date: 2023-09-15
weight: 2
---
## Creating a shell with flake.nix
First, create an empty git repository where your shells will live:
```txt
hut% mkdir jungle-examples
hut% cd jungle-examples
hut% git init
Initialized empty Git repository in /home/Computational/rarias/jungle-examples/.git/
```
And then, place a file named `flake.nix` on the repo with this content:
```nix
{
inputs.jungle.url = "jungle";
nixConfig.bash-prompt = "\[nix-develop\]$ ";
outputs = { self, jungle }:
let
pkgs = jungle.outputs.packages.x86_64-linux;
in {
devShells.x86_64-linux.default = pkgs.mkShell rec {
pname = "my-shell";
buildInputs = with pkgs.bsc; [
ovni osumb # other packages here...
];
};
};
}
```
This file defines a how to create a shell in the Nix language with the
`pkgs.mkShell` function using the packages listed in `buildInputs`. It also
requests the packages to be taken from the *jungle* input, which corresponds to
the set of packages that [we defined earlier](../ch1#where-packages-come-from),
tuned for the cluster. We will describe it in more detail later.
The tool `nix develop` tries to find a flake.nix in the current directory and
enter the shell described by `devShells.x86_64-linux.default` (or the
corresponding architecture).
Now, **it is important that all the files of the repository are committed in
git**, as nix will only read what is in the index of git. If we try to enter the
shell with the `nix develop` command, it will complain and fail:
```txt
hut% nix develop
warning: Git tree '/home/Computational/rarias/jungle-examples' is dirty
error: getting status of '/nix/store/0ccnxa25whszw7mgbgyzdm4nqc0zwnm8-source/flake.nix': No such file or directory
```
The first warning states that the git directory has modified files not added to
the index. Then the error occurs because the flake.nix is not in the index of
git, so `nix develop` doesn't see it. So let's add it to a commit and try again:
```txt
hut% git add flake.nix
hut% git commit flake.nix -m 'First shell'
[master (root-commit) eb8a4ac] First shell
1 file changed, 13 insertions(+)
create mode 100644 flake.nix
hut% nix develop
warning: creating lock file '/home/Computational/rarias/jungle-examples/flake.lock'
warning: Git tree '/home/Computational/rarias/jungle-examples' is dirty
[nix-develop]$
```
In the `flake.nix` we have set the shell prompt to `[nix-develop]` so we can
easily spot that we are inside a `nix develop` shell. To exit:
```txt
[nix-develop]$ exit
hut%
```
## Using the flake.lock file
Now we see the `creating lock file` message and the git tree becomes dirty
again (however, we enter the shell successfully).
This `flake.lock` file that has been created collects the current state of the
jungle packages in a file, so future invocations will use the same versions. We
can see more details with `nix flake metadata`:
```txt
hut% nix flake metadata
warning: Git tree '/home/Computational/rarias/jungle-examples' is dirty
Resolved URL: git+file:///home/Computational/rarias/jungle-examples
Locked URL: git+file:///home/Computational/rarias/jungle-examples
Path: /nix/store/bckxqjkkv52hy4pzgb96r7fchhmvmql8-source
Revision: eb8a4ac544a74e3995d859c751e9ff4339de6509-dirty
Last modified: 2023-09-15 13:06:12
Inputs:
└───jungle: path:/nix/store/3wv6q0f3pkgw840nnkn4jsp9xi650dyj-source?lastModified=1694772033&narHash=sha256-7a09O0Jb8WncxeB32ywmQEMqJdEFLrOG/XVT9bdII6I%3D&rev=653d411b9e46076a7878be9574ed6b3bd627cff1&revCount=195
├───agenix: github:ryantm/agenix/d8c973fd228949736dedf61b7f8cc1ece3236792
│ ├───darwin: github:lnl7/nix-darwin/87b9d090ad39b25b2400029c64825fc2a8868943
│ │ └───nixpkgs follows input 'jungle/agenix/nixpkgs'
│ ├───home-manager: github:nix-community/home-manager/32d3e39c491e2f91152c84f8ad8b003420eab0a1
│ │ └───nixpkgs follows input 'jungle/agenix/nixpkgs'
│ └───nixpkgs follows input 'jungle/nixpkgs'
├───bscpkgs: git+https://pm.bsc.es/gitlab/rarias/bscpkgs.git?ref=refs/heads/master&rev=3a4062ac04be6263c64a481420d8e768c2521b80
│ └───nixpkgs follows input 'jungle/nixpkgs'
└───nixpkgs: github:NixOS/nixpkgs/e56990880811a451abd32515698c712788be5720
```
Now, as long as we keep these two files `flake.nix` and `flake.lock`, we can
reproduce the same shell in the future, so let's add the lock file into git too.
```txt
hut% git commit -m 'Add flake.lock file'
[master d3725ec] Add flake.lock file
1 file changed, 135 insertions(+)
create mode 100644 flake.lock
hut% git status
On branch master
nothing to commit, working tree clean
```
## Using the shell with nix develop
Now, the invocations of `nix develop` won't complain that the git tree is dirty
anymore and will enter the shell:
```txt
hut% nix develop
[nix-develop]$
```
And the requested packages are now available:
```txt
[nix-develop]$ which ovniemu
/nix/store/0yzas8007x9djlpbb0pckcr1vhd0mcfy-ovni-1.3.0/bin/ovniemu
```
The packages of the shell are listed in the `$buildInputs` variable, in case you
need to examine them:
```txt
[nix-develop]$ printf '%s\n' $buildInputs
/nix/store/0yzas8007x9djlpbb0pckcr1vhd0mcfy-ovni-1.3.0
/nix/store/lnjirzllhjn2fadlqzrz7a547iawl8jc-osu-micro-benchmarks-7.1-1
[nix-develop]$ exit
hut%
```
In the [next chapter](../ch3) we will see how to add more packages and also how to modify
them.