Next: Bonus: Package Variants, Previous: Level 1: Building with Guix, Up: Programutveckling [Contents][Index]
We now have a Git repository containing (among other things) a package definition (see Level 1: Building with Guix). Can’t we turn it into a channel (see Channels in GNU Guix Reference Manual)? After all, channels are designed to ship package definitions to users, and that’s exactly what we’re doing with our guix.scm.
Turns out we can indeed turn it into a channel, but with one caveat: we must
create a separate directory for the .scm
file(s) of our channel so
that guix pull
doesn’t load unrelated .scm
files when
someone pulls the channel—and in Guile, there are lots of them! So we’ll
start like this, keeping a top-level guix.scm symlink for the sake of
guix shell
:
mkdir -p .guix/modules mv guix.scm .guix/modules/guile-package.scm ln -s .guix/modules/guile-package.scm guix.scm
To make it usable as part of a channel, we need to turn our guix.scm
file into a package module (see Package Modules in GNU Guix
Reference Manual): we do that by changing the use-modules
form at
the top to a define-module
form. We also need to actually
export a package variable, with define-public
, while still
returning the package value at the end of the file so we can still use
guix shell
and guix build -f guix.scm
. The end result
looks like this (not repeating things that haven’t changed):
(define-module (guile-package) #:use-module (guix) #:use-module (guix git-download) ;for ‘git-predicate’ …) (define vcs-file? ;; Return true if the given file is under version control. (or (git-predicate (dirname (dirname (current-source-directory)))) (const #t))) ;not in a Git checkout (define-public guile (package (name "guile") (version "3.0.99-git") ;funky version number (source (local-file "../.." "guile-checkout" #:recursive? #t #:select? vcs-file?)) …)) ;; Return the package object define above at the end of the module. guile
We need one last thing: a
.guix-channel
file so Guix knows where to look for package modules in our repository:
;; This file lets us present this repo as a Guix channel. (channel (version 0) (directory ".guix/modules")) ;look for package modules under .guix/modules/
To recap, we now have these files:
. ├── .guix-channel ├── guix.scm → .guix/modules/guile-package.scm └── .guix └── modules └── guile-package.scm
And that’s it: we have a channel! (We could do better and support
channel
authentication so users know they’re pulling genuine code. We’ll spare you
the details here but it’s worth considering!) Users can pull from this
channel by
adding
it to ~/.config/guix/channels.scm
, along these lines:
(append (list (channel
(name 'guile)
(url "https://git.savannah.gnu.org/git/guile.git")
(branch "main")))
%default-channels)
After running guix pull
, we can see the new package:
$ guix describe Generation 264 May 26 2023 16:00:35 (current) guile 36fd2b4 repository URL: https://git.savannah.gnu.org/git/guile.git branch: main commit: 36fd2b4920ae926c79b936c29e739e71a6dff2bc guix c5bc698 repository URL: https://git.savannah.gnu.org/git/guix.git commit: c5bc698e8922d78ed85989985cc2ceb034de2f23 $ guix package -A ^guile$ guile 3.0.99-git out,debug guile-package.scm:51:4 guile 3.0.9 out,debug gnu/packages/guile.scm:317:2 guile 2.2.7 out,debug gnu/packages/guile.scm:258:2 guile 2.2.4 out,debug gnu/packages/guile.scm:304:2 guile 2.0.14 out,debug gnu/packages/guile.scm:148:2 guile 1.8.8 out gnu/packages/guile.scm:77:2 $ guix build guile@3.0.99-git […] /gnu/store/axnzbl89yz7ld78bmx72vpqp802dwsar-guile-3.0.99-git-debug /gnu/store/r34gsij7f0glg2fbakcmmk0zn4v62s5w-guile-3.0.99-git
That’s how, as a developer, you get your software delivered directly into the hands of users! No intermediaries, yet no loss of transparency and provenance tracking.
With that in place, it also becomes trivial for anyone to create Docker
images, Deb/RPM packages, or a plain tarball with guix pack
(see Invoking guix pack in GNU Guix Reference Manual):
# How about a Docker image of our Guile snapshot? guix pack -f docker -S /bin=bin guile@3.0.99-git # And a relocatable RPM? guix pack -f rpm -R -S /bin=bin guile@3.0.99-git
Next: Bonus: Package Variants, Previous: Level 1: Building with Guix, Up: Programutveckling [Contents][Index]