Pragmatism in the real world

A short primer on SPF, DKIM and DMARC

I use FastMail for my email and as I control my own domain, I needed to set up SFP, DKIM and DMARC on it. These are DNS records that help the email servers put the emails that I send into my recipient's inbox and to mark any forged emails as spam. These are my tidied up notes so that I can find them again when I next need them. SPF SPF is a DNS record… continue reading.

Indenting output in a shell script with pr

When printing output in a shell script, it's quite useful to be able to indent information to group it. The easiest way to do this is with pr, like this: body=$(curl -s "http://localhost:8888/") echo "Response:" echo "$body" | pr -to 4 This generates: Response: { "links": { "games": "/games" } } Given that pr appeared in version 1 of AT&T Unix, I'm late to the party with this one, but it's a useful thing to… continue reading.

Using Monolog's TestHandler

When I write integration tests with PHPUnit, I find it helpful use Monolog's TestHandler to check that the logs I expect are generated. It's reasonably common that classes that write to a log take a PSR\Log\LoggerInterface in their constructor and then use that for logging. This usually logs to the error handler for pushing to Sentry or whatnot. This makes testing easy! For testing we can use the TestHandler which stores the logs it receives… continue reading.

Getting status code and body from curl in a bash script

When writing a shell script recently, I realised that it would be really handy to get the the status code from a curl command in addition to the body. Usually, I call curl like this: body=$(curl -s "http://localhost:8888/") echo "Curl exit code: $?" echo "Body: $body" This works well, but no status code is available as curl's exit code is related to its own error system, not the HTTP call. Searching Stack Overflow, I came… continue reading.

Release process checklist

I recently released a new version of rst2pdf. We don't do this frequently and it would be very easy to get it wrong. As a result, we have a RELEASE_PROCESS.rst document in our repo that provides a step-by-step list of what to do. I can't emphasise enough how useful such a document is and every project should have one and I've used them with client projects too. In general the following items need to be… continue reading.

Renaming PDF files based on their content

My accountant recently moved my business accounts system over to FreeAgent. One thing I like to do is keep a copy of every invoice PDF that I issue in a folder on my computer as a back up, just in case the online systems let me down. As I was learning new systems, I took advantage of this time to write a script to rename the invoice PDFs from Nineteen-Feet-Limited_Invoice_123.pdf to my preferred format of… continue reading.

Small scripts for repetitive tasks

One thing that I like to do is write a script for seemingly trivial things that I do more than once. I do this as it turns out that I end up needing them again. One example is a pair of script I use when testing rst2pdf. rst2pdf's tests work by creating a PDF and then comparing this to a reference PDF. If they are different, then the test has failed. When a test fails,… continue reading.


I do not enjoy exercise, but I'm at that age where I can see far enough into my future that I would like to remain mobile and healthy well into my later years. So I exercise. I'm not into sports and I find it relatively boring, but this is what is working for me. In the average week I do some form of exercise at least 6, sometimes 7 days. Most days, I walk. Just… continue reading.

macOS tips and tricks

It's been over a decade since I last updated my article for new users to the Mac, so time for a new one that I can point people too. This article is intended to give a quick and easy introduction to some key things that I think you should know when you move to using macOS. Basics There’s one menu bar for all applications. That is, you can only see the menus for the currently… continue reading.

Command line access to GitLab & GitHub

I've always been a huge fan of the command line and have been using the gh command line tool to access GitHub for a while. My current client uses GitLab and I was delighted to discover that there is a glab CLI tool. As you can imagine, both tools do essentially the same thing: operate on GitHub/GitLab from the command line. The two main uses of gh & glab that I have is creating and… continue reading.