FreeBSD, Lisp, Emacs, PostgreSQL & co.

ncgopher, poudriere-devel and

ncgopher, poudriere-devel and

As I was idly browsing Mastodon the other day, I discovered the existence of a new Gopher client: ncgopher. It's quick, it's written in Rust, it supports TLS and it actually does more than Gopher, as it also supports Gemini and finger. It looked nice enough that I decided to make a port for FreeBSD. And this turned out to be an excellent decision, as I got to try a few new things along the way.

USES = cargo

There is a new USES available to ports Makefiles: cargo. Well, I say new, it is to me, as I haven't been actively working on ports stuff in a long time. As one would expects, this does the right thing and calls cargo build with the configuration specified in CARGO_ variables. In the case of ncgopher, I had to pass --release as an argument to the command, and define the list of dependencies. Creating this list manually would be quite an undertaking, but fortunately, there is now a dedicated make target: cargo-crates. This target extracts the dependencies from the file Cargo.lock and spits them out exactly as they should be declared in the Makefile.

The only slightly tedious step is to list the licenses used by the port and its dependencies. An additional target is available to generate the list, cargo-crates-licenses, but the output is the SPDX 1.2 format, which is different to the one used in ports Makefiles. I had to resort to something along the lines of make cargo-crates-licenses | awk '{print $2}' | sort -u, and then lookup the name of the license in the predefined list. I'm not sure there is a better way to do that; I might look at creating a translation table for that in the future, and put it in a script.


As usual, after I had prepared a first version of the port, I fired up poudriere to tell me what I did wrong. Given that this is a Rust application, I expected it to take some time. Well, indeed, on my laptop, rust takes at least 3 hours to build. I say at least, because I never got to see the end of it: I would run out of memory before that. I tried helping with generous swap files, added via swapon, but that didn't work. And of course, I had to wait 3 long hours to see it fail again. And again.

Having run out of ideas, I turned to freebsd-questions, where a good soul directed me towards using poudriere-devel. It turns out this new version is able to download binary packages to speed up build time (and, in the case of ports, test time). The default configuration has it download everything as a binary package, actually, if I undertand well, so I took the conservative path and only asked for a few packages to be fetched instead of built:

# /usr/local/etc/poudriere.conf
# Set to always attempt to fetch packages or dependencies before building.
# XXX: This is subject to change
# Default: off; requires -b <branch> for bulk or testport.
# The branch will be appended to the URL:
# Packages which should never be fetched.  This is useful for ports that
# you have local patches for as otherwise the patches would be ignored if
# a remote package is used instead.
# Alternatively a whitelist can be created to only allow specific packages to
# be fetched.
# Default: everything

Then, it's only a matter of specifying the branch when running poudriere, if you haven't opted for providing a default (implicit) value in the configuration file:

$ poudriere testport -j 131x64 -p porting -b latest www/ncgopher

And this is enough to bring us down from 3 hours to 3 minutes. Poudriere and the very pragmatic people behind it will never cease to amaze me…


There was one last novelty this weekend: I gave a try. Codeberg is maintained by a non-profit organisation based in Germany, focuses on open source projects and lives off donations. According to their FAQ, they are pretty sustainable already, having enough to stick around for the next 12 years.

The service itself consists of a gitea instance and I found it very responsive. This looks to me as a very good solution whenever I want to promote a project out of my personal repository.