Package Management
Bob takes advantage of Nix to manage dependencies. Nix supports all common programming languages and codgenerators like: golang, nodejs, python, java, protoc, openapi-generator etc.
You can check search.nixos.org/packages for a complete list of available packages.
The dependencies are stored in /nix/store. Bob's internal shell takes care of making them available to each tasks environment. This isolates the execution of tasks from the system and aims to get rid of "Works on My Machine".
To learn more about Nix read Nix Package Manager Manual or Nixpkgs Manual.
A Hello World example
First, make sure to have Nix installed. This allows Bob to override the
PATH variable with dependencies from the /nix/store/. Be prepared to declare all required binaries for you build in
the dependencies
section.
Bellow, is a example build-task which will uses the GNU Hello program.
build:
run-hello:
cmd: hello
dependencies:
- hello
Now run bob build run-hello --no-cache
$ bob build run-hello --no-cache
Building nix dependencies...
/nix/store/js9xgkjs8qhjv6r48g1dk9ian8iszg8w-hello-2.12
Running task run-hello with 0 dependencies
run-hello running task...
run-hello Hello, world!
run-hello ...done
As you see Nix will download the binary and places it inside the /nix/store. Bob assures that the path of the binary is available in your $PATH when running this task.
Dependencies can be declared for all tasks at once or for each task individually. Task level dependencies
have
priority.
How to Declare Dependencies
Dependencies are declared by the name of the package from Nixpkgs. You can also provide a path to a .nix file containing a Nix expression.
Using a package with multiple versions
Let's assume you want 2 tasks which need 2 different versions of Go. Which can be handy when you want to update microservices one-by-one. You can declare your tasks like so:
build:
run-go-version:
cmd: go version
dependencies:
- go_1_18
run-go-lower-version:
cmd: go version
dependencies:
- go_1_16
nixpkgs: https://github.com/NixOS/nixpkgs/archive/6eed87d4490ce045dda1091999d1e38605afb8ea.tar.gz
Building run-go-version
and run-go-lower-version
you'll notice that they each output a different Go version:
$ bob build run-go-version --no-cache
run-go-version running task...
run-go-version go version go1.18.1 linux/amd64
$ bob build run-go-lower-version --no-cache
run-go-lower-version running task...
run-go-lower-version go version go1.16.15 linux/amd64
How to find a package
You can go to NixOS binary cache server and search for your desired
package.
Copy its name and add it to dependencies
node.
For example, if you want to use PHP 7.4, search for PHP and add php74
to your dependencies
:
Using your custom .nix file
Nixpkgs repository has over 60 000 packages, but sometimes you might not find what you need. In that case, you can write
your own Nix expression file and add it in your dependencies
:
build:
run-version:
cmd: ginkgo version
dependencies:
- ginkgo_1.16.5.nix
This will search for a ginkgo_1.16.5.nix
file in your working directory and try to build it with nix-build
. To learn
more how to write Nix expressions check the Nix Package Manager Manual.
Here is the content of ginkgo_1.16.5.nix
:
{ lib, buildGoModule, fetchFromGitHub }:
buildGoModule rec {
pname = "ginkgo";
version = "1.16.5";
src = fetchFromGitHub {
owner = "onsi";
repo = "ginkgo";
rev = "v${version}";
sha256 = "sha256-v2JcH2jqB7ffF0mS6aOHM3bODf9eyGwmigp4kfCxBsI=";
};
vendorSha256 = "sha256-tS8YCGVOsfQp02vY6brmE3pxi70GG9DYcp1JDkcVG9Y=";
doCheck = false;
meta = with lib; {
description = "BDD Testing Framework for Go";
homepage = "https://github.com/onsi/ginkgo";
license = licenses.mit;
maintainers = with maintainers; [ saschagrunert ];
};
}
Now when executing your task, Nix takes care of building the package declared in the .nix file.
$ bob build run-version --no-cache
Building .nix files...
/nix/store/a2m8ccfn39zzpyq8i4irxzw091iyybr4-ginkgo-1.16.5
run-ginkgo-version running task...
run-ginkgo-version Ginkgo Version 1.16.5
Build all dependencies at once
If you want to build all project dependencies at once you can run bob install
:
$ bob install
Installing following dependencies:
ginkgo_1.16.5.nix
vim
ruby
Building nix dependencies...
/nix/store/v12zsh3zy8xggh7pwl3nxcvdqdkjw0ah-vim-8.2.4350
/nix/store/sbnzvyv06x1j2n1aa4vizw0pm3lxsvl3-ruby-2.7.5
/nix/store/30j23057fqnnc1p4jqmq73p0gxgn0frq-bash-5.1-p16
/nix/store/mi38zzxcylfc1jwnbbjyln959k1yjl9b-coreutils-9.0
/nix/store/4w3fd4s7l967bdplcqn74bf3iq45h4f8-gnused-4.8
/nix/store/g2ax8hr2vcv74ymdi9i0z898zgwv5qck-findutils-4.9.0
Building .nix files...
/nix/store/a2m8ccfn39zzpyq8i4irxzw091iyybr4-ginkgo-1.16.5
All dependencies installed!
This can be handy if you want to see that you set all dependencies correctly and save some time on your next builds.
Pinning exact version of Nixpkgs
By default, bob will build your dependencies using your local version of Nixpkgs. If you want to pin the exact version of Nixpkgs you can add in bob.yaml the exact Git commit hash of the version you want to use:
nixpkgs: https://github.com/NixOS/nixpkgs/archive/3590f02e7d5760e52072c1a729ee2250b5560746.tar.gz
Picking the commit can be done via status.nixos.org, which lists all the releases and the latest commit that has passed all tests.