Or, how i learned to love the linter and eat my vegetables.

tl;dr; fix your code as you go, and enforce it across the team in CI

Have you ever experienced a code base with almost no technical debt? A codebase with full test coverage? Neither have I. This is the sort of nirvana that we see people talk about at conferences (or rather YouTube clips therefrom). Yet, for the large majority of us, it just never seems to materialise. All the brownfield projects, well they are dirty dirty with spotty tests and terrible lint per definition. All the greenfield projects, well they quickly devolve into the same.

Some teams fight with their PMs and stakeholders and propose that you set aside a full sprint to clean up code, fix your tests and refactor when needed. Yet, it never seems to be enough. It’s simply not feasible to set aside time to fix things because the relative cost will seem too high when competing with other business features.

The thing is, the benefits of cleaning up your code are incremental, so why shouldn’t our efforts be too?

Other teams embrace this incrementality and claim to live by the boy scout principle. “Leave the code nicer than you found it”. Great in theory, but how does that actually work in practice? At the end of the day most of us will just ship our feature, make the PR and move on: “I’ll fix those tests later”.

Poor code quality isn’t a bug per se, but it does slow the velocity of your project long term. Consistent indentation, testing unhappy paths, and code warnings, all slow you down. I call these tasks vegetables, because they’re boring and nobody likes them, but at the end of the day we all know that they are good for us. The boy scouts are right; we should leave things nicer than we found them, but we have to force people to do it.

Make a soup of it all

Fixing vegetables is as integral to the cost of a feature as ensuring that all the other tests still pass. Sit down with your team and agree that yes, we will all pull together and fix something on every PR. Then enforce it in CI.

In my experience, each PR in your project will take 5 to 15 minutes longer to do if you fix a veggie along with that feature or bug. At 1000 PRs per year, that’s 250 hours spent improving your codebase. Yet you’ve probably saved more than that by increasing velocity because of all those extra bugs your new sexy tests caught.

Not just in theory, in practice too

To help you get started, I have put together a small tool, Eat Your Vegetables.

Use EYV in conjunction with your current linters/static analysis/coverage tools. Dial them up to maximum enforcement, and add all files that error or warn into the ignore file. Then configure and run EYV as part of your CI. EYV will ensure that the list of ignored files shrink with every commit on your master branch. If not, well you’ll get a snarky message and you won’t be allowed to merge.

Check it out here: www.github.com/cfeckardt/eat_your_vegetables

At the time of writing and version 0.1.1, there is only support for Rubocop and Simplecov. But it’ll only take you ten minutes to add support for your favourite linter/coverage tool, and I’ve put together a short how to as well (it’s in the README). If your favourite tool is missing, feel free to open an issue and I’ll try to add it.

Moving further

Code quality does not just extend to linters and tools. Each of us knows of some part of our code base that desperately needs a refactor. Make a .refactorcandidates file that lists the worst files in your project. Then let EYV enforce that too.

Happy coding!