How to add a package to Guix

make easy things easy

I have explained more than once how to add a package to Guix, although the Guix Cookbook provides a detailed great tutorial. Here, let make a step by step pedestrian explanations for the working scientist. The most common case is the addition of a package from a repository as PyPI or CRAN or Bioconductor or name-it.

Let consider the R package PNWColors. Because it is registered on the CRAN repository, get the Guix recipe is as easy as the command-line1:

$ guix import cran -r PWNColors

which returns the Guix recipe,

(define-public r-pnwcolors
  (package
    (name "r-pnwcolors")
    (version "0.1.0")
    (source
      (origin
        (method url-fetch)
        (uri (cran-uri "PNWColors" version))
        (sha256
          (base32
            "1phplnclkficfv8s6wsyrckk4ixzbayiy5iix6dddg40485l9nyj"))))
    (properties `((upstream-name . "PNWColors")))
    (build-system r-build-system)
    (home-page
      "https://github.com/jakelawlor/PNWColors")
    (synopsis
      "Color Palettes Inspired by Nature in the US Pacific Northwest")
    (description
      "PNW-Inspired Palettes for 'R' data visualizations.  Palettes are variable in length and checked for colorblind accessibility from hue, saturation, and lightness value scaling using the 'Chroma.js  Color Palette Helper' <https://gka.github.io/palettes/>.")
    (license #f)))

So far, so good. What do we do with that? Three options:

  1. local addition via the --load-path option
  2. addition via channels
  3. submit upstream

Package via --load-path

It is my recommendation for getting fast local packages. First, let consider you have a folder, for instance, ~/src/my-extra. In this folder, you can add a file, for instance cran.scm containing the recipe above. Then, you should get:

$ guix build -L ~/src/my-extra r-pnwcolors
error: package: unbound variable
hint: Did you forget `(use-modules (guix packages))'?

guix build: error: r-pnwcolors: unknown package

Indeed, we have forgotten this use-modules at the top-level. Now the file reads,

(use-modules (guix packages))

(define-public r-pnwcolors
  (package
    (name "r-pnwcolors")
    (version "0.1.0")
    (source
      (origin
        (method url-fetch)
        (uri (cran-uri "PNWColors" version))
        (sha256
          (base32
            "1phplnclkficfv8s6wsyrckk4ixzbayiy5iix6dddg40485l9nyj"))))
    (properties `((upstream-name . "PNWColors")))
    (build-system r-build-system)
    (home-page
      "https://github.com/jakelawlor/PNWColors")
    (synopsis
      "Color Palettes Inspired by Nature in the US Pacific Northwest")
    (description
      "PNW-Inspired Palettes for 'R' data visualizations.  Palettes are variable in length and checked for colorblind accessibility from hue, saturation, and lightness value scaling using the 'Chroma.js  Color Palette Helper' <https://gka.github.io/palettes/>.")
    (license #f)))

and guix build reports the error:

error: url-fetch: unbound variable
hint: Did you forget `(use-modules (guix download))'?

Again, let add the missing modules and repeat. The message now reports a cryptic hint. Well, it is a R package, thus somehow, it requires a build system. Hence, let try to add (guix build-system r). Ouch, another error:

$ guix build -L ~src//my-extra r-pnwcolors
guix build: warning: failed to load '(cran)':
no code for module (cran)
hint: File `/hme/simon/src/my-extra/cran.scm' should probably start with:

     (define-module (cran))

guix build: error: r-pnwcolors: unknown package

Ok… what does it mean? The recipe needs to be defined inside a module. In short, the module name (define-module (NAME) corresponds to the base-name of file cran.scm.

(define-module (cran)
  #:use-module (guix packages)
  #:use-module (guix download)
  #:use-module (guix build-system r))

(define-public r-pnwcolors
  (package
    (name "r-pnwcolors")
    (version "0.1.0")
    (source
      (origin
        (method url-fetch)
        (uri (cran-uri "PNWColors" version))
        (sha256
          (base32
            "1phplnclkficfv8s6wsyrckk4ixzbayiy5iix6dddg40485l9nyj"))))
    (properties `((upstream-name . "PNWColors")))
    (build-system r-build-system)
    (home-page
      "https://github.com/jakelawlor/PNWColors")
    (synopsis
      "Color Palettes Inspired by Nature in the US Pacific Northwest")
    (description
      "PNW-Inspired Palettes for 'R' data visualizations.  Palettes are variable in length and checked for colorblind accessibility from hue, saturation, and lightness value scaling using the 'Chroma.js  Color Palette Helper' <https://gka.github.io/palettes/>.")
    (license #f)))

It works! Note that the dance to add #:use-module may be longer. For R packages, it usually requires (gnu packages cran) and (gnu packages bioconductor).

Congrats! You made your first Guix package.

Obviously, you can add many packages to this file cran.scm. Or you can also create another file, for instance bioconductor.scm if the package are from the repository Bioconductor. Do whatever fits your habits!

Make a channel

The documentation should be enough to complete this item. I do not recommend this road when developing new packages.

The point is to turn the previous ~/src/my-extra folder as a Git repository (git init and git add). Then let write the file ~/.config/guix/channels.scm as,

(cons*
  (channel
  (name 'my-extra)
  (url "file:///home/simon/src/my-extra")
  (branch "master"))
 %default-channels)

and run guix pull. This is polluting the generations and to avoid such, instead, I recommend to save the snippet above in any other file, for instance, ~/src/my-channels.scm and then use guix time-machine. However, because of %default-channels, it will fetch updates and thus what is done today could break tomorrow. Therefore, it seems better to run today guix describe -f channels and store the results to ~/src/my-channels.scm. It pins the state (version) of Guix. It reads,

(list
 (channel
  (name 'mine)
  (url "file:///home/simon/src/my-extra")
  (branch "master"))
 (channel
  (name 'guix)
  (url "https://git.savannah.gnu.org/git/guix.git")
  (commit
   "fb32a38db1d3a6d9bc970e14df5be95e59a8ab02")
  (introduction
   (make-channel-introduction
    "9edb3f66fd807b096b48283debdcddccfea34bad"
    (openpgp-fingerprint
     "BBB0 2DDF 2CEA F6A8 0D1D  E643 A2A0 6DF2 A33A 54FA")))))

then the command-line is,

$ guix time-machine -C ~/src/my-channels.scm \
       -- build -L ~/src/my-extra r-pnwcolors

Awesome! Ready to push this channel elsewhere and turn file:/// into htpps://. Or submit to Guix proper so others could also enjoy the recipe.

Submit to Guix

If you are still reading, here we go! We need:

  1. a development environment for Guix,
  2. to make the addition locally,
  3. to make a patch and submit it.

Let extract the essence from the contributing section.

Development environment

It is as easy as two steps:

  • git clone https://git.savannah.gnu.org/git/guix.git
  • Go to the repository and build Guix:
    • cd guix
    • guix environment guix
    • ./bootstrap
    • ./configure --localstatedir=/var/
    • make

So far, so good! Now, let check that we are effectively running the Guix from the checkout:

$ ./pre-inst-env guix describe
Git checkout:
  repository: /home/simon/src/guix
  branch: master
  commit: 35aaf1fe10488ae9ed732fb2c383d09a70c109c0

Add the recipe

It depends on the kind of package you are trying to add; give a look at the files under gnu/packages. For packages from CRAN, the file is gnu/packages/cran.scm, from Bioconductor gnu/packages/bioconductor.scm, etc.

Let open the considered location and let add the recipe. Some files have convention as alphabetically sorted (recommended). Once added, let run make; if it returns an error then something is wrong and it is hard to guess what beforehand: raise your issue to help-guix@gnu.org. Last, ./pre-inst-env guix build r-pnwcolors should build fine.

The easy part is done. Let jump to the hard one.

Submit upstream

First thing first, configure ~/.gitconfig. Here, it is important: 1) the convention is to use your real name2, please do; and 2) please use a regular and valid email. Do not forget to setup Git for sending email, something along these lines:

[sendemail]
        smtpEncryption = tls
        smtpServer = smtp.gmail.com
        smtpUser = zimon.toutoune@gmail.com
        smtpServerPort = 587

We are ready, let's go! The process is not straightforward: 4 steps have to pass. First, and the most important, check that the package is compliant with the Guix standards. Please read with care all this section and that too!

$ ./pre-inst-env guix lint r-pnwcolors
gnu/packages/cran.scm:926:6: r-pnwcolors@0.1.0: use @code or similar ornament instead of quotes
gnu/packages/cran.scm:909:2: r-pnwcolors@0.1.0: invalid license field
warning: SQLite database is busy
gnu/packages/cran.scm:926:0: r-pnwcolors@0.1.0: line 926 is way too long (262 characters)
fetching CVE database for 2021...
gnu/packages/cran.scm:913:6: r-pnwcolors@0.1.0: source not archived on Software Heritage and missing from the Disarchive database

It means that the fields synopsis, description and license must be improved. Take inspiration by reading the other packages. For license, check the upstream directory. Here, the information is here.

Do not forget to complete the copyright header if the change if more than 10 lines.

Ok, once happy, second let commit the change,

$ git add gnu/packages/cran.scm
$ git commit

and the commit message should be something along these lines,

gnu: Add r-pnwcolors.

* gnu/packages/cran.scm (r-pnwcolors): New variable.

Please read previous commit messages with git log to catch the convention.

Almost done. Third, let create the patch with the command-line,

$ git format-patch --base=origin/master -1
0001-gnu-Add-r-pnwcolors.patch

where -1 means only one patch (replace by any number corresponding to the number of commits you did). And the file 0001-gnu-Add-r-pnwcolors.patch is the patch, it reads,

From 7dfb8c478e89619df13a22f238be7dc773784f56 Mon Sep 17 00:00:00 2001
From: zimoun <zimon.toutoune@gmail.com>
Date: Tue, 12 Oct 2021 22:24:15 +0200
Subject: [PATCH] gnu: Add r-pnwcolors.

* gnu/packages/cran.scm (r-pnwcolors): New variable.
---
 gnu/packages/cran.scm | 24 +++++++++++++++++++++++-
 1 file changed, 23 insertions(+), 1 deletion(-)

diff --git a/gnu/packages/cran.scm b/gnu/packages/cran.scm
index 937f53784e..15f8df7cee 100644
--- a/gnu/packages/cran.scm
+++ b/gnu/packages/cran.scm
@@ -31,7 +31,7 @@
 ;;; Copyright © 2020 Antoine Côté <antoine.cote@posteo.net>
 ;;; Copyright © 2020 Arun Isaac <arunisaac@systemreboot.net>
 ;;; Copyright © 2020 Magali Lemes <magalilemes00@gmail.com>
-;;; Copyright © 2020 Simon Tournier <zimon.toutoune@gmail.com>
+;;; Copyright © 2020, 2021 Simon Tournier <zimon.toutoune@gmail.com>
 ;;; Copyright © 2020 Aniket Patil <aniket112.patil@gmail.com>
 ;;; Copyright © 2021 Marcel Schilling <marcel.schilling@uni-luebeck.de>
 ;;;
@@ -905,6 +905,28 @@ functions which can speed up workflow.")
 control over dimensions and appearance.")
     (license license:gpl2+)))

+(define-public r-pnwcolors
+  (package
+    (name "r-pnwcolors")
+    (version "0.1.0")
+    (source
+     (origin
+       (method url-fetch)
+       (uri (cran-uri "PNWColors" version))
+       (sha256
+        (base32
+         "1phplnclkficfv8s6wsyrckk4ixzbayiy5iix6dddg40485l9nyj"))))
+    (properties `((upstream-name . "PNWColors")))
+    (build-system r-build-system)
+    (home-page
+     "https://github.com/jakelawlor/PNWColors")
+    (synopsis "Colors palettes for data visualizations")
+    (description
+     "This package provides color palettes.  They are checked for colorblind
+accessibility from hue, saturation, and lightness value scaling using the
+Chroma.js Color Palette Helper.  See <https://gka.github.io/palettes>.")
+    (license license:cc0)))
+
 (define-public r-ecp
   (package
     (name "r-ecp")

base-commit: 35aaf1fe10488ae9ed732fb2c383d09a70c109c0
--
2.32.0

The last step, fourth, send it:

$ git send-email --to=guix-patches@gnu.org 0001-gnu-Add-r-pnwcolors.patch

After waiting a couple of minutes, you should receive an email from help-debbugs@gnu.org which assigns a patch number. Here, it is 51169. The submission can be read in the tracker: http://issues.guix.gnu.org/51169.

A final remark, we sent only one patch. For several ones, the workflow is the same: commit each addition separately then create patches with a cover letter (option --cover-letter to the command-line git format-patch); edit this cover letter to summary the aim of the series. Send this cover-letter (usually 0000-cover-letter.patch), wait to get a number, then send all the patch series to that number, for instance git send-email --to=51169@debbugs.gnu.org 0001-gnu-Add-r-pnwcolors.patch and so on with 0002-gnu-stuff-blabla.patch.

Join the fun, join Guix!

Footnotes:

1

the symbol $ means as regular user; type what is written after. :-)

2

Do as I say, not as I do!


© 2014-2022 Simon Tournier <simon (at) tournier.info>

(last update: 2022-04-19 Tue 21:46)