December hacks


Some great stuff happening in and around Regal at the moment. First, v0.14.0 was released earlier this week, and it's quite a solid one. Two new linter rules, a new output format, and a bunch of fixes and improvements in existing rules. The new output format is SARIF, which is a standardized format tools like linters can use to report their findings. The format seems well-supported by a number of tools, but I've yet only tried it out using the SARIF VS Code extension.


Next, we're running a holiday campaign around Regal, where we'll be giving away a few custom linter rules as gifts to the community every now and then during December. And not just rules, but some fun and hidden features in Regal too. It's not every day you get a chance to work on silly or fun stuff like this, and I find I really enjoy it. There's a few seriously cool rules we've been working on for this too though, and my colleague Charlie delivered one of the cooler rules I've seen in any linter. More on that in a follow-up post!

Minimum Compatible OPA Version (mcov)

A few weeks ago, Torin Sandall made some changes in OPA to allow the compiler to keep track of what capabilities (i.e. features such as built-in functions) that's been used as part of policy compilation. This information may then be used to determine what the minimum compatible version of OPA is required to evaluate the policy. Having access to that through the Go API is obviously enough if the purpose is to integrate that feature in tools working with OPA and Rego. However...

I tend to do a lot of changes in policy as a result of linting with Regal, and one thing I'd like to check is how these changes affect the minimum compatible version of OPA required. I could probably integrate something for that in Regal, but given that there are other relevant use cases for this, I figured a standalone tool would be a better option. This tool is mcov, and along with the "OPA versions cheatsheet" that I wrote to keep track of what changes happened in any given OPA release, it's a rather nice little utility.

tools regal code mcov open source



While the bronchitis is still keeping me from working for any longer periods of time — and two kids claiming much of the little time I've got to spare — I've found at least a few free moments for getting started on this blog. A few attempts to run a blog have been made in the past, but most often I've gotten stuck in the technical details of the blog platform itself. While I do like to tinker, it's an easy trap to fall into, spending way too much time getting things just the way you want them, and then grow tired of it all before you even get to the actual writing. Perfect is the enemy of good, and all that.

To avoid that this time around, I went with Quickblog, which is a static site generator written in Clojure. The project is maintained by Michiel Borkent, a.k.a. @borkdude who is one of the most prolific contributors to the Clojure ecosystem, and who I've had some great interactions with during my intermittent Clojure stints. Michiel is also the creator of clj-kondo, which was an inspiration for me when building Regal.

Quickblog strikes a good balance between simplicity and flexibility, much thanks to its Clojure foundation. I also love the fact that there's only a dozen or so blogs using it yet, most (?) of which are listed in the README for the project. Judging by the commit history of quickblog, many of those authors have also contributed something to the project. Grassroots community vibes!

To tinker or not to tinker

The out-of-the-box experience is decent, and while I'll want to tweak the theme more than I've done so far, it doesn't feel too urgent. There was really only one thing I wanted to fix right away — the .html extension used for links throughout the site. It's a vanity thing for sure, but I've always prefered my URLs free from those, so let's try and fix that!

Most web servers will automatically serve e.g. /foo.html when /foo is requested, and GitHub Pages is no exception. The http-server embedded in quickblog and used for local testing however did not, so first order of operations was a small contribution to allow that.

With that out of the way, the next step was to make the .html extension optional in quickblog's renderer. Adding a configurable :page-suffix option took a little more work, but was a great introduction to the codebase. Both of my PRs got merged within an hour, which is just phenomenal! Hopefully I've now got enough to keep me from tinkering for a while, but we'll see...

If you're curious about what the code for my blog looks like — and intentionally there isn't much of it! — it's available on GitHub.

Publishing to GitHub Pages

The final step was remarkably easy. Following the steps outlined in the GitHub docs for Publishing with a custom GitHub Actions workflow, I was able to render and publish the blog in just a few minutes. The workflow snippet below should be fairly self-explanatory, but to summarize:

  1. Checkout the repo
  2. Get Babashka
  3. Render the blog
  4. Upload the public/ directory as a build artifact
  5. Deploy the artifact to GitHub Pages

GitHub recommended running the deployment as a separate job, so that's what I went with.

    runs-on: ubuntu-latest
      - uses: actions/checkout@v4
      - uses: delaguardo/setup-clojure@12.1
          bb: latest
      - run: bb quickblog render
      - uses: actions/upload-pages-artifact@v2
          path: public/
    needs: build
      pages: write
      id-token: write
      name: github-pages
      url: ${{ steps.deployment.outputs.page_url }}
    runs-on: ubuntu-latest
      - uses: actions/deploy-pages@v2
        id: deployment

Could be that caching could speed up the process in case I ever have hundreds of posts at some point, but let's worry about that later. One thing I'm noticing now though is the missing syntax highlighting for the YAML block above. Unsurprisingly, that works for Clojure, but I've not tried other languages. Will definitely want support for Rego too later. Oh well, just to tinker a little more...

Update 2023-11-27: Syntax highlighting fixed. Turned out to be rather simple to simply pick whatever languages one would want. Also now included in local distribution rather than fetched from CDN.

quickblog clojure meta



Another slow week spent mostly in bed, and with little to no energy for anything but the simplest of tasks. Saturday marks the 2nd week of coughing. And not just any random cough either. At first it was a dry cough, and one of those that eventually turn painful. Then, and thankfully only for a short time, came the fever. The cough eventually got a bit better, or at least not as dry. If that was due to the drug I got prescribed or not, who knows.


The first couple of days felt very much like covid, but as Ina and the kids remained unaffected that couldn’t be, or at least it didn’t feel likely to be. After a few days of coughing my breathing got heavier, and I got tired from pretty much any activity. By now I could even hear my lungs squeak like a broken accordion, or an old wooden rocking chair. I should probably have seen a doctor earlier, but now almost two weeks in, I did. Most likely bronchitis, she said, and if so there’s nothing much to do but wait, as there’s no real treatment for that other than to suffer for what’s commonly 3 weeks.

She took some tests, and my oxygen uptake level was lower than normal. An hour later and I’m at some other clinic for getting x-rays of my lungs. The result was sent back to the first doctor, but she had left to see a doctor herself, or rather a veterinarian, for her dog. Priorities. We’ll see tomorrow what the results say.

annoyances health life