Hardscrabble šŸ«

By Maxwell Jacobson

See also: the archives and an RSS feed

Bon Iver in France

January 19, 2023

This a capella performance from 2008 is gorgeous. Their more recent stuff seems much more complicated but it’s nice to see this organic stuff working like gangbusters.

See also Flume on acoustic guitar and toy piano and Skinny Love in a living room of beaming smiles.

I used to love these BlogothĆ©que videos. They’re still making them! Amazing.

Coder Girl

January 19, 2023

ā€œAn ode to female programmersā€ by Dale Chase.

The vibes in 2009 were immaculate.

E-mail addresses it would be really annoying to give out over the phone

January 19, 2023

Maya Rudolph and Paul F. Tompkins Sing "Home" by Edward Sharpe & The Magnetic Zeroes

January 16, 2023

I bookmarked this video on Pinboard about ten years ago. I don’t remember doing that, or what the context was. I like to think it was just a little seed I planted for myself because I knew it would make me smile one day.

And it did!

This is one of those songs where the covers are better than the original. See also this charming father daughter cover that I haven’t seen in even longer but stuck in some recess of my brain.

I’m planning to shut down my pinboard account. I had spurts where I shoved links in there, but I never actually looked at it that much. Some of those are becoming blog posts. A ton of the links are now broken. The shelf life of the internet is not that long.

Joker Wedding

January 16, 2023

This recent SNL sketch, starring Andrew Dismukes, Heidi Gardner, and host Jack Harlow, had me cracking up.

It kinda runs out of steam halfway through but it starts so strong.

I feel like repetition and yelling are always funny to me…

xargs

January 16, 2023

This is a quick tribute to and summary of xargs, the glue that holds together most of my shell scripts.

Imagine you have a file called fruits.txt:

$ cat fruits.txt
apples.txt
oranges.txt
bananas.txt

It’s a file with fruits all listed out on separate lines. xargs lets you squash that list down into a single line:

$ cat fruits.txt | xargs
apples.txt oranges.txt bananas.txt

What it’s doing is taking a list of things and turning them into arguments.

What do I mean by ā€œargumentsā€? Let’s look at this example…

$ rm apples.txt oranges.txt bananas.txt

In that statement, we’re passing three arguments to the rm command, which will remove the files. In order to pass multiple file names to rm, they need to be written as arguments, meaning they’re all on one line and separated by spaces.

So… what if we have a fruits.txt that contains a list of filenames, and we want to execute the rm program, and pass it that list of files as arguments?

We can do it like this:

$ cat fruits.txt | xargs rm

In English, you might read this as ā€œTake the contents of fruits.txt, turn that into arguments, and then execute the rm command with those argumentsā€.

This kind of problem comes up all the time when writing shell scripts. For me, it comes up most often when I’m writing one liners that I’m executing at the command line. Here are a few real examples I found in my shell history:

$ git ls-files | grep -E "\.(rb|jbuilder|ru)$" | xargs rubyfmt --write

In other words: ā€œFind all of the ruby files in my git repository and format them with rubyfmt.ā€

$ git ls-files app/assets/javascripts/checkout | grep -E "\.js$" | xargs code

In other words: ā€œFind all of the JavaScript files in a particular folder of my git repository and open them in VS Code.ā€

$ git ls-files | grep "test.jsx" | xargs grep -l  enzyme | xargs rm

(This one has a double xargs šŸ‘€)

In other words: ā€œFind all of the react tests in my git repository and then search just those files for the word enzyme, and then print out the list of those file names, and then pass them as arguments to the rm command.

That last example is a pretty good category of problem that xargs solves. I often search through a codebase to find source code that matches a pattern. It’s easy enough to do that with a simple grep (or the search in your preferred editor). But I occasionally want to narrow down the search to a subset of files, and that’s not always easy to do with a single statement.

For example, I might want to search for ā€œFind me everywhere in this codebase that contains the string FOO but narrowed down to files that happen to also contain the string BARā€. That’s easy enough to achieve once you’re comfortable with xargs:

$ grep -lr BAR . | xargs grep FOO
./app/models/human.rb:    puts FOO.inspect

Note: in my day-to-day life, I’m generally using ripgrep, not grep, but I wanted to keep the examples simple by using more standard things. But once you’re using ripgrep, the command gets a bit simpler and faster too:

$ rg -l BAR | xargs rg FOO
app/models/human.rb
22:    puts FOO.inspect

All right, that’s all I got. Have fun.

Rachel

January 15, 2023

This short film is so funny even while it kind of feels like a horror story the entire time.

Kate Berlant and John Early are usually so heightened and wacky that it’s almost disorienting to see them in a slightly natural mode.

You can read more about the true story that inspired this on Vulture.

Also: this reminds me I need to see Kate Berlant’s new show, Kate while I still can…

Miley Cyrus - Flowers

January 15, 2023

This new Miley Cyrus song is a bop:

I feel like Cyrus is pretty underrated. See also this recent performance:

How to reduce recruiter spam

January 5, 2023

If you work in the tech industry, you may get a lot of emails from recruiters, and maybe even the occasional cold call.

In times of abundance, we like to complain about this. It can be genuinely annoying to be spammed, even if it is a bit of a humble brag to complain that so many people want to hire you.

So, how to reduce the amount you get?

Let me back up a little and give some context for this story… Back in November 2013, I registered hardscrabble.net, signed up for an email account on Fastmail, and promptly tried to retire the gmail account I had been using since 2007. I was bought in to the idea that you need to own your own domain, and avoid being locked in to services that may not stick around.1

But I had a problem… even if I want to stop using my gmail account, the rest of the world is still going to keep emailing me at that address, because it’s still in their address books. I was prepared to take on the tedious task of updating all of my own accounts on various services to use my fancy new custom address, but I had no way to update the address books of my aunts and cousins.

Over the years, emails to my old address mostly dried up. But I still got the occasional recruiter email there. This surprised me, because my new address was listed publicly in several places (linkedin, this blog, my github) and my gmail wasn’t listed publicy anywhere I was aware of.

So, several months ago, I started replying to any recruiter emails sent to my gmail with something along these lines:

Hi Molly,

I’m not currently interested in exploring new job opportunities, but I’d love to ask you a favor if you have a moment…

Where did you get this email address? I’ve been trying to retire it for a decade (I list a different email address on LinkedIn for example), but people continue to email it, so I assume it’s still listed somewhere. Or is it in some database? If so, would you mind telling me what service you’re using to source candidates? I don’t mind being in a database but I’d love to perhaps update my info there…

I’ve been curious about this for years and if you can help me resolve the mystery I would be in your debt and might even be able to refer some candidates who are actually on the market šŸ˜‰

All the best, Max

I was basically lying about referring them candidates but I felt like I needed to offer a back scratch if I’m going to ask for one. And it worked! These recruiters were super nice, and were happy to answer the question, which I really appreciated.

Here’s an example reply:

Hahaha, thank you for the response Max and this is probably the most fun I’ve had with ā€œnot interestedā€ emails!

We use GEM in addition to LinkedIn for our recruiting efforts - it is relatively newer compared to LinkedIn but I think it’s been a pretty popular software since a few years ago and to my knowledge a lot of companies are utilizing it. I managed to remove this particular email address from our database so you shouldn’t receive any outreach from my team (unless we switch for a brand new software maybe?) Unfortunately, I’m not quite sure where GEM pulled this email from, but it looks like they’ve listed a few more: redacted. Let me know if you’d like to remove all of them - happy to do so as well!

Here’s what I learned: there are a whole bunch of companies out there which are scraping the internet for data and then selling that data to companies. And they all offer a flow to opt out2.

Here are some examples:

And then in the interest of naming and shaming, here are some services recruiters cited which do not seem to have a publicly-discoverable page to opt out of having your data sold:

Opting out on those pages reduced the amount of recruiter spam I’ve received.

And then here’s the punchline to this blog post: I got laid off yesterday and now I need to start thinking about a new job search, and my inbox is crickets. Whoops!

  1. Almost a decade later, gmail is still holding pretty strong I have to admit… 

  2. Which I assume they are legally required to do? Not sure… 

Steam Locomotive

December 8, 2022

A few weeks ago, Facebook1 published a blog post called Sapling: Source control that’s user-friendly and scalable that I read with great interest.

Source control is an interest of mine. It’s this absolutely critical tool in our software lives, but it’s got this ruthless learning curve that leads to most people carving out a small handful of commands they feel confident using, and never straying outside of those. People keep trying to figure out ways to make it easier to use – I’m thinking of things like Tower, GitHub Desktop, and Visual Studio Code’s Source Control – and they’re actually pretty great. I’m particularly impressed with the Visual Studio Code one, because it embraces the exact same terminology that you find when using the git command line interface2, but it organizes that information and presents it all in very usable ways (the conflict resolution tooling in particular is night and day better than anything I’ve used before).

Plus, it’s always fun to hear about people dealing with devex scaling issues. They’ve got so many people over there writing so much code that they have to have huge internal teams to make tools for the rest of them to use just to keep up. That’s nuts. Godspeed to ā€˜em.

Enter sapling, their new CLI tool, which seems to be a new client for git repositories. That is, you can bring your own git repository, but instead of using the git CLI or any of the graphic clients I mentioned above, you use their alternative CLI, which you invoke on the command line with sl.

Here’s the thing… ā€œsaplingā€ is a great project name3 and sl is a great name for a command. There’s only one problem, and it’s a showstopper: sl is taken!

Here’s what I see when I run sl in my terminal:

output of sl, an ASCII train crossing the screen

I’ll go into why this is very important, and in fact the remainder of this blog post is entirely about how much I love this command and what it means to me, so I apologize if you want to learn more about sapling. I literally cannot even try it, because I cannot install it, because of this naming collision. So you’re on your own. I hope it’s great.

Here’s the output of man sl, which has a lot to unpack:

SL(1)			     General Commands Manual			   SL(1)



NAME
       sl - cure your bad habit of mistyping

SYNOPSIS
       sl [ -alFc ]

DESCRIPTION
       sl is a highly advanced animation program for curing your bad habit of
       mistyping.

       -a     An accident is occurring. People cry for help.

       -l     Little version

       -F     It flies like the galaxy express 999.

       -c     C51 appears instead of D51.

SEE ALSO
       ls(1)

BUGS
       It sometimes lists directory contents.

AUTHOR
       Toyoda Masashi (mtoyoda@acm.org)



				 March 31, 2014 			   SL(1)

First of all.. let’s check out some of these delightful alternate modes.

Here’s the output of sl -a:

output of sl -a, an ASCII train crossing the screen with people crying for help

You’ll notice, as promised, that people cry for help.

There are a few other fun flags, but I’ll leave exploring those as an exercise for the reader. One tip: try combining flags.

Some fun facts about sl:

  1. Looking at the source code, it seems this program dates back to 1993, when this blog’s author was five years old.
  2. sl, of course, is short for steam locomotive.
  3. The author, Masashi Toyoda, is currently a professor at The University of Tokyo, but he still highlights his true claim to fame – sl, of course – on his homepage
  4. It takes about six seconds to run
  5. If you try to kill it by pressing ctrl c to send an interrupt signal, it just ignores you. This is very annoying in a peevish way that I find charming. You will sit through the animation.

The man page makes it sound like the motivation for this was to help break a habit of misstyping ls as sl. If, each time you make that mistake, you’re forced to watch a 6 second animation that you cannot skip… perhaps that will help you break that habit.

This is kind of like the command line version of Mavala Stop Deterrent Nail Polish Treatment, a product I’ve personally found very helpful. You may have heard of it. It’s a clear nail polish you can put on which tastes terrible. If you find yourself idly biting your nails, it will help you stop. It’s incredibly helpful as a habit breaker.

I personally do not misstype ls as sl very often. In fact I often will idly type sl on purpose and watch the train animation when I’m thinking thru a problem.

But I have found it useful to help break some other habits. I’ll give one more example.

One command line habit I have is running hub browse to open the current repo on github.com. It’s great. It’s context dependent, so for example if you’re currently on a branch, it will open that branch on github.com.

But I want to break this habit. A few years ago, GitHub introduced an official CLI called gh. I installed that too, and it’s also pretty good, and in fact it also has a command called gh browse. Based on this doc comparing hub and gh, I would like to stop using hub entirely and just use gh.

There’s only two problems:

  1. gh browse does not seem to be as clever as hub browse; it just loads the repo home page, no matter what branch you’re on
  2. my damn muscle memory continues to type hub browse no matter what I do

So… where does sl come in?

First step: uninstall hub with brew uninstall hub.

It’s gone now. Nice. Now when I type hub browse, I see this:

$ hub
zsh: command not found: hub

That’s accurate enough, but it’s not sufficiently punitive to be effective.

Second step: bring in the steam locomotive

I added this alias to my shell configuration:

alias 'hub'='sl -a'

Now, whenever I type hub browse… I get the train.

Third step: make gh browse context dependent.

Running man gh-browse, I see that gh browse actually has some handy-looking options:

OPTIONS
       -b, --branch <string>
	      Select another branch by passing in the branch name


       -c, --commit
	      Open the last commit

(plus some others, not pictured).

Which is to say that you can run gh browse --branch asdf to open github to branch asdf. Or you can run gh browse --commit to browse directly to the last commit, wherever you’re currently checked out.

So, a script like this, built on top of the gh CLI, kinda-sorta recreates the behavior of hub browse:

#!/usr/bin/env sh

branch="$(git symbolic-ref --short HEAD 2>/dev/null)"

if [ $? -eq 0 ]; then
  gh browse --branch="$branch"
else
  gh browse --commit
fi

So, now we can save that file as git-browse, and put it somewhere on our $PATH.

Now I can type simply git browse and git will find that git-browse script and invoke it. Under the hood, it uses the gh command. And if I ever forget, and type hub browse, I get to look at a train and contemplate my choices.

  1. I guess I should say ā€œMetaā€ but idcĀ 

  2. Why, in GitHub Desktop, do you ā€œpublishā€ your branch instead of ā€œpushā€ it? I can see the argument that it’s more intuitive to a beginner, but it forces them to learn two things instead of one.Ā 

  3. In fact I made a little project called sapling 7 years ago which had nothing to do with git. It was a knock-off of tree another favorite tool of mine, that I made when I was first learning the basics of Rust.Ā