summaryrefslogtreecommitdiff
path: root/posts/2014-11-08-reproducible-development-environments.md
blob: 1672c78ac77a7bf222704d607051cb4d6213a122 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
title: Reproducible Development Environments with GNU Guix
date: 2014-11-08 22:00
tags: gnu, guix, scheme, guile, wsu
summary: Easily acquire the dependencies needed to hack on a project
---

If you’re a software developer, then you probably know very well that
setting up a project’s development environment for the first time can
be a real pain.  Installing all of the necessary dependencies using
your system’s package manager can be very tedious.  To "solve" this
problem, we have resorted to inventing new package managers and
dependency bundlers for pretty much every programming language.  Ruby
has rubygems and bundler, Python has pip and virtualenv, PHP has
composer, node.js has npm, and so on.  Wouldn’t it be nice to instead
have a single package manager that can handle it all?  Enter
[GNU Guix](https://gnu.org/s/guix), a purely functional package
manager and GNU/Linux distribution.  Using Guix, you can easily create
a development environment for any software project using the `guix
environment` tool.

`guix environment` is a new utility added in Guix 0.8, which should be
released in a few weeks.  It accepts one or more packages as input and
produces a new shell environment in which all of the dependencies for
those packages are made available.  For example, `guix environment
emacs` will get you everything you need to build GNU Emacs from a
source release tarball.  By default, your `$SHELL` is spawned, but
you may opt to use any arbitrary shell command instead.  If you’ve
used Nix before, you may notice that this sounds exactly like
`nix-shell`, and that’s because it was what inspired me to write
`guix environment`.

Now, let’s take a look at an example.  One of my hobby projects is
[Sly](https://gitorious.org/sly/sly), a game engine written in Guile
Scheme.  Here’s the relevant Guix code that will produce a complete
development environment:

```scheme

    ;;; Copyright (C) 2014 David Thompson <davet@gnu.org>
    ;;;
    ;;; Sly is free software: you can redistribute it and/or modify it
    ;;; under the terms of the GNU General Public License as published by
    ;;; the Free Software Foundation, either version 3 of the License, or
    ;;; (at your option) any later version.

    (use-modules (guix packages)
                 (guix licenses)
                 (guix build-system gnu)
                 (gnu packages)
                 (gnu packages autotools)
                 (gnu packages guile)
                 (gnu packages gl)
                 (gnu packages pkg-config)
                 (gnu packages sdl)
                 (gnu packages maths)
                 (gnu packages image))

    ;; The development environment needs a tweaked LTDL_LIBRARY_PATH
    ;; for finding libfreeimage.
    (define freeimage
      (package (inherit freeimage)
        (native-search-paths
         (list (search-path-specification
                (variable "LTDL_LIBRARY_PATH")
                (directories '("lib")))))))

    (package
      (name "sly")
      (version "0.0")
      (source #f)
      (build-system gnu-build-system)
      (inputs
       `(("pkg-config" ,pkg-config)
         ("autoconf" ,autoconf)
         ("automake" ,automake)
         ("guile" ,guile-2.0)
         ("guile-sdl" ,guile-sdl)
         ("guile-opengl" ,guile-opengl)
         ("gsl" ,gsl)
         ("freeimage" ,freeimage)
         ("mesa" ,mesa)))
      (synopsis "2D/3D game engine for GNU Guile")
      (description "Sly is a 2D/3D game engine written in Guile Scheme.
    Sly differs from most game engines in that it emphasizes functional
    reactive programming and live coding.")
      (home-page "https://gitorious.org/sly/sly")
      (license gpl3+))
```

You may have noticed that the source field has been set to false.
This is because the package is not for building and installing.  It’s
sole purpose is to provide the necessary software needed to build Sly
from a fresh git checkout.

Assuming this code is in a file called `package.scm`, you can simply
run `guix environment -l package.scm` to spawn a shell for hacking
on Sly.  By default, the environment created is an augmented version
of your pre-existing shell’s environment.  This is convenient when you
want to use your installed software in the new environment, such as
git.  However, it’s important to make sure that the environment really
does have everything needed for development without relying on any
impurities introduced by your existing environment.  Without verifying
this, new developers might be frustrated to find out that the
environment provided to them is incomplete.  To verify, pass the
`--pure` flag and build from scratch.

So, `guix environment` is a pretty nice way to acquire all the
dependencies you need to work on a project, but there is still a lot
of room for improvement.  What if you were working on a web
application that required a running PostgreSQL database, Redis server,
and XMPP server?  It would be really great if Guix could handle
setting this up for you, too, a la Vagrant.  To do so, `guix
environment` could use the existing features of `guix system` to spawn
a new virtual machine that shares the host system’s package store and
the project’s source tree, and then spawn a shell with your
development environment.  I hope to implement this in the
not-too-distant future.  Until next time, happy hacking!

Read the discussion about this post on
[Hacker News](https://news.ycombinator.com/item?id=8616918).