~/devreads

Rob Allen

https://akrabat.com/ · 110 posts · history since 2023 · active

26 May

Rob 2 min read

For OSS work, I work with two git remotes: upstream: the canonical OSS project repository, where main is the default branch and is what gets released. origin: a personal fork. All my feature branches live here. I set up locally like this: Fork the project repo to my account. Clone my fork locally, so the origin remote is my fork.…

developmentgit

17 Mar

Rob 1 min read

I have a new project where we will be integrating with a third party API that is currently being written. Due to Conway's Law, we are being sent new versions of the OpenAPI spec as a set of JSON files via email. I quite like seeing the HTML rendering of an OpenAPI spec when reading it and understanding it, so…

apiopenapi

3 Mar

Rob 2 min read

Recently I discovered that this code passed our PHPStan level 10 checks: use http\Exception\InvalidArgumentException; // ... throw new InvalidArgumentException; I was surprised as http\Exception\InvalidArgumentException is not a class in our system. While cooling, I discovered that there's an http PHP extension and it appears that PHPStan has a stub for this which means that it accepts it as existing even…

php

27 Feb

Rob 1 min read

Today has been a struggle entirely due to my own internal negative thoughts and feelings about impacting events that are outside my control. Navigating this to come out stronger rather than letting it consume my self-belief and confidence isn’t easy, especially at the time. I’m not worse at my job and my abilities haven’t diminished, but sometimes it’s hard to…

me

22 Jan

Rob 1 min read

Dad

I don't often post personal things here, however last weekend my dad died peacefully in his sleep and it feels important to acknowledge this. I have no words.

me

31 Dec 2025

Rob 3 min read

As we reach the end of 2025, I take this opportunity to look back over the photos that I have taken and thing about the year. This year I published 1,064 photos to Flickr with, of course, at least one photo every day as part of my Project 365. The lovely thing is that my photos remind me what happened…

meyear in pictures

11 Nov 2025

Rob 1 min read

I've recently upgraded my MacBook Air to macOS 26 Tahoe and one thing I noticed was that Rodeo's rules were no longer working. With the help of exiftool, I worked out that when exporting to JPEG from Photos for macOS 26 Tahoe, the Object Name, Caption-Abstract and Keywords IPRC properties were no longer being populated. This is a regression from…

macphotographyrodeo flickr uploader

14 Oct 2025

Rob 1 min read

Sometimes it's helpful to add some text to my current Obsidian daily note without having to switch to Obsidian, find the daily note and then type my text. To do this, we can use the magic of Obsidian's obsidian:// URI schema and automate the text capture in Apple Shortcuts, with an assigned keyboard shortcut to activate it. This is the…

macshortcuts

7 Oct 2025

Rob 2 min read

I've set my Mac up such that video calls such as Zoom use the microphone and earphones attached to my Behringer UMC204HD, which all other audio plays through the my normal speakers which are the default. One issue I have with this is that it's quite hard to change the volume when a call as the volume buttons on the…

macswift

30 Sept 2025

Rob 3 min read

I use OpenIn to open links in a given browser when I click on them in other applications. This is really helpful to keep various work related stuff in different browsers or profiles and I find it very helpful. One thing that's bothered me is that links from the Jira Cloud Slack App ignore my OpenIn rules and always open…

computing

23 Sept 2025

Rob 1 min read

After pulling a new version of the Docker PostgreSQL container, I started getting this warning: WARNING: database "dev" has a collation version mismatch DETAIL: The database was created using collation version 2.36, but the operating system provides version 2.41. HINT: Rebuild all objects in this database that use the default collation and run ALTER DATABASE dev REFRESH COLLATION VERSION, or…

postgresql

16 Sept 2025

Rob 1 min read

I use bash's history all the time, via ctrl+r and also with the up and down keys; it's wonderful. Sometimes, I want to get back to the end of my history and I recently discovered that there's a shortcut for this: meta+>. It doesn't matter where you are in your history, pressing meta+> jumps you to the end and you…

command lineshell scripting

9 Sept 2025

Rob 2 min read

Following on from my earlier exploration of JWKS (RFC7517), I found myself needing to convert the JWKS into PEM format. This time I turned to Python with my preference of using uv with inline script metadata and created jwks-to-pem.py. The really nice thing about inline script metadata is that we can use the cryptography package to do all the hard…

command linepython

2 Sept 2025

Rob 2 min read

Recently, since getting a new computer, I've noticed that I've been losing bash history items and it took a while to work out what was going on, though I'm still not completely sure as it never seemed to be so much of a problem. I regularly use the up and down keys with context specific history. For example, I will…

command lineshell scripting

26 Aug 2025

Rob 1 min read

One project that I'm working on uses RFC 9457 Problem Details for HTTP APIs for its error responses. In the OpenAPI spec, we can define this as a component and use in the relevant paths as appropriate: components: schemas: ProblemDetails: type: object properties: type: type: string format: uri-reference description: A URI reference that identifies the problem type default: about:blank example:…

openapi

19 Aug 2025

Rob 1 min read

Inspired by John Gruber mentioning on the Cortex podcast that he has a shortcut that saves links to a note in Tot, I thought I'd do something similar for saving to a note in Apple Notes. I want to store as a bullet item containing the name of the page, the link and the date. Something like this: (Funny that…

macshortcuts

12 Aug 2025

Rob 1 min read

One app that I find incredibly useful is SwiftBar and one use I have is to display track info for the currently playing song in Apple Music. SwiftBar plugins work as shell scripts that execute on a timer and echo specially formatted text which SwiftBar then turns into an item on the menu bar with an attached menu I use…

mac

5 Aug 2025

Rob 1 min read

I run Apple Music on my Mac desktop and send the output to my HomePod minis. To control the volume, you need to manipulate the Apple Music volume slider rather than the global volume controls for the Mac. It's easier to press buttons than use a mouse, so I used Keyboard Maestro to respond to two buttons on my Stream…

applescriptkeyboard maestromac

29 Jul 2025

Rob 3 min read

I'm working on a NestJS project that uses monorepo mode. It consists of a number of separate microservice applications that each have their own Docker container that are managed in development using Docker Compose. I like step-debugging in my IDE and so needed to set it up for this application. This is what I did. The application setup Each service…

nodejstypescript

22 Jul 2025

Rob 2 min read

Back in 2016, I wrote about using QuickGrab to take a screenshot of the active window via a single key press with no mouse use required. It's now 2025 and I'm still using this and Apple has announced that Rosetta 2 will be phased out in a couple of years. As QuickGrab is one of the few Intel-only apps I…

macsoftware

15 Jul 2025

Rob 2 min read

I've been writing a simple Swift command line tool called QuickSS. It's a single file swift file, that I compile to a standalone binaryusing: swiftc quickss.swift -o quickss To distribute it on modern Macs, I need to sign it and then get Apple to notarise it. Signing the binary To sign the binary, you need a "Developer ID Application" certificate…

command linedevelopmentshell scripting

8 Jul 2025

Rob 2 min read

I'm currently writing a script that notarises a macOS CLI app which needs to access a password. Rather than put it in an environment variable, I thought I'd use the 1Password CLI. This is the first time I've used it, so these are my notes. The 1Password CLI tool is call op. I installed it via Homebrew with: brew install…

command linedevelopmentshell scripting

1 Jul 2025

Rob 1 min read

We have an HP all-in-one scanner and printer that is on our local network. Recently, I was away from home and needed to reconfigure the scanning settings for unimportant reasons. Usually, when I'm not in the office, I use Tailscale to connect back to machines as required, but the printer isn't running Tailscale, so its built-in web app isn't directly…

computing

24 Jun 2025

Rob 1 min read

I run a Tailscale network so that remote computers can access local services. I also have a Linux box at home on that network that advertises itself as an exit node and recently noticed that it wasn't working. I had some time recently to sit down and work out what was going on. My initial suspicion was that it was…

computing

17 Jun 2025

Rob 1 min read

I'm a member of a number of groups that publish a magazine, either paper-based or PDF. I prefer the PDF version, so download from the website and then move to the relevant directory. Recently, I realised that I could use Hazel to do this for me. To take one example, the filename of the PDF that I download is of…

mac

10 Jun 2025

Rob 1 min read

On a server that I help to maintain, it has postfix installed for emailing results of cron jobs and other status updates. This was set up to relay through SendGrid as they had a 100 email per month plan and we send out significantly fewer than that. Unfortunately, SendGrid are retiring their free plan, so I had to move to…

computingsysadmin

3 Jun 2025

Rob 1 min read

I've had a few cases recently when I wanted to know the number of words that I had written. To do this, I've copied the text to BBEdit which displays the word count in its status bar, but this is a bit of a faff. I finally sat down and created a Shortcut for it that took 10 mins. This…

computingmac

27 May 2025

Rob 1 min read

On one of my servers here, I run a local Perforce P4 server for my son. He's a game developer and as they use P4 at work, he wanted to learn it in a sandbox and to have somewhere familiar to put his own work. Installation onto Ubuntu was easy enough and I provided access outside of our local network…

software

20 May 2025

Rob 1 min read

Earlier this year, Lorna spent some time updating rst2pdf's website to use Sphinx. The nice thing about Sphinx is that it uses restructuredText, the same as rst2pdf does, so we now stay in the same ecosystem. While, we could have continued using Jekyll, it makes much more sense for us to use the same markup language as we use for…

rst2pdf

13 May 2025

Rob 1 min read

When writing an OpenAPI specification, I came across the need for a particular property in an error response to be either a string or an object. This situation came about when validating a POST request that takes an items property that is a list of objects As a contrived example of a pet with accessories, consider this example request in…

apiopenapi

6 May 2025

Rob 1 min read

On the Roave Discord recently, there was a discussion about not breaking BC in interfaces inspired by this post by Jérôme Tamarelle: It's clearly true that if you add a new parameter to a method on an interface, then that's a BC break as every concrete implementation of the interface needs to change their signature. However, Gina commented that you…

php

29 Apr 2025

Rob 2 min read

While it would be nice to put the genie back in the bottle, that hasn't happened often in human history, so for the foreseeable future, AI in the form of LLMs are here to stay. I imagine that what we use them for will change over time as we collectively internalise their limitations. Personally, I'm now using them for my…

ai

22 Apr 2025

Rob 1 min read

To provide consistency between the environments of our developers, I'm a strong proponent of using containers so that every developer is using the same versions of our tools. This is really important for command line tooling that depends on a separately installed language such as NodeJS or PHP as a simple npm i -g can install wildly different versions if…

apidockeropenapi

15 Apr 2025

Rob 2 min read

One of the projects that I'm working on at the moment uses Stripe which means that we need to handle web hooks in order to ascertain what's happened as that's how Stripe communicates back to us. For production and staging, it's easy enough to register a url on Stripe's dashboard, but when developing, it's a little more complicated as our…

developmentdocker

8 Apr 2025

Rob 1 min read

With the release of macOS 18.4, Safari no longer shows a padlock when you visit a website that uses https. I assume there's a reason for this but I was scratching my head trying to work out how to view the SSL certificate when I went to a new-to-me website domain that my bank asked me to go to. This…

computingmac

2 Apr 2025

Rob 4 min read

With the recent release of the new OpenAI ChatGPT that can do image generation, I thought that I might add a feature image to my last blog post. I've had mixed experiences of AI generation of images, probably because I'm not good at prompting them. I started with this: We now have an image, but it doesn't have a credit.…

ai

25 Mar 2025

Rob 1 min read

I'm using Signal more now and as it's fully end-to-end encrypted, if something goes wrong with your phone or you lose it, you will lose your entire message history. Signal on Android has an official backup method, but there isn't one for iPhone or desktop. As a result, a number of backup tools have been written by various people. The…

command linecomputing

18 Mar 2025

Rob 1 min read

As a hobby project, I've been writing a screensaver for my Mac that displays my photos with a caption and date taken. To get the width and height of the screen so that I could size the image correctly, I used this code in my ScreenSaverView: self.screenWidth = frame.size.width self.screenHeight = frame.size.height However, I discovered that with two or more…

development

11 Mar 2025

Rob 1 min read

By default, the first user that you create on macOS is an administrator and has more power over the system than a normal user account. The reason it does this is obvious as you need this power to create other users, to install software and so on. However it also means that the computer is slightly more vulnerable to attack…

computingmac

4 Mar 2025

Rob 1 min read

I was helping a friend set up a new website and hit a problem where the website was in an infinite redirect loop: I could see this in curl quite easily: $ curl -I https://myfriendswebsite.example.com/ HTTP/1.1 301 Moved Permanently Location: https://myfriendswebsite.example.com/ To debug, we turned off Cloudflare by setting the Proxy status on the DNS record in Cloudflare's admin to…

computing

25 Feb 2025

Rob 3 min read

One of the bigger changes in PHPUnit 10 was the introduction of the new extension system which replaced listeners and hooks. The old way On one of my projects we have a TestListener that sets up the database before we run some functional tests against it. It looks like this: <?php declare(strict_types=1); namespace App\Test\Listeners; use App\Test\Functional\Helpers\DbHelper; use PHPUnit\Framework\TestListenerDefaultImplementation; use PHPUnit\Framework\TestSuite;…

php

18 Feb 2025

Rob 1 min read

There is a different between OAuth scopes and roles. A scope is the abilities that the client requests that the user can then decide if they are going to authorise that client to do those things. A role is the rights that a given user has within the application. Scope examples are "read-name", "read-address", "read-email", 'write-all", etc. Example roles might…

development

11 Feb 2025

Rob 1 min read

I recently had a problem with a failing Playwright test that only happened when running in Docker. The test that was failing was: let locator = page.locator('a[href="/login"].nav-link'); await locator.click(); await expect(page).toHaveTitle(/Log in/); The test clicks the link to go to /login and then checks that the next page's title contains the text "Log in". Not an especially complicated test, so…

developmentjs

4 Feb 2025

Rob 2 min read

One very minor thing that's been bugging me since macOS Sequoia came out is that if you launch an app that lives in your menu bar, but also has a hidden Dock icon a second time, then the Dock icon will re-appear. This happens to me a lot because I use Alfred to launch apps and also to bring an…

applescriptcomputing

28 Jan 2025

Rob 1 min read

I create a fair few scripts in my ~/bin/ directory to automate tasks. Since discovering uv and inline script metadata, I've started using Python far more for these. As ~/bin is on my path, I want to run the script by calling it directly on the command line. To do this, I use this shebang: #!/usr/bin/env -S uv run --script…

python

21 Jan 2025

Rob 1 min read

My preferred calendar app for the Apple ecosystem is Fantastical as I've found that it meets my needs well. One minor irritant is that the editor popover defaults to a collapsed view and I have to expand it to see everything, in particular the notes field which I use frequently. I recently discovered that there's a hidden preference to change…

computing

14 Jan 2025

Rob 1 min read

One thing that I've found helpful is to add a set of patterns to my global git ignore file (config/git/ignore for me) that allow me to create temporary files that are automatically excluded from git. The patterns I use are these: # Ignore a file by renaming it with ignore its name *.ignore ignore.* *.ignore.* This lets me create a…

computinggit

7 Jan 2025

Rob 1 min read

When I'm on a Zoom or FaceTime call, I want stop all notifications on my Mac so that I'm not distracted by them and would like this automated. It's not easy to tell when a call is happening, so I simplified the problem to stopping all notifications if the Zoom or FaceTime is running as I only run these apps…

computing

31 Dec 2024

Rob 4 min read

As usual, at the end of the year, I look back over the photos I have taken and think about the year. This year I have published 1162 photos to Flickr. It has been a good year, seeing friends and family, taking photos, attending conferences all coupled with enjoyable work for a good client. I am pleased to have kept…

meyear in pictures

24 Dec 2024

Rob 1 min read

Thanks to Kyle and Lorna, we've moved rst2pdf's development out of the dark ages of setup.py and into uv with pyproject.toml. As a result, I've changed the way I develop rst2pdf locally; these are my initial notes. Set up Python environment Given a clone of the rst2pdf git repository, do this get going: $ uv sync --all-extras This will create…

pythonrst2pdf

17 Dec 2024

Rob 1 min read

I recently discovered the /usr/libexec/corebrightnessdiag command line tool on macOS. In particular, /usr/libexec/corebrightnessdiag nightshift-internal will give information about when the Mac's nightshift settings, including when sunrise and sunset are! $ /usr/libexec/corebrightnessdiag nightshift-internal Night Shift Status { AutoBlueReductionEnabled = 1; BlueLightReductionSchedule = { DayStartHour = 7; DayStartMinute = 0; NightStartHour = 22; NightStartMinute = 0; }; BlueReductionAvailable =

command linecomputing

10 Dec 2024

Rob 1 min read

We recently changed ISP to Aquiss who could not have been more helpful with pre-sales and support for the change over from BT Internet. Aquiss do not provide a router, so I removed the BT Smart Hub and put in a Ubiquity UCG-Max and connected it up to my existing AC Pro Ubiquiti access points. Obviously as it was a…

software

3 Dec 2024

Rob 1 min read

I recently acquired an Elgato Prompter which acts as an additional screen on my Mac. It does this using DisplayLink and the DisplayLink Manager app needs to be running. A new security feature of the newer macOS versions is that when your screen is being recorded, an icon is displayed in your menu bar. It looks like this and cannot…

computingsoftware

26 Nov 2024

Rob 3 min read

I've been playing with different Ethernet network adapters to see if I can maximise the throughput to my Mac as my ethernet didn't seem particularly faster than WiFi. To test the speed, I want to use my internal network only as going onto the Internet will create too many variables. iperf3 is the solution for this. Running the test To…

computing

19 Nov 2024

Rob 1 min read

For some work I'm doing, I have been given access to a Linux box that is part of a legacy production system. The first thing I have done is updated the terminal prompt to include the word PRODUCTION in red, by adding this to .bashrc: export PS1="$(tput setaf 1)PRODUCTION $(tput sgr0)$PS1" The nice thing about doing it this way is…

computing

12 Nov 2024

Rob 1 min read

This is one of those posts that I write so that I can look it up again as this information is all over the Internet, but it took me a little while to find what I was looking for. To accept command line arguments in a Python script, use the argparse package: import argparse You can then instantiate a parser…

python

5 Nov 2024

Rob 1 min read

Earlier in the year, I wrote about updating Flickr metadata using Python. For this script to work, I needed to install the flickrapi package first. I recently came across PEP 723 – Inline script metadata that makes this much easier for single file scripts like my sync-flickr-dates script. Essentially, we can now put a special comment block at the top…

python

29 Oct 2024

Rob 1 min read

There's a new feature in macOS Sequoia that allows mirroring of your iPhone to your Mac. This is a nice feature that allows you to fully interact with your iPhone as an app on you Mac's desktop. When I upgrade to Sequoia and run the iPhone Mirroring app, it selected Victory, my old iPhone 14 Pro Max which is running…

computing

22 Oct 2024

Rob 1 min read

I recently installed Python 3.13.0 rc2 to test rst2pdf against it and found that I couldn't install PyMyPDF which is required for the tests. $ pip install pymupdf ... This is because for a pre-release version, binary wheels are not provided to PyPI for the mupdf dependency which is written in C++. Hence, the compiler needs the headers. On my…

pythonrst2pdf

15 Oct 2024

Rob 1 min read

Last week, Dave Winer posted that Scripting News turned 30. That's an amazing milestone and Dave's still writing daily. 1994 seems like quite a while ago; the web was only 3 years old! I started blogging in 2003 on a personal domain and added this blog in 2005. I don't write daily though and I tip my hat to Dave.…

computing

8 Oct 2024

Rob 1 min read

In my Makefile, I check for OpenAPI spec issues with this command: docker run --rm -it -v $(PWD):/tmp stoplight/spectral lint \ --ruleset /tmp/spec/.spectral.yaml /tmp/spec/openapi.yaml When running in GitLab CI, we set the image to stoplight/spectral:latest, and override the entry point so that we can run spectral directly: openapi-lint: stage: test image: name: stoplight/spectral:latest entrypoint: [""] script: - spectral lint --ruleset…

development

1 Oct 2024

Rob 1 min read

Sometimes you need some additional DNS entries in your containers. This is how to do it in compose.yaml. Internal entries Within the containers, the name of the container in compose.yaml is resolvable via DNS. Given this compose.yaml: services: web: # ... app: # ... networks: myapp: driver: "bridge" We can ping web from within the app container. If we need…

developmentdocker

24 Sept 2024

Rob 1 min read

When Guzzle throws BadResponseException, the message includes information about the method, URL response code and then a truncated part of the body. For example: "Client error: `GET https://dev.clientproject.com:4444/oauth2/authorize?client_id=983e98d2fab8756a&scope=scope&response_type=code&redirect_uri=%2Fhome&code_challenge=some_code_challenge_here` resulted in a `400 Bad Request` response: {"error":"invalid_request","error_description":"The request is missing a required parameter, includes an

php

17 Sept 2024

Rob 1 min read

Recently, I set up my PHP dev environment to allow me to step debug from unit tests that I run with make unit The relevant parts of Makefile look like this: # Set DEBUG=1 to enable Xdebug ifeq ($(origin DEBUG),undefined) XDEBUG := else XDEBUG := XDEBUG_SESSION=PHPSTORM endif unit: ## Run unit tests docker compose exec php bash -c "$(XDEBUG) vendor/bin/phpunit…

developmentphp

10 Sept 2024

Rob 2 min read

I'm working on a project that uses MS SQL Server as its database. Recently, I noticed that the SQL Server Docker container now works with Apple Silicon Macs, so looked into setting up a PHP-FPM container with the sqlsrv extension installed. I'm noting the relevant parts of my Dockerfile for when I need them again, so this is entirely an…

developmentdockerphp

3 Sept 2024

Rob 3 min read

For one project that I'm working on the PHP-FPM-based Docker container is built from a Ubuntu container with PHP is installed into it. A little like this: FROM ubuntu:22.04 RUN apt-get update && apt-get upgrade -y && apt-get install -y gnupg curl # Register the Ondrej package repo for PHP RUN mkdir -p /etc/apt/keyrings \ curl -sS 'https://keyserver.ubuntu.com/pks/lookup?op=get&search=0x14aa40ec0831756756d7f66c4f4ea0aae5267a6c' | gpg…

developmentdockerphp

27 Aug 2024

Rob 2 min read

Unsurprisingly, uploading files with Slim 4 is pretty much the same as for Slim 3 as they are both use PSR-7 for Requests. Recently, Matthew asked a question about why he was getting an error, so I looked into it. One thing that's really nice about Slim is that you can write a complete application in a single file (+…

command line

20 Aug 2024

Rob 2 min read

It's common to use a UUID when you need a primary key for your database records. Unlike incrementing numeric keys, it has the advantage that it's not tied to a specific database instance and can be created before insertion into the database. Usually, people use version 4 UUIDs, which contains a lot of randomness to ensure that it's going to…

computingsoftware

13 Aug 2024

Rob 1 min read

I'm a huge fan of making my life easier and one thing I have found really helpful is automatic text substitution. The Mac has a built-in solution, but it's slightly clunky as it uses a popup to confirm that you want to substitute, so I use Keyboard Maestro, however there's many alternatives out there. My personal preference is to prefix…

computing

6 Aug 2024

Rob 1 min read

I've been doing a few updates to Daily Jotter, my little Mac app that's available in the Mac App Store. It's been a little while since I last updated it and a few things have changed. After updating the code to fix deprecation warnings, my immediate problem was that the debug version of the app wouldn't start up and I…

development

30 Jul 2024

Rob 1 min read

Recently, I was writing a bash script that read a file into a string and then passed that string elsewhere that then calculated the hash of it. To my surprise, I was getting a different hash to doing the equivalent in PHP with file_get_contents(). Digging into it, I discovered that when you assign the output of cat to a variable,…

shell scripting

23 Jul 2024

Rob 1 min read

If you want to see the hex values of a file, the easiest way to do this is to use xxd. Given foo.txt that contains "This is some text!": $ xxd foo.txt 00000000: 5468 6973 2069 7320 736f 6d65 2074 6578 This is some tex 00000010: 7421 0a t!. There are three columns in the output: number of first character…

shell scripting

16 Jul 2024

Rob 1 min read

When using Docker Compose, I often map the ports to local ones in the compose.yaml like this: services: web: build: context: ./docker/web ports: - "8080:80" Adding to the port map If port 8080 is in use already on a developer's machine, then we can add a new mapping using compose.override.yaml services: web: build: context: ./docker/web ports: - "8081:80" The compose.override.yaml…

development

9 Jul 2024

Rob 4 min read

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…

computing

2 Jul 2024

Rob 1 min read

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…

shell scripting

25 Jun 2024

Rob 1 min read

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…

php

18 Jun 2024

Rob 1 min read

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…

shell scripting

11 Jun 2024

Rob 1 min read

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…

development

4 Jun 2024

Rob 4 min read

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…

shell scripting

28 May 2024

Rob 2 min read

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…

shell scripting

21 May 2024

Rob 1 min read

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…

lifeme

14 May 2024

Rob 5 min read

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…

computing

7 May 2024

Rob 2 min read

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…

command linecomputing

30 Apr 2024

Rob 1 min read

I wanted to stash just the unstaged changes in my git repo. There's a git stash --staged which will stash the staged files, but I didn't see an equivalent to stash just the unstaged ones. Obviously, this is a common problem so a minute or two of googling will find the Git stash uncached: how to put away all unstaged…

command linedevelopment

23 Apr 2024

Rob 1 min read

While reading Alex Chan's post about experimenting with the Flickr API, I noticed the call out to keyring by Jason Coombs for accessing the macOS Keychain. The built-in app: security The built-in way to access the keychain from the command line is /usr/bin/security: To create a password: $ security add-generic-password -s FlickrAPI -a rodeo -w redacted-key Note that you need…

command linecomputing

16 Apr 2024

Rob 1 min read

I've been following the work of Matt Gemmell for years. His techno-thriller Kestrel series a great fun to read and I recommend that you read them if that's your thing. He also writes short stories, one every week. These are excellent. They are free and as they are short, they don't take long to read at all. A wonderful break…

around the weblife

9 Apr 2024

Rob 1 min read

With some commercial projects, it can be useful to know that all your dependencies have licences that your organisation deems acceptable. I had this requirement for a few clients now and came up with this script that we ran as part of our CI which would then fail if a dependency used a license that wasn't allowed. This proved to…

php

2 Apr 2024

Rob 1 min read

I install Python apps on my Mac using pipx like this: pipx install rst2pdf This will then install rst2pdf into its own isolated environment so that its dependencies do not affect and are not affected by any other Python app I have installed. Internally, it creates a venv at /.local/pipx/venvs/rst2pdf with symlinks to the currently installed python in the bin…

computingrst2pdf

26 Mar 2024

Rob 2 min read

In order to verify a JWT created with an asymmetric key, the verifier needs to get the correct public key. One way to do is described in RFC7517 which describes the JSON Web Key format. Within the header of the JWT there is a kid property which is the key ID which is then used to find the correct key…

php

19 Mar 2024

Rob 3 min read

The most common use of JWTs is as an authentication token, usually within an OAuth2 workflow. Creating these tokens is part and parcel of the authentication library that you use. I recently had a requirement to use a JWT independent of authentication and these are some notes on what I learned when researching with Lcobucci\JWT. Make up of a JWT…

php

12 Mar 2024

Rob 1 min read

One annoyance I had with my external USB hard drives is that they weren't sleeping when idle which makes them noisy. We can't have that! My first port of call was hdparm and its -S parameter: sudo hdparm -S 60 /dev/sdb However this didn't help. Fortunately, I found hd-idle which worked! After installing, you need to edit /etc/default/hd-idle and change…

computing

5 Mar 2024

Rob 1 min read

I recently added a second SSD to my Linux server and had to look up how to format it and set it up, having not taken notes for the first one. These are the notes I took the second time. This is all done from the command line and the monospace text is to be typed directly – though change…

computing

27 Feb 2024

Rob 2 min read

Shortly after building a script to create binaries for Rodeo, my command line Flickr uploader, I realised that I could use a Github Actions workflow to run it and attach the created binaries to the Release page once I had created it. This is what I did. Trigger on release A GitHub Actions workflow is a YAML file and each…

developmentgorodeo flickr uploader

20 Feb 2024

Rob 3 min read

Last week, I attended PHPUK 2024. This is one of the major PHP conferences and I was pleased to speak about DDD there. Sam and the team did a fantastic job this year with the videos already published. To my mind, attending a conference provides a number of benefits. The first and most obvious one is that you learn some…

conferences

13 Feb 2024

Rob 2 min read

One nice thing about Go is that it can cross-compile which allows me to use my Mac to build binaries for different operating systems. This is increibly useful for providing binaries for Rodeo, my command line Flickr uploader. To do this we set the GOOS and GOARCH environment variables before calling go build. For example to build for x64 on…

developmentgorodeo flickr uploader

6 Feb 2024

Rob 2 min read

When I was building Rodeo, my command line Flickr uploader, one thing I wanted to do was set the version number that you see when you type rodeo -v to the correct version when I build the application for release. The basic process I wanted was: Tag git repository with new version number and push Build rodeo with that version…

developmentgorodeo flickr uploader

30 Jan 2024

Rob 2 min read

I have a Linux-based server that acts as my Plex server amongst other things. It's fanless and I added an additional SSD for to hold the media data so it is nice and quiet. I'm a little bit of a belt-and-braces person when it comes to backing up my data, so in addition to backing up to the cloud, I…

computing

23 Jan 2024

Rob 1 min read

I upload lots of pictures to Flickr and sometimes I just want to point at a file in Finder and upload it. Fairly recently, macOS introduced Quick Actions to Finder and this seemed like the ideal way to have a quick and easy way to upload an image to Flickr. To do this, the easiest way is to use Automator…

computing

15 Jan 2024

Rob 1 min read

I regularly need to darken images for background use behind a title. I've been using a filter in Acorn, but finally decided to make it a script that uses ImageMagick so that I could simplify it all with Alfred. This is the script: darken-image.sh #!/usr/bin/env bash if [ -z "$1" ] then echo "Usage: darken-image [contrast=40]" echo "" exit 1…

computing

9 Jan 2024

Rob 2 min read

I usually use my rodeo app to upload photos to Flickr, but for various reasons, I recently uploaded some photos directly via Flickr itself. One feature of rodeo that I really like is that it sets the date posted to be the same as date taken which means that they are ordered correctly in my photo stream. As this doesn't…

python

2 Jan 2024

Rob 1 min read

When creating my Year in Pictures post I decided that I wanted a montage of all the photos I had taken. In previous years, I've done this by taking a screenshot in an application where I try to set the zoom level correctly to get something acceptable. This time, I decided to do it properly and guessed that ImageMagick could…

software

31 Dec 2023

Rob 3 min read

As we finish 2023 and look forward to 20024, I have had an enjoyable time looking back at the photos I took throughout the year. As with the last 10 years, I have managed to take a least one photo every day as part of my Project 365, which allows me to remember what happened during this year of my…

mephotographyyear in pictures

9 Nov 2023

Rob 2 min read

For years, 19ft.com has been a hand-built static HTML website with a smidgen of PHP to set things like dates and include a header and footer to each page. While I haven't yet redesigned it, it seemed prudent to move it to a static site generator before I did so and I chose Hugo, mainly because as a go CLI…

web

1 Nov 2023

Rob 2 min read

I have a set of Markdown files with YAML front matter that contains a created property containing the date that the file was created. Due to various machinations, the file creation date no longer matches this date, so I thought I'd fix this. Setting created date of a file On macOS, to change a file's creation date you use SetFile…

computingshell scripting

5 Sept 2023

Rob 1 min read

For some automation that I"m writing, I need to get the Bundle ID for some Mac applications. The easiest way to do this is with AppleScript: osascript -e 'id of app "{Application Name}"' This can easily be turned into a bash script such as `bundle-id-of` like this: #!/usr/bin/env bash osascript -e 'id of app "'"$1"'"' And we can now obtain…

software

15 Aug 2023

Rob 1 min read

I'm a huge fan of ExifTool for manipulating EXIF data in images as it really is the Swiss Army knife for all things metadata related with images. Recently, I wanted to strip some privacy-related metadata from some photos; specifically location, people and keywords. That is, I wanted to keep the title, the camera settings, the creator, and so on, but…

photographysoftware

19 Apr 2023

Rob 1 min read

I recently needed count the number of rows in an SQL query that had a Group By clause. It looked something like this: SELECT account_name FROM events WHERE created_at >= CURDATE() - INTERVAL 3 MONTH GROUP BY account_id This provides a list of account names (28 in my case), but if you try to count them using: SELECT COUNT(account_name) as…

database

7 Mar 2023

Rob 2 min read

TL;DR: If someone sees you enter your passcode on your phone and then steals your phone, they can lock you out of your Apple account, losing access to all your iCloud data, including photos. Treat your phone passcode as carefully as the secret it is. The problem I heard about "A Basic iPhone Feature Helps Criminals Steal Your Entire Digital…

computing

21 Feb 2023

Rob 2 min read

I have just returned from the 2023 edition of PHPUK and, as always, found it a valuable conference to catch up with the PHP community and find out what’s happening in the ecosystem. This year, I was accepted to speak on the differences between RPC, REST and GraphQL APIs and was surprised and gratified that the room was at full…

conferencesphp

13 Feb 2023

Rob 2 min read

A very big part of my work at Covie for the last year has been putting in place the processes required for to achieve SOC 2 Type II compliance. This standard by the AICPA is all about an organisation's security, availability, processing integrity, privacy and confidentiality controls and processes. It's a comprehensive set of requirements covering our product's and organisation's…

compliance