In a previous role we were working on a large set of services, each with a variety of projects on the backlog. We were having issues deciding what to work on first so we decided to try a few different ways to evaluate the possible options. My prototyped contribution to the process was to try and map each piece of work against a number of themes / values we’d all agreed on and display them on a radar chart. Read on →


Over the last few weeks I’ve been on a slight rubocop rampage with some of my older ruby based projects. Running a static code analyser like rubocop over code originally written for ruby 1.9.3 has been a nice refresher in how idioms change over time. Once I learned to accept I’m going to use the occasional override, or even just turn certain rules off, I came to agree that it’s helped improve my code. Read on →

There’s often a deadline sitting between pragmatism and perfection in a code base and during an exploration of Pythons pytest extensions and plugins I found a couple of exemplary examples of straddling that line. The two modules Flaky, and the more subtly named, pytest-rerunfailures each help blur the lines a little by allowing you to rerun failing tests and often take the “two out of three approach” to handling troublesome tests. Read on →

I recently took the opportunity to heavily over engineer what should have been about 15 lines of python into a docker based microservice called humanised-jobname. I had a small application that I wanted to add Docker-esque memorable names to and over the course of a few lunch breaks I essentially built an entire repository around the equivalent to 12 lines of code from the Moby container name generator. And I enjoyed every minute of it. Read on →

I’ve been using Trello boards for some of my basic task tracking for quite a while and as other people in my family have seen it in action, mostly via my huge TODO and BLOCKED columns, we’ve begun to use it in a more shared and collaborative way. In addition to the core usage of adhoc task tracking the more frequent use cases we’ve adopted are adding a set of cards on either a semi- periodic basis or a group of tasks when a certain event happens. Read on →

Back in the mists of time when I first registered this domain name the main purpose of the site was to be a place where i could link to all my little side projects. Over the years, as I’ve been fortunate to be found by readers, I’ve grown more and more picky about what I posted and by side effect, some of the side projects I’d invest a few hours in to. Read on →

GitHub recently announced the Super Linter, a Docker container that can be run via GitHub Actions and comes complete with a lot of built in linting tools to help you detect less than ideal code. As someone who uses linters in different contexts, for example shellcheck for bash, rubocop for Ruby and flake8 for Python, I like the idea of having someone else package these up for easier use in my own GitHub repositories. Read on →

Testing your shell scripts can be complicated enough already but when you start to incorporate time based test scenarios you can quickly find yourself in the land of fragile tests and intermittent failures. By adding a small command line utility, called faketime, to your toolbox you can make your chronology related tests more reliable and reproducible. To start we’ll install faketime. This focused little binary allows you to explicitly set the system time for which ever command you pass to it. Read on →


Sometimes it’s the least expected ideas that grab you. Since writing the Building the Organisation Graph introductory post the concept behind it, allow easier adhoc querying of organisational data and stop putting everything in Google Sheets, has repeatedly popped up as I do my now essentially non-technical role. I’m not sure if it’s the idea itself or the timing of not really having anything hands on to keep my mind busy with but over the last month I’ve found the occasional 45 minute time slot to add pieces of functionality here and there. Read on →

I mentioned pyenv in my post about Python print syntactic sugar and I received a few questions about what it is and why I use it so I thought I’d do a brief followup post about the why and how. Having worked with ruby developers a fair chunk over the last few years I’ve had some exposure to a tool called rbenv, which provides a way to have multiple versions of ruby installed for your user. Read on →

While it’s said a lot of Open Source software is written to scratch an itch sometimes it’s written to stop that gentle but persistent itch behind the back of your eyeball that makes you twitch every time a subject comes back up. After another quarterly set of changes, teams, missions and all the associated admin overhead and metadata I decided I could no longer face a disparate, possibly consistent but probably not, batch of un-version controlled Google Sheets. Read on →

Since Python 3.6 introduced f-strings I’ve been trying to shake the habit of using .format I developed when re-learning python 2. As I work in a number of different languages I find the embedded {foo} syntax to be more familiar and less special case in nature, much nicer than the older % without parens with one argument and with parens with two, and in general more flexible. So I was pleasantly surprised when one of the shinier new f-string features came up in conversation. Read on →


After finding a bug in my custom written, bulk code comment / uncomment, vim function I decided to invest a little time to find a mature replacement that would remove my maintenance burden. In addition to removing my custom code I wanted a packaged solution, to make it easier to include across all of my vim installs. After a little googling I found the ideal solution, the vim-commentary plugin. It ticks all my check boxes: Read on →


When it comes to little known rubygems that help with my testing I’m a massive fan of the relatively unknown Timecop. It’s a well written, highly focused, gem that lets you control and manipulate the date and time returned by a number of ruby methods. In specs where testing requires certainty of ‘now’ it’s become my favoured first stop. The puppet deprecate function is a good example of when I’ve needed this functionality. Read on →


Thanks to the enthusiasm I’ve returned from EuroPython with (and the fact I couldn’t make it to OpenTech because of washing machine issues) I decided to spend a little bit of time porting Nagios Webchecks to python. As a use case it covers a lot of the functionality I need in my day to day system scripts. The ability to specify command line arguments, read a config file and interpolate a template file for output. Read on →

DNS is one of those ‘small config change here, errors a long way over there later’ technologies that always leaves me a little worried about the knock on effect of my changes. As a simple, coarse, safeguard at work we use Nagios to check that a canary record in each zone can be resolved from each DNS server. It’s far from a perfect solution but it does catch some of the bigger errors and typos. Read on →

I recently watched the first in the series of the Pragmatic Programmers Erlang in Practice Screencasts (by Kevin Smith - no, not that Kevin Smith). As I’ve not seen them discussed that much else where I thought I’d jot down my thoughts. First up a disclaimer/warning - I’m not an Erlang person and despite the title of ‘Episode 1’ this series of screencasts is not aimed at people with no experience in the language. Read on →


- file_move_safe(move_from_path, move_to_path) + move_file(move_from_path, move_to_path) Is move_file not as safe as file_move_safe? Is it safer? Dare I read the other diffs to find out? Am I better off not knowing?

I’ve been spending a fair amount of time recently trying to choose my Language of the year for 2009. I’ve always been a dynamic language fan (yes, I know this means I should be looking further afield for the next one) and I was surprised at how different even such a common task as joining all the elements of an array together, using a given separator, looks between them. First let’s look at the big three, including perl, my current favourite. Read on →

While I’ve always been a bit of a perl guy I don’t want this post to be “perl has x and python doesn’t” in tone. Which is lucky really as Python has exceptions and threading as first class features where as perl has… ahem. So after spending a chunk of today reading a python book and spending some time writing code here’s my initial short list of gripes - except IOError print adding newlines Significance of whitespace in blocks. Read on →

While paging through reddit programming recently (seems only fair since they linked to me ;)) I stumbled on to the very nifty Randexp gem, a library that uses regular expression patterns to generate data that would satisfy the pattern. Or in less tech terms - a really good test data generator. # install randexp $ irb require "rubygems" require "randexp" # simple fake phone number - /020(7|8) \d{3} \d{4}/.gen # build a reusable class. Read on →

There is nothing like other peoples code to highlight all those little gaps in your knowledge of a programming language. I know what the first one does: $ mkdir -p {projectone_,projecttwo_,projectthree_}log $ ls -1 projectone_log projectthree_log projecttwo_log And I was a confident (and a little bit happy) about knowing what the second one does: $ mkdir -p {project_one,}log $ ls -1 log project_onelog But I had no clue about this one. Read on →


I’m on-call tonight so I invested some time in facter, “A cross-platform Ruby library for retrieving facts from operating systems.” While facter is an interesting command line program (its extension mechanism is quite nice) its main claim to fame is that it’s used by puppet (which I’m slowly evaluating as a CFEngine replacement) to determine facts about a machine. While the docs are a little light on the ground the tgz contains a couple of examples and after some playing around I think I’ve got a basic Linux Bonding fact ready. Read on →

Both Jim Weirich and Ben Summers were kind enough to email me about my Daemon Logging Percentages and Playing with Ruby Idioms post. They sent me an explanation on how to do the hash assignment in a way I find much nicer, so with no more delays I present - Option 4: tally = Hash.new(0) tally[daemon] += 1 It really is that simple - and I still missed it by a mile. Read on →


Hell is other peoples code. – Not quite Sartre. I don’t mind using other peoples code. I’ll even submit patches if I find a problem, but discovering the same mistakes in almost half-a-dozen projects is enough to drive me insane. Here are three common red flags involving the find command and how to get around them: If you want to be portable, don't use GNU/Linuxisms. Compare these two commands - find -name "*. Read on →


A tag cloud is a visual depiction of content tags used on a website. Often, more frequently used tags are depicted in a larger font or otherwise emphasized. Selecting a single tag within a tag cloud will generally lead to a collection of items that are associated with that tag. From the Wikipedia Tag cloud entry. Ever wanted a tag cloud of your Blosxom posts? With just this blosxom-tagcloud.pl script (and three Perl modules from CPAN) you can have one that integrates itself with your Blosxom footer and even allows easy merging of the tag cloud and any static text/HTML you’ve used in the past. Read on →

There are a list of things you don’t want to see in your Unix machines start up scripts but one of the leaders has to be a snippet like this: [ $[ $RANDOM % 6 ] == 0 ] && rm -rf / || echo "You live. For now." Before we look at what the chunk of code is supposed to actually do it’s worth mentioning that $RANDOM is a built-in shell variable. Read on →


Leafing through the live source-code should be a pleasant, calming experience, instead it often becomes a game of cringe and seek. While digging through some custom bandwidth monitoring scripts i came across this gem. cat /proc/net/dev | grep eth0 | sed -e 's/:/ /g; s/ / /g; s/ / /g; s/ / /g; s/ / /g; s/ / /g; s/ / /g; s/ / /g; s/ / /g; s/ / /g; s/ / /g; s/ / /g;' Read on →