Many modern languages (and some old ones) today have their own package manager ecosystem, where someone working on that language can easily get pieces of code written by other people that do their task for them.

A few examples include:

All this readily available code is great, it avoids having to re-implement a lot of stuff on your own projects and makes it a breeze. In fact the tool that is going to be shown today, tmplgen, is written in Rust and thus makes heavy use of the crates ecosystem.

On the counter side, distributions must package it, if their users require it. And with such a nice package manager, it is easy to get lost in massive trees of dependencies, where one language module has a dependency on another and another and another and so on.



To help solve that problem, Void Linux contributor and Exherbo core developer Cogitri wrote a tool for automatically querying those language specific managers via Web APIs and then writing xbps-src templates for those packages automatically.

Today we are going to package a small collection of packages from RubyGems as a tutorial.


First we need to install the tool, simple enough, it is available in the repositories.

\# xbps-install -y tmplgen
Name    Action    Version           New version            Download size
tmplgen install   -                 1.2.0_1                -

Size required on disk:        5715KB
Space available on disk:       184GB

[*] Downloading binary packages

[*] Verifying package integrity
tmplgen-1.2.0_1: verifying RSA signature...

[*] Running transaction tasks
tmplgen-1.2.0_1: unpacking ...

[*] Configuring unpacked packages
tmplgen-1.2.0_1: configuring ...
tmplgen-1.2.0_1: installed successfully.

0 downloaded, 1 installed, 0 updated, 1 configured, 0 removed.


tmplgen requires some configuration before it can be run, it needs the XBPS_DISTDIR variable to be set.

$ export XBPS_DISTDIR=/path/to/void-packages

Picking something to package

Let's pick something to package from RubyGems, one package that has C extensions and one that doesn't. I decided on rb-readline


Let's run tmplgen and try to package something with it.

$ tmplgen -t gem rb-readline
[WARN  libtmplgen::helpers] ruby-rb-readline of package description is longer than 80 characters, please cut as you see fit!
[WARN  libtmplgen::tmplwriter] Gem ruby is part of ruby, won't write a template for it!
[WARN  libtmplgen::tmplwriter] Won't write template for built-in package ruby

Ok, let's see if anything was done at all.

$ git status --porcelain
?? srcpkgs/ruby-rb-readline/

There it is!, note that it prefixes the package name with ruby-.

# Template file for 'ruby-rb-readline'
short_desc="The readline library provides a pure Ruby implementation of the GNU readline C library, as well as the Readline extension that ships as part of the standard library"
maintainer="maxice8 <>"

post_install() {
    vlicense LICENSE

Looks neat, it automatically set up most information for it. A few things to note is that it can't handle a few cases which we must do it ourselves:

  • It doesn't automatically cut the short_desc.
  • It doesn't convert a license to the SPDX short-identifier if its ambiguous.
  • It guesses the file is called license file is called LICENSE.
  • It can't know if the package has C extension and thus needs the gemspec build style.
  • It can only guess the wrksrc

Let's do those fixups, where applicable.

# Template file for 'ruby-rb-readline'
short_desc="Pure Ruby implementation of GNU readline library"
maintainer="maxice8 <>"

post_install() {
    vlicense LICENSE

Looks nice, let's build it!

$ xbps-src pkg ruby-rb-readline
$ xls ruby-rb-readline

And let's run an example just to be sure.

\# xbps-install --repository=hostdir/binpkgs -y ruby-rb-readline
$ ruby /tmp/example_readline.rb
> ls
You typed: ls
> vi
You typed: vi
> quit
You typed: quit



tmplgen is an amazing tool, this tutorial doesn't show it's full capabilities like walking down the whole dependency tree of a package and also automatically updating to a new version. And is meant more to show basic usage, if there is enough demand a followup can be written.