TLDR: Helped my father move. Then I shaved all the yaks. Fur everywhere. Very messy.
Because of the way holidays at ActiveState work, it’s very economical in terms of vacation days to take the last two weeks of the year off (Christmas and New year’s weeks). I had a fair bit of vacation left, so I decided to take the first week of the new year off as well, for a total of three weeks of vacation.
So what did I do with all that time?
Answer: Helped me father move, then wrote a lot of Rust and some Perl.
Helping My Father Move
My mother died at the beginning of September. She and my father had been living in Florida, but it didn’t make sense for my father to continue living there alone. My wife and I had been discussing moving to a new house in Minneapolis for a while, so my father suggested we find a place where we could all live. We were looking for either a duplex or a property with an ADU1. We found a perfect odd duplex2 very quickly. The sale closed on December 16. My father’s stuff from Florida arrived a few days later, and he moved in to his part of the duplex.
Unfortunately, because of COVID, we didn’t go down to Florida to help him prepare for the move. While he did sort through some of his stuff, his sorting could’ve been more aggressive, as he was moving from a large house with two people to a much smaller space with one person. The upshot is that he moved a ridiculous amount of stuff here, far more than could ever fit in his space. So we spent many hours going through it.
We still have a ridiculous number of boxes of stuff to give away in the main part of the house, along with an endless pile of cardboard and packing paper, but his unit in the duplex is looking great.
This made me even more enthusiastic about getting rid of tons of stuff before my wife and I move, which will happen later this year, after some renovations to our part of the duplex.
My Local COVID Tracker
I’ve posted about this a couple times already. I made an update to track more counties, as well as to add a graph showing the seven-day new case average per 10,000 people.
The new graph by population made it clear that the counties near me were doing worse than the state as a whole. The original graph, showing just the raw count of new cases, made it look like the state overall was worse than the nearby counties, when in fact I think the opposite is true.
Precious and My Yak Shaving Expedition
Precious is a project is a project I started to create a meta-linter/tidier in Rust. The goal is to replace TidyAll. I’ve written about TidyAll’s issues in the past.
Switching DateTime to use Precious
I’ve used precious
for a
few projects, including itself, but I wanted to try moving a Perl project to it. I picked
DateTime for no particular reason, other than that
it’s something I’ve worked on for many years.
This is what led me down the yak shaving rabbit hole, to mix some metaphors.
First, I found some bugs with precious
and made
a v0.0.7 release of it.
Then when I started working on converting DateTime from TidyAll to precious
, I found several bugs
in omegasort
3, leading to a
new release of that as well.
As I worked on switching DateTime to use precious
, I realized there was a bootstrapping problem.
With TidyAll, I can just specify TidyAll and any needed plugins as develop phase prereqs for the
distribution, making it easy for others to install all the needed tools, like
perltidy,
perlcritic, and TidyAll itself.
But precious
isn’t on CPAN, nor is omegasort
. I did briefly consider going down the whole
Alien route, but quickly discarded that idea. While depending on a
notional Alien::precious
would work fine for my Perl projects, it wouldn’t help for anything
that’s not Perl.
Note that precious
, being a Rust project, produces a single statically linked4 binary. Go
programs like omegasort
are totally static, not even linking libc. This will become more important
later in my yak shaving journey.
Just One Little Installer
So my next thought was to build a simple installer for precious
that could be run using the very
safe “pipe curl
output into an interpreter” strategy. I quickly wrote an installer in Perl that
would live in the precious
repo. I was using
fatpack, which is a great tool for turning Perl
programs into single-file executables, as long as all of its dependencies are pure Perl.
But then I started thinking about omegasort
. Did I want to write a nearly identical program to
live in the omegasort
repo? And then do it again for my next Rust or Go project? Plus there are
lots of other useful tools that fall in this “released as a single binary on GitHub” bucket, like
ripgrep.
Just One(!) Installer
Then I had an idea. What if I wrote one installer for all these things? So I made a little Perl
distribution called App-ugri
, where “ugri” stood for Universal GitHub Release Installer. I
actually finished that before I realized the critical flaw in my plan. Even though I could fatpack
ugri
into a single file so you could pipe curl
into perl
, what about Windows?
Then I remembered why I was creating this installer in the first place. It’s because of languages like Rust and Go that produce a single statically linked executable. The solution was pretty obvious. Write this installer in Rust.
ubi
“UBI” stands for Universal Binary Installer. I liked the pun here more than the original “ugri” name. Of course, by “universal binary installer” I mean it just installs single-file executables from GitHub project releases, so it’s not very universal (yet?).
Since I’d already written this once in Perl, writing a Rust version was mostly pretty easy. The only
wrinkle was that I had to learn a little bit about async programming in Rust, because the GitHub API
client I was using, octocrab
, is async. This was
something I’d been wanting to learn about anyway, so I welcomed the challenge.
There is a usable 0.0.2 release on the GitHub project’s releases page.
Of course, ubi has a bootstrapping problem. What do you install a universal binary installer with?
You curl
a script into sh
, of course5!
That looks like this:
|
|
That should work on Linux and macOS. But I would love some help with creating the equivalent PowerShell script for Windows. I also need to improve the release tooling to provide binaries for more systems.
Installing precious
and omegasort
Once you have ubi
installed, installing these tools is trivial:
|
|
But wait, there’s more yak!
Along the way, I also ended up working on
my dzil
bundle to to make
switching to precious
easier. So now my bundle will:
- Generate a
precious.toml
config file for any project which doesn’t yet have one, as long as there’s notidyall.ini
file either. - Generate an extended test that runs
precious lint --all
and makes sure there are no files that fail the linting checks. - Generate a simple
dev-bin/install-xt-tool.sh
script that installsubi
, then uses that to installprecious
andomegasort
. - Generate a git hook script that uses
precious
, along with agit/setup.pl
script to install that hook for the given repo. - Update the
dist.ini
to always include anauthordep
on the version of the bundle that is being run.
And since I was messing with all this, I added
podchecker
and
podtidy
to my standard precious
config for Perl
projects.
That last bullet point, about updating the dist.ini
file, came out of some issues I found in
trying to get precious tests passing in CI using my
ci-perl-helpers
tooling for Azure Pipelines.
I’ve written about those in the past as well. I ended up
making some improvements to the helpers,
so now they’ll automatically run the dev-bin/install-xt-tools.sh
script before running extended
tests.
And when they’re building a tarball for any Perl distro where the name starts with “Dist-Zilla”,
they make sure to include the git checkout’s lib
directory in @INC
when running dzil build
. I
assume that if you’re testing a dzil
plugin or plugin bundle in CI, then you want to use said
plugin or bundle when generating the tarball for said plugin or bundle6.
The results of all of this can be seen in
my PR to switch DateTime to precious
.
Other Random Bits
- I tweaked a PR for the CLDR project (Common Locale Data Repository) to fix a typo in one language’s datetime info.
- I submitted a PR to octocrab to update its
dependencies so I could update the same deps in
ubi
. - I made a new release of DateTime-Locale to add some more documentation.
- I almost started rewriting omegasort in Rust (just because I like it better than Go), but I managed to restrain myself. I might get back to this at some point, but I’m glad I worked on these other projects for now.
- I wrote this blog post.
Putting the Yaks to Bed
I wrapped this all up yesterday, more or less. I return to work on Monday, so my timing was pretty good.
Accessory Dwelling Unit - think of an apartment built over a garage. ↩︎
It’s not a normal duplex. Instead of a house split into two pieces, it’s an older three story house, built in 1915, with a newer, much smaller two story “apartment” attached to the back. ↩︎
Because TidyAll is in Perl, sorting plugins for it are just simple Perl classes. But
precious
only invokes other executables, so I realized I needed a sorting tool soon after starting onprecious
. I wanted to write the sorting tool in Rust but at the time I started, Rust had no support for Unicode collation, so I wrote it in Go instead. ↩︎Except for libc. ↩︎
But it can install itself if you already have it installed. ↩︎
Does that sentence make any sense? I’ve lost track. There’s too much yak fur in here! ↩︎