Skip to main content
Version: 0.4.0

Package Management

Bob takes advantage of Nix as package manager to declare dependencies. Nix supports all common programming languages and codgenerators like: golang, nodejs, python, java, protoc, openapi-generator. Check search.nixos.org/packages for a complete list. It is available for Linux and MacOS.

The dependecies 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 and set use-nix: to true in your bob.yaml. This allows Bob to override the PATH variable with dependecies 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.

use-nix: true

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.

When downloading fails, Nix tries to build dependecies by leveraging the nix-build binary. Dependencies can be declared for all tasks in a bob.yaml or for each task individually. Task level dependencies have priority.

How to Declare Dependecies

Dependencies are decalred by the name of the package (in nix they are called derivation) from Nixpkgs. You can also provide a paths to a .nix file containing a Nix expression (the instructions on how to build a package).

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:

use-nix: true
build:
run-go-version:
cmd: go version
dependencies:
- go_1_18
run-go-lower-version:
cmd: go version
dependencies:
- go_1_16

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:

img alt

Using your custom .nix file

Nixpkgs repository has over 60 000 packages, but sometimes you might not find what you need. In this case, you can write your own Nix expression file and add it in your dependencies:

use-nix: true
build:
run-version:
cmd: ginko 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-ginkgo-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:

use-nix: true
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.