Statix — Lints and Suggestions for the Nix programming language

Hiya o/,

Statix, is a linter for the Nix programming language, written in Rust with rnix-parser. Here is an excerpt from the readme:

statix check highlights antipatterns in Nix code. statix fix can fix several such occurrences.

It detects around 11 antipatterns at the moment (it can also fix these with statix fix!). The fix subcommand is beautiful in that it is idempotent and can fix all issues in one go.

Feel free to open issues on Github with lint ideas and things you’d like to see! Here is a little screenshot of statix check in action:

18 Likes

Are there plans to add it to nixpkgs?

Also adding making it a pre-commit hook would be great.

4 Likes

@figsoda has already opened a PR here!

Also adding making it a pre-commit hook would be great

Looks neat, thanks for the link. If I remember correctly, nixpkgs-fmt has a similar integration.

1 Like

How well does it work with flakes enforced usage of final: prev: even if at least one isn’t used?

This is neat, but the flake hardcodes Linux. I was able to get it to work on Darwin by adding libiconv to the buildInputs. Is it possible to update it to support Darwin?

It also threw up several errors on my nixos-configs. I’m not sure if that’s just a limitation of the tool, or I’m doing something very weird. They obviously build and activate though. Should I open an issue on GitHub?

[./hosts/x86_64-darwin/claudette/users/reckenrode/home-manager/default.nix] syntax error: unexpected TOKEN_SQUARE_B_OPEN at 448..449, wanted any of [TOKEN_IDENT]
[./common/home-manager.nix] syntax error: error node at 683..691
[./hosts/x86_64-linux/zhloe/kea/default.nix] syntax error: unexpected TOKEN_ASSIGN at 282..317, wanted any of [TOKEN_SEMICOLON]
[./lib/mkHosts.nix] syntax error: unexpected TOKEN_DYNAMIC_START at 612..619, wanted any of [TOKEN_SEMICOLON]
1 Like

Thanks for testing it out on Darwin! I can add Darwin support over the next couple of days.

It also threw up several errors on my nixos-configs. I’m not sure if that’s just a limitation of the tool, or I’m doing something very weird. They obviously build and activate though. Should I open an issue on GitHub?

Most likely a bug with rnix-parser (or atleast, the version of rnix-parser that I am using). Let me give it a go on a more recent version of rnix, and see if the errors persist, if they do, I’ll file issues over on the rnix-parser repo.

3 Likes

Currently does not lint unused function args.

final: prev: even if at least one isn’t used

Interesting, yeah, that is something to keep in mind when writing a lint for this.

4 Likes

Do you think this could be integrated into nixpkgs-hammering?

2 Likes

It could be! I did briefly take a look at nixpkgs-hammering, but it seemed to be focused more on nixpkgs itself, and not general nix antipatterns. In the near future, I am looking to partially evaluate nix code as well (flake inputs and imports), would you say that is within scope of nixpkgs-hammering?

2 Likes

I investigated this a bit, rnix-parser does not support template expressions in paths, introduced in nix 2.4, which not yet released. I’ll try to add support for this over the weekend.

2 Likes

I would say language level issues are in scope of nixpkgs code reviews. Some of those lints in nixpkgs-hammering already are independent of nixpkgs itself. I opened an issue: Incoperate statix? · Issue #124 · jtojnar/nixpkgs-hammering · GitHub

4 Likes

Great project!

I was wondering if there was a more idiomatic way of ignoring entire directories other than -i \*directory\*.
Just ./directory/ didn’t work

I was wondering if there was a more idiomatic way of ignoring entire directories

Yeah I found this a bit un-intuitive as well. I have opened an issue to track progress on fixing this.

1 Like

@nerdypepper
Thanks for your work on statix. I rly like the usability of it compared to other linters!

Apologies if this is a bit of beginner question, I still feel new to the nixos ecosystem. During my learning I stumbled over Best practices — nix.dev documentation and they make intuitive sense to me.
Are there any plans of including these checks? It’s non-trivial to make the descriptions to statixs checks.

1 Like

I absolutely agree with all of the points on that page. We already support the unquoted URLs lint, and shouldn’t be too hard to add the rest as well.

I suspect that existing nix code makes good use of with and rec, and a refactor might be tedious, those lints might be better off as opt-in.

@don.dfh @nerdypepper That specific list anti-patterns is not entirely uncontroversial though. Since we (@domenkozar @lucperkins) want to make nix.dev the official hub for Nix ecosystem documentation, we will eventually have to break that down to what Nix experts can agree on to be best practice. So, don’t take it too seriously for now. We can pick up that specific bit of discussion when the Nix logo appears on that web site’s top-left corner.

2 Likes