initial commit

This commit is contained in:
Amy de Buitléir 2025-10-12 16:00:37 +01:00
parent 309202f9b4
commit bd70f8eb74

View file

@ -0,0 +1,193 @@
= Bash
In this section we will create a very simple flake, and then make several improvements.
To follow along, open a new terminal shell.
Start with an empty directory and create a git repository.
....
$ mkdir my-project
$ cd my-project
$ git init
....
This will be a very simple development project,
so that we can focus on how to use Nix.
We want to package the following script.
////
$ cp ../cow-hello.sh .
////
[source,bash,linenums]
.cow-hello.sh
....
$# cat cow-hello.sh
....
Add the script to your directory and we will test it.
....
$ chmod +x cow-hello.sh
$ ./cow-hello.sh # Fails
....
This probably failed on your machine -- why?
The `cow-hello.sh` script depends on `cowsay`,
which isn't part of your default environment (unless you specifically configure Nix or NixOS to include it).
We can create a suitable temporary environment for a quick test:
....
$ nix shell nixpkgs#cowsay
$ ./cow-hello.sh # Succeeds
....
However, that approach becomes inconvenient once you have more dependencies.
Let's exit to the original (default) environment,
and see that `cowsay` is no longer available.
....
$ exit
$ ./cow-hello.sh # Fails again
....
For a single script like this, we could modify it by replacing the first line with a "Nix shebang",
as shown later in <<#shebang>>;
then the script would run in any Nix environment.
But for this exercise, we will package it as a "proper" development project.
We want to define the development environment we need for this project,
so that we can recreate it at any time.
Furthermore, anyone else who wants to work on our project will be able to recreate
the same development environment we used.
This avoids complaints of "but it works on my machine!"
////
$ cp ../flake.nix .
////
Create the file `flake.nix` as shown below.
If you're not on an `x86_64-linux` system, modify the highlighted lines accordingly.
[NOTE]
====
If you're not sure of the correct string so use for your system,
run the following command.
nix eval --impure --raw --expr 'builtins.currentSystem'
====
[source,nix,linenums,highlight="10,12,14"]
.flake.nix (version 1)
....
$# cat flake.nix
....
The `description` part is just a short description of the package.
The `inputs` section should be familiar from <<#flake-inputs>>.
If we ignore parts of the long package names, the `outputs` section looks like this:
[source,subs=quotes]
....
devShells = {
x86_64-linux.default =
_blahblah_.mkShell {
packages = [
_blahblah_.cowsay
];
}; # mkShell
}; # devShells
....
This says, in effect, that to create a `default` shell for the `x86_64-linux` architecture,
call the `mkShell` command and tell it you need the `cowsay` package.
We can refactor the code to eliminate some duplication.
[source,nix]
....
devShells = {
x86_64-linux.default =
let
pkgs = nixpkgs.legacyPackages.x86_64-linux;
in
pkgs.mkShell {
packages = [
pkgs.cowsay
];
}; # mkShell
}; # devShells
....
After a bit more refactoring, here's the entire flake.
You may want to compare this carefully to the original version,
in order to reassure yourself that the definitions are equivalent.
////
$ cp ../flake-3.nix flake.nix
////
[source,nix,linenums]
.flake.nix (version 2)
....
$# cat flake.nix
....
Let's enter the shell.
....
$# echo '$ nix develop # Fails'
$# nix develop --command sh
....
Because we haven't added `flake.nix` to the git repository, it's essentially invisible to Nix.
Let's correct that and try again.
....
$ git add flake.nix
$# echo '$ nix develop'
$# nix develop --command sh
....
The warning is because the changes haven't been committed to the git repository yet.
We changed `flake.nix` of course, but when we ran `nix develop` it automatically created a `flake.lock` file.
Don't worry about the warnings for now.
We can see that `cowsay` is now available, and our script runs.
....
$ ./cow-hello.sh # Succeeds
....
We created an appropriate development environment, and tested our script.
Now we are ready to package it.
Add the new lines below to `flake.nix`.
////
$ cp ../flake-4.nix flake.nix
////
[source,nix,linenums,highlight="23..48"]
.flake.nix (version 3)
....
$# cat flake.nix
....
MAYBE INTRODUCE GETATTRS EARLIER
CONTINUE HERE
CONTINUE HERE
CONTINUE HERE
CONTINUE HERE
....
$ nix run
....
== Supporting multiple architectures
////
Good adoc0 scripts clean up after themselves.
$ cd .. ; rm -rf my-project # clean up
////