This post is the first public announcement of my new package manager and deployment tool for linux - hermes.
Hermes provides features like:
- Atomic deployments.
- Atomic rollback.
- Remote builds.
- Sandboxed and reproducible builds.
- Avoidance of version conflicts.
- Avoidance of centralized infrastructure.
- Build everything from source.
- Shared caching to avoid excessive rebuilds.
Those familiar with Nix or Guix will feel right at home, or you could think of hermes a bit like docker, where instead of building images in layers, you are building software packages from source into directories that can reference each other.
The following are some simple and non comprehensive examples, designed to show what using hermes looks like…
Install a package directly from a git repository
$ git clone https://github.com/andrewchambers/hpkgs $ hermes build ./hpkgs/community/python3.hpkg $ ./result/bin/python3
Install software directly from github
$ hermes build https://raw.githubusercontent.com/andrewchambers/hpkgs/f4393d/community/bash.hpkg $ ./result/bin/bash
$ hermes build --build-host ssh://acha.ninja ...
$ hermes build ./dev-env.hpkg -o dev-env $ ./dev-env/run make $ ./dev-env/run bash
Remote atomic deployment
$ hermes build ./app.hpkg -o app $ hermes cp ./app ssh://$SERVER/deployments/app
$ hermes gc
Hermes is an attempt at creating a simple but powerful package management tool where you maintain total control of your software dependencies.
You could also consider Hermes my attempt at simplifying some of the ideas and implementation behind Nix and Guix. These simplifications range from less code, fewer commands, no C++, no monads, no lazy functional programming, no glibc. Don’t worry if those don’t mean much to you, the point is you shouldn’t really need to know about them.
The following are some of my initial design goals:
Have a decentralized package ecosystem
Hermes is trying to keep things decentralized where it can.
- Installation of packages directly from https urls (including github git commits).
- Forking package trees using version control like Git.
- Install software on any linux distro.
Have a simplified package model
I’ve tried to simplify the model of packaging that Nixos and Guix have pioneered.
Hermes packages definitions are just functions, that when called, build software
by running commands like
make. If the package
is already installed, hermes doesn’t bother building it again.
The main difference from ’traditional’ package managers, is each package has a unique install directory, so there doesn’t need to be any package conflict handling.
Be lean and small
Hermes itself is lean, it fits on a floppy disk when statically linked and compressed, and can be made even smaller when omitting certain features.
Hermes only has a few core commands,
hermes cp, and
hermes gc, which so far are enough to build packages,
do remote deployments and remove unwanted packages.
Being this lean opens some future possibilities for places other tools cannot reach.
Have no background server/daemon
I am not a fan of the docker daemon, or the nix and guix build daemons. Hermes does not use one, instead working via other mechanisms such as lock files and strategic setuid.
Packages are written in the Janet programming language with a small set of extra functions that make sense in the context of building software.
When you create a hermes package you write a small function for installing the package into the path pointed to by the dynamically scoped variable :pkg-out. All dependencies are automatically detected and built simply by referencing them.
Here is a package for the ’ed’ text editor:
(use ../prelude) (import ../core) (defsrc ed-src :url "http://ftpmirror.gnu.org/ed/ed-1.16.tar.lz" :hash "sha256:cfc07a14ab048a758473ce222e784fbf031485bcd54a76f74acfee1f390d8b2c") (defpkg ed :builder (fn  (core/link-/bin/sh) (os/setenv "PATH" (join-pkg-paths ":" "/bin" [core/coreutils core/sed core/grep core/awk core/gcc core/make])) (os/setenv "CFLAGS" *default-cflags*) (os/setenv "LDFLAGS" *default-ldflags*) (unpack-src ed-src) (sh/$ ./configure --prefix= ^ (dyn :pkg-out)) (sh/$ make -j (dyn :parallelism)) (sh/$ make install)))
You should note that Janet itself is a small but powerful general purpose programming language, so the skills you learn using hermes are useful for writing all sorts of great software.
Want to learn more?
Head over to the project github hermes and check out our quickstart and man pages.