mirror of
https://codeberg.org/mhwombat/nix-book.git
synced 2026-01-07 22:37:23 +08:00
193 lines
4.5 KiB
Text
193 lines
4.5 KiB
Text
= 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
|
|
////
|