Lint.nix: simple linting/formatting framework

I’m happy to announce the open-sourcing of lint.nix, a (very) simple formatting/linting framework that we’ve been using at work. There’s not much to it, but we’ve been very happy with it as a quick way of setting up linting and formatting on our projects.

6 Likes

You know GitHub - numtide/treefmt-nix: treefmt nix configuration ?

1 Like

I do. I haven’t actually used it (it didn’t exist yet when we wrote the initial version of lint.nix 3+ years ago) so I can’t speak from experience or tell you in what cases you should pick one or the other, but they obviously sit at very different points in the design space.

Lint.nix is a little over 100 loc, and obviously Nix-only. It manages to do a lot with a little, but it’s also not really competing in terms of scope or features.

3 Likes

One issue I’ve been having with any nix based approach is Time-To-First-Feedback in CI.

People expect this for formatters and linters to be in the seconds range, but with non-optimized nix-based approaches more often than not [in bigger projects] Nix evaluation commonly gets in the way of scoring on that metric.

As to my knowledge, there’s no optimized solution available which would include:

  • Don’t pin anything, defer to whatever is already in CI cache
  • Always use static builds to reduce setup time

If we’re lucky, tackling these UX problems may be the next iteration in this space of Nix tooling.

EDIT: Maybe self.formatter goes some way to mitigate this. I wouldn’t know, I’ve been working with full-blow local environments, so far, which easily can happen to have a side effect that screws up set up time.

2 Likes

When using something like treefmt inside devenv or nix develop you’d only need to evaluate and download once when entering a project. After that it’s just as fast as usual to run the formatters.

For CI it does depend a bit on the method of caching that the CI uses.

1 Like

Smart caching is absolutely part of the solution package. In fact, I wouldn’t rule out persistent eval caching for it’s significant upside, especially when dealing with gnarly IFD.

I may one day try something along the lines of:

  • Have a custom CI image
  • Have that image pin nixpkgs (or for that matter provide any relevant inputs via a built-in predefined registry)
  • Have that image ship a usable eval cache
  • Run X in CI via nix run --override-inputs ... making use of the image-wise pinning

As a Nix power-user, I may be comfortable in setting up and maintaining such a design and setup.

As a layman interested in leveraging Nix technologies, my current thinking is that an ecosystem tool such as treefmt could optionally handle command resolution in the presence of a detected nix command via heuristics.