--- 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.