Skip to the content.

Announcing Stack Lint Extra Deps

by @pbrisbin on December 17, 2021

Freckle is happy to announce a new command-line tool for linting a Stack-based Haskell application. If you make heavy use of extra-deps, this tool may be useful to you.

Context & Motivation

At Freckle, we publish a custom snapshot for use across all our Haskell applications. This brings a minor bit of supply-chain security, but we primarily do it out of convenience. As a team, we no longer manage disparate, app-specific resolvers or extra-deps; we just use the canonical snapshot and assume the same versions of all dependencies when we move from project to project. extra-deps require maintaining (as I’ll describe soon), so centralizing them has been a big boost to efficiency.

There exists a priority order of extra-deps sources:

  1. Using the latest Hackage release
  2. Using any Hackage release
  3. Using the latest git version tag
  4. Using any git version tag
  5. Using the latest git commit
  6. Using any git commit

Whenever we release a new snapshot (roughly every two weeks), we re-evaluate every extra dependency to see if we can now move it up on this list. We used to do this cumbersome series of checks by hand for every dependency: referencing the new resolver’s Stackage page, checking against Hackage, and possibly browsing git tags. With any reasonably-sized list of extra-deps this takes ages.

We built lint-extra-deps to do it for us:

Features

Checks

lint-extra-deps asks the following for each extra dependency and suggests changes depending on the answers:

If it’s a Hackage dependency,

If it’s a Git dependency,

The Git checks are somewhat heuristics-based. We assume the base name of the repository is the package name on Hackage, and we take any tag that parses as a Version to represent a possibly-released version. This may result in false-positives or false-negatives.

Which checks are performed can be changed through the --checks option.

Exclude/Include

lint-extra-deps will operate on the extra-deps or packages key of the input Yaml file. This means it supports stack.yaml or snapshot.yaml use-cases. By default, it processes all dependencies, but you can:

PATTERN is a glob matched against the Hackage package name or the owner/repo portion of a git dependency.

For example,

stack lint-extra-deps --exclude 'freckle/*'

Would skip any git dependencies from our own organization, and

stack lint-extra-deps 'hspec*'

Would check only the handful of Hspec packages we’re using right now.

Exit

By default, lint-extra-deps exits non-zero if suggestions were made, but this can be disabled by passing --no-exit.

Installation

We’re shipping binaries from CI and you can find instructions for installing them in the README, or head right to the Releases.

stack will look for any executables named stack-{subcommand} and support calling them as, well, a sub-command. So with this installed, you can run (e.g.) stack lint-extra-deps --help for complete usage.

At Freckle, we rarely let an annoying and manual task go un-automated. If you are are performing similar extra-deps maintenance for your projects, we hope this tool can get you back some time.

If you would enjoy working on tools like this, or the projects it enables, we’re hiring. And as always, patches welcome.