🔗 emperror.dev/errors

Drop in replacement for the github.com/pkg/errors package. The original package is archived as there’s a plan to change how Go handles errors. But not all of us are ready to adopt this yet.

Detecting When GetItem On DynamoDB Returns Nothing

I was trying to remember how best to detect when a GetItem call to DynamoDB returns no values. That is, when there’s no item with that key in the table. This is in a project that is using v2 of the Go AWS SDK.

After poking through some old code that did this, it looks like the way to do so is to check that the returned Item field is nil:

out, err := p.client.GetItem(ctx, &dynamodb.GetItemInput{
    Key:       key,
    TableName: tableName,
})
if err != nil {
    // Error getting the item
    return nil, err
} else if out.Item == nil {
    // No item found
    return nil, nil
}

// Do the thing with out.Item

Ok, I can live with this approach. I’m kinda happy that I don’t need to check the error message, since doing so using the Go AWS SDK is a bit of a pain.

Rebinding Keys For Quickly Resolving Conflicts in GoLand

I’m dealing with a lot of conflicts today as I try to clear a backlog of Git rebases in my to-do pile. I’ve been using GoLand to do this, as my current Git “mergetool” is configured to Vimdiff for some reason1 and I’m not really bothered to find some other tool, at least not yet. GoLand does a pretty good job.

Unfortunately, the default key-bindings for resolving conflicts in GoLand is far from good. About the quarter of actions are bound to keys that make sense. Half the actions, like ignoring hunks, are not bound to anything, while the last quarter are bound to keys that result in a suboptimal experience. For example, the key to accept changes for a delta use the arrow keys, whereas the key to go to the next delta is F7. What a strange default. I’d have to constantly move my hand off the arrow keys over to the Fn row if I want to go through and fix each delta. This, plus moving over to the mouse to select an action not bound to a key, makes resolving conflicts really slow.

Fortunately GoLand allows remapping keys to pretty much anything, so I’d figured it’s time to fix this problem. I set about coming up with a nicer key-mapping scheme for resolving conflicts. I wanted to come up with one that adhered to these principals as best it can:

  1. My hands must not move from where they rest on the keyboard for almost the entire time a file is being worked upon. The only exception are actions that are invoked less frequently and have a large radius of change — such as the accepting all changes from the left or the right. I’d figured it’s still okay to use the mouse for those.
  2. The arrow keys should be used for navigation (go here) and for addressing (this one).
  3. The modifier keys should be used for choosing the operation, such as going to the next delta, or choosing or ignoring a change.

Here’s the key-map I’ve come up with. The actions marked with an asterisk were the one’s that I needed to change. All these actions are within the “Version Control Systems > Diff & Merge” group within the “Keymap” section in preferences.

Action Key Binding
Previous Difference * ^⌘↑
Next Difference * ^⌘↓
Previous Conflict * ^⌥⌘↓
Next Conflict * ^⌥⌘↓
Accept Left Side ^⌘→
Accept Right Side ^⌘←
Ignore Left Side * ⇧⌘←
Ignore Right Side * ⇧⌘→
Confirm Merge ⌘Enter

I’ve only tried this out as part of a single rebasing session, but already it feels so much faster. It’s taken me probably half the time to go through each file now, maybe even better. I also like the fact that most of the time I only need to hold down Ctrl and Cmd key, and use the arrows to move to and accept changes. Ignoring a change involves moving my left pinky to the Shift key, adding a bit of resistance to indicate an action that requires just that little bit more care.

We’ll see how this goes as I deal with future conflicts, and I may make a change or to. But this is looking really promising.

One last note: this was done in GoLand but I’d imagine it’s possible to set this key-mapping up in most, if not all, of JetBrain’s other IDEs.


  1. It was previously something else, and I have no idea how it got changed. [return]

🔗 A delightful reference for HTML Symbols, Entities and ASCII Character Codes

A great reference site I stumbled along when I was trying to find the perfect arrow to include in a webpage. Nice, clean, and quite comprehensive. No awful ads either, which is a breath of fresh air.

Turning Off Shared Command History in Oh My Zsh

TL,DR: add “unsetopt share_history” to your .zshrc file

I’ve been using Oh My Zsh at work for a few months. As far as terminal config managers go, this one works pretty well. But the default configuration does include something which I found quite annoying.

First, a few words on how I use the terminal. I’m in the terminal constantly in my day to day. At the start of the day, I’m creating terminal tabs and running commands to do things like build the project I’m working on, start a testing session, etc. This all starts very ad-hoc, but over time these tabs take on a particular role. I may run make and git in the left-most tab, run tests in the tab next to that, have logs tailing in the one after that, etc. As I start and stop commands in each tab, they all build up a different history, which is usually visible in the terminal output itself. Eventually it comes to the point where in order to run a particular tool, I simply need to switch to the particular tab and press ↑ one or two times to get to it.

Installing Oh My Zsh broke this workflow. Out of the box Oh My Zsh enables shared command history across each session, meaning that the commands recalled when pressing ↑ are the last commands executed in any tab. This meant that when going through the history, the recalled command would be different from the ones that I’ve entered in the tab I’m in. In addition to this resulting in pressing ↑ way more times than I used to — sometimes to the point where I gave up and simply typed the command out again — it also meant that the recalled commands differ from the ones I saw in the tab output itself. This was very jarring.

Fortunately, this feature can be turned off simply by adding the following to your .zshrc file.

unsetopt share_history

I did just this and my old workflow was restored.

I don’t know why shared command history was chosen as the default. Am I in the minority using the terminal this way? Maybe. But I know for certain that this group is larger than a single person. In either case, I’m glad that I was able to disable this “feature”.

DynamoDB JSON Attribute Types Quick Reference

Because apparently it’s too difficult for AWS to provide an easy way to find this information.

Atomic Types

Type JSON Value
Binary B String value containing the Base64-encoded binary data.
Boolean BOOL Either true or false
String S String value
Number N String with the numerical value
Null NULL Should always be true

Collection Types

Type JSON Value
List L A JSON array, with each element being an attribute with a type.
Map M A JSON object, with the keys being the map keys, and the values being an attribute with a type.

Set Types

Type JSON Value
Binary Set BS A JSON array of Base-64-encoded binary data.
Number Set NS A JSON array of string with the numerical values.
String Set SS A JSON array of strings.

Source: AttributeValue API documentation: this the definitive guide from AWS.

List and Delete All Docker Containers

A useful command I occasionally use. This will list all Docker containers, and delete each one regardless of whether it’s running or not. Good if you use Docker for dev containers and need to reset your state.

docker ps -a --format '{{.ID}}' | xargs -I{} docker rm -v {}

EDIT: thanks to @sonicrocketman for suggesting another way to do this. Works just as well:

docker ps -aq | xargs -I{} docker rm -vf {}

Showing Only Changed Files in Git Log

This technique shows only the changed files in a git log call without having to show the entire patch:

git log --name-only ...

The

If there’s anyone else out there using Buffalo to build web-apps, I just discovered that it doesn’t clean up old versions of bundled JavaScript files. This means that the public/asset directory can grow to gigabytes in size, eventually reaching the point where Go will simply refuse to embed that much data.

The tell-tail sign is this error message when you try to run the application:

too much data in section SDWARFSECT (over 2e+09 bytes)

If you see that, deleting public/assets should solve your problem.

Showing A File At a Specific Git Revision

To display the contents of a file at a given revision in Git, run the following command:

$ git show <revision>:<filename>

For example, to view the version of “README.md” on the dev branch:

$ git show dev:README.md

There is an alternative form of this command that will show the changes applied to that file as part of the commit:

$ git show <revision> -- <filename>

This can be used alongside the log command to work out what happened to a file that was deleted.

First, view the history of the file. You are interested in the ID before the commit that deleted the file: attempting to run git show using the deletion commit ID it will result in nothing being shown.

$ git log -- file/that/was/deleted
commit abc123
Author: The Deleter <deleter@example.com>
Date:   XXX

    Deleted this file.  Ha ha ha!

commit beforeCommit
Author: File Changer <changer@example.com>
Date:   XXX

    Added a new file at file/that/was/deleted

Then, use git show to view the version before it was deleted:

$ git show beforeCommit:file/that/was/deleted