2020 was weird. 2021 is off to a weird start. I figured I should bring some sanity back to the world where I'm able. Unfortunately, my sphere of influence barely extends past this page; however, you're here, so you get to receive a slice of stability in the form of this post on implementing pre-commit for my site.
I realize I've missed my personally imposed cadence of an article a month or so. Even the best intentions can get sidelined as we re-prioritize the various facets of our lives. This is natural. So, what happens when you come back to a project after a few months and are dedicated to making progress?
You immediately get distracted with implementing a chore. Funny how that works. How do you counter-act that? You write an article about the chore so you get the benefit of both.
On the topic of 'shoulds'
Now then, before we actually delve into pre-commit
, what in tarnation is a
'shoulds'? These are those things in your career that you know you should do
but often de-prioritize them in favor of other more pressing work.
You know that you should write tests.
You know that you should write more and better documentation.
You know that you should make those small improvements and cleanup for readability while you're working in that file.
The code does what it's supposed to without those changes. You're familiar with working in the codebase so the documentation feels superfluous. The function doesn't actually do much or is so simple that writing a test that is demonstrably more lines of code, more complex, and more work than the thing you're testing is inane.
I've been there, you've been there, we all get it. 'Shoulds' are hard. They're especially challenging because you don't have to. Yet, you should.
What got implemented
Implementing pre-commit
on this project is one of those 'shoulds'. No one else
works in this code base and whatever rules (or lack thereof) I impose are simply
imposed upon myself. Rules in this context are obviously flexible, malleable,
negotiable, and absolutely non-binding.
So how do I impose some good hygiene and best practices on myself in a way that
doesn't allow me to be lazy about it? Well, pre-commit
is certainly a way. If
you didn't check out the link above then here's the gist of what pre-commit
does for me: it automatically runs a variety of checks for simple issues before
submitting my code to the remote.
In order to get checks to run you install pre-commit
and then configure a
.pre-commit-config.yaml
file for your project. Mine looks like so:
repos:
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v3.2.0
hooks:
- id: trailing-whitespace
- id: end-of-file-fixer
- id: check-yaml
- id: check-added-large-files
- repo: https://github.com/pycqa/isort
rev: 5.7.0
hooks:
- id: isort
- repo: https://github.com/psf/black
rev: 20.8b1
hooks:
- id: black
- repo: https://gitlab.com/devopshq/gitlab-ci-linter
rev: v1.0.3
hooks:
- id: gitlab-ci-linter
- repo: https://github.com/igorshubovych/markdownlint-cli
rev: v0.27.1
hooks:
- id: markdownlint
The above is a list of the checks that I want to perform every time I try to
bundle a commit. Nested into the structure you'll see lists of id
which are
the explicit thing that I want to run. All of those perform helpful 'shoulds'
that you might find familiar (e.g. black
for formatting, markdownlint
and
gitlab-ci-linter
to check for malformed/misconfigured issues, etc.). The rest
of that file is all about where to get the thing and what version of it I want
to run.
Once you've got that situated then you install the hooks, like so:
>$ pre-commit install
After that your pre-commit
checks will run automatically each time you try to
make a commit. If you're non-conforming then your commit isn't created and
you get helpful messaging for the things you need to fix first.
If, like me, you want to run it ahead of generating a commit then you can do so manually:
>$ pre-commit run --all-files
Extending the shoulds
I implemented pre-commit
here because it's been on my mind for a while and it
really was something that I should have done from the get-go. It's never too
late to do something you should do and, at least in this instance, it turned
out to be something to pry me back into the practice of working on this project.
The benefits of something like pre-commit
are much more obvious when you have
a team working on a code base. You all know that one engineer who just can't
seem to get their formatter working and 90% of their changes in every pull
request just seem to be a battle over whose formatter should win. Let's stop the
in-fighting and just programmatically define who should win.
Be kind, be patient, be safe.