--- date: 2023-03-29 title: Finally, Templating in Bashtard! tags: - Bash - Bashtard - FreeBSD - GNU+Linux --- In the past year, I've written Bashtard, a simple configuration system written in Bash to minimize the required dependencies, and to have a better system to handle different distributions/OSs in your cluster. Especially the past two months I've done quite a bit of work on it. I've worked out how to do reusable playbooks, generate a usable Debian package from the Makefile, extend the supported platforms, and more. And now, I've finally found a library to improve templating functionality, [Bash Pure Template](https://github.com/husixu1/bpt). When I originally started Bashtard I had looked around for nice and simple templating solutions that I could use. Sadly, pretty much all the available results required me to add dependencies, or couldn't really do more than what I did using `sed` and `awk`. For a long time, I had accepted that the kind of system that I wanted didn't exist, and I wasn't interested in making it myself at the time. Last night, however, I decided to just give it a quick search to see if anything had changed, and BPT popped up somewhere in my results. Having a quick look through the documentation made me very interested, it seemed to have all the features I desired, while still sticking to utilities I've already accepted for Bashtard. With one small exception, `md5sum`. This utility is not available on the FreeBSD systems I maintain. On FreeBSD, this tool is called `md5`, and has different options it can use. On the bright side, both `md5sum` and `md5` accept the content to be hashed on `STDIN`, and will write the hash to `STDOUT`. Additionally, Bashtard already contains logic to deduce what kind of system it is running on. And so I decided it's worth a try. There's only 5 references to `md5sum`, and the all happen in the same function, `bpt.fingerprint`. I've added an extra variable, `util`, and a `case...esac` to set this variable. ```bash local util case "${BASHTARD_PLATFORM[key]}" in freebsd) util=md5 ;; linux-*) util=md5sum ;; *) debug "bpt/fingerprint" "Falling back to md5sum for hashing" util=md5sum ;; esac ``` After that, just replace all the `md5sum` invocations with `"$util"`. And a quick test later, it seems to function just fine. Implementing BPT as a library was incredibly straightforward too. ```bash . "$BASHTARD_LIBDIR/vendor/bpt.bash" file_template_bpt() { local file file="$1" ; shift eval "$* bpt.main ge \"$file\"" } ``` The `eval` is a bit icky, but it saves me from polluting the environment variables through various `export`s. Another small adjustment I've made to BPT is the shebang. Upstream uses `#!/bin/bash`, but this is incorrect on some systems, including FreeBSD. It uses `#!/usr/bin/env bash` in the Bashtard version. Additionally, the upstream repository uses `.sh` as the file extension, which I've updated to be `.bash` to more accurately reflect which shell it is used with. Upstream also uses a 4-space indent, which I've left as-is for now, since indentation is more of a personal choice, even if that choice is wrong. Finally, I added 3 `shellcheck disable` rules to make shellcheck happy. After some playbook testing on my own systems, I can say that BPT works pretty well so far, and I'm very glad the author made it available as free software. Thanks!