My command line toolbet

A laptop on a desk, plugged into a bigger monitor, there is a cat sleeping being the laptop but only his bottom half is visible.

I have decided that 2024 would be the year of… tracking stuff. Last year, I made a point at work of keeping a semi up to date Obsidian vault with a lot of notes, links and context for the things I’ve been working on, the people I interacted with and the projects I ran into. Unsurprisingly, it turned extremely useful after a holiday or when switching back to an old project. That’s why this year, I want to do more of that: track the book I’ve read (or started reading and gave up on 1), the movies and TV shows I’ve watched, and the developer tools I’ve been using. Since I’ve also committed to write more often on this blog, I’ve decided to water two plants with one hose2 and list them here. I, for one, look forward to searching the name of “that one weird tool to transform JSON” in a few months.

Atuin

I discovered Atuin after someone on Mastodon boosted a post from Ellie, in which she mentioned that she was quitting her current job to focus on Atuin, a tool that dramatically improves the experience of search for commands you’ve previously run. First, the story was super inspiring to read. As someone with a bunch of side projects, including one that’s been keeping me busy for a few years, on and off, the idea of doing the same thing has been hinting at me for a little while now. It’s cool to see people brave enough to take the leap.

After I installed Atuin, it automatically imported my existing history by detecting and parsing my ZSH history file. In retrospect, this is a pretty obvious behaviour that you’d expect, but I definitely had a “oh nice” moment after installing atuin and running my first command.

Since I’m a strong believer in the “arrow-up + enter” and “CTRL+R”, to the point where I’ve sometimes re-ran commands before my brain could catch up and destroyed some of my work, I’m pretty excited about atuin3. Of course, I’ve only just started using it. There are a lot of additional search and filtering options that I need to look into. I’m also not using the server to synchronize commands right now, since I’m using it on my work machine. I don’t think that I’m running any sensitive commands and I know that the data is safely encrypted, but you never know. I will definitely look into using the server on my personal machine though. I only have the one laptop but it seems like an easy way to backup my history. Meanwhile, I think the etiquette requires that I share my stats, so here it is as a pretty screenshot…

Stats about the command I’ve run over time

…and here is the data as text format:

Command Times Run
gst 247
gd 177
ls 171
swift 141
gca 128
gp 89
cd 79
gh 59
cat 58
code 55

This looks like a pretty boring history as most of the commands (gst, gd, gca, and gp) are aliases to git commands, provided by Oh-My-Zsh4.

jq

Contrary to atuin that I discovered last week, jq is one of those tools that I’ve been using for so long, I don’t remember a time when it wasn’t installed on any of my machines. jq is a “is a lightweight and flexible command-line JSON processor”. It can read a JSON file or grab the content of the standard input, manipulate it and print the result however you want. Most of the time, I’ve been used it with curl to transform the response from a API, but I’ve also used it to cleanup and search into log files. Here is an example using the extremely convenient randomuser.me API in which we fetch 1000 random users (quietly, that’s the -s part) and then:

  • Grab the results key
  • Filter the users whose city is “Nantes”5
  • Grab the id, the email and the login informations
  • Generate a CSV
curl -s https://randomuser.me/api/\?nat\=fr\&results\=1000 | jq '.results[] | select(.location.city == "Nantes") | [.id.value, .login.username, .email] | @csv' -r
"2690194853841 61","tinycat468","celia.colin@example.com"
"2510288995485 30","goldenlion126","victoria.gaillard@example.com"
"1740141543737 31","ticklishladybug554","eliot.robin@example.com"
"1770966069401 22","lazytiger474","leandre.roche@example.com"
...

Of course, you can do way more than that. I’ve used it in my command line tool that checks for outdated Swift packages in my project or generate JSON out of thin air:

jq --null-input --arg name `whoami` --arg pwd $PWD '{ username: $name, current_directory: $pwd }'
{
  "username": "palleas",
  "current_directory": "/Users/palleas"
}

As I’m writing this post and grabbing links to various pages on the official website, I just realized that you can extend jq with modules. I don’t have a clear use case yet, but that looks like something fun to play with eventually.

gh

I’ve been using GitHub for a long time now, pretty much when I started to learn what git was vastly superior to SVN through the Pro Git book6. I shortly discovered a command line tool named hub (because it was “GitHub without the git part”) that wraps git and adds a bunch of niceties like cloning a GitHub repository without having to pass the full git URL, opening issues, creating repositories… It has since been replaced by gh, a more official command line tool for GitHub that was released a few years ago. To my surprise, hub still exists and seems somewhat maintained. At the time of writing this post, the latest commit was 3 months ago. Even if I’ve since moved to gh myself, learning that hub still exists warmed my heart. Similar to hub, gh is a command line tool that makes it easier to interact with GitHub, as well GitHub enterprise (which I use at work). Interestingly when I first ran atuin on my work machine, gh was in the top 5 of the commands most run, and for good reason: I use it all the time. For example, I use it to create repositories using gh repo create ... or share a command’s output using gist with <some-command> | gh gist create -. I open the repository page or the pull request’s page for the current branch in Safari with gh repo view --web and gh pr view --web respectively. I also create pull requests with gh pr create ... and watch the CI builds with git pr checks. It’s honestly one of my favourite tools and has saved me a lot of times. gh allows you to interact with a lot of areas of GitHub: repositories, codespaces, gists, projects, and so much more. All of the commands provide a bunch of well thought out options (including filtering the output with jq!), but that’s not all. Once you’ve authenticated using your GitHub account (or your GitHub enterprise instance), it also lets you execute raw calls to the REST API or the GraphQL, and supports extensions! I’ve accumulated a few scripts and aliases that rely on gh to make my work (or working on my side projects) a lot easier. Some of them are work-related, so I can’t share them here, but I can list some of the use cases:

  • Looping through all of the comments on a pull-request and marking them as outdated. This is useful to me when internal tools post comments on open pull-request, which I often find noisy. It’s also convenient on long-lived pull-requests on which a lot of discussions happened but no longer make sense.
  • Going through pull requests where my review was requested, but have since been merged. This is pretty common on very active large monorepos like ours. It’s also very useful to declare pull-request review bankruptcy on a Monday morning after a big vacations. If you use GitHub and like automating repetitive tasks, I highly recommend checking out the GitHub CLI page.

Take the time to learn your tools

I voluntarily restricted this blog post to 3 of my most used developer tools, There are many more, as I’m sure you can imagine. Except for Atuin that I only started using this week, those tools have been part of my belt for years and yet, I restricted myself to the most basic usages. It’s only fairly recently that I started writing scripts on top of gh or that I took some time to read the jq documentation past the basic transformations section. There is a time constraint that often pushes us not to stop and smell the roses and read the documentation, but I guarantee that it’s worth it. I’m even willing to bet you’ll discover something new you didn’t think was possible. I hope this list was useful to you and introduced you to new tools, made you rediscover some you already knew or made you think about potential new uses for your favourite tools. I truly enjoyed writing this blog post and learned things as I browsed some of those tools’ homepages.

  1. I’m ashamed, but I’ve given up halfway through The Fellowship of the Ring 

  2. A nicer alternative to murdering harmless little birds 

  3. I assume that you can delete commands from your history, but I could be totally wrong 

  4. Another tool that could have made this list, you should check it out

  5. My hometown, I recommend it if you’re in France, it’s pretty nice 

  6. I just did the maths but stopped counting after 10 years.