blueprint icon indicating copy to clipboard operation
blueprint copied to clipboard

formatter.nix & flake checks

Open phaer opened this issue 1 year ago • 6 comments

Is your feature request related to a problem? Please describe.

I love simply adding a formatter nix to invoke treefmt-nix by just adding a treefmt-nix.mkWrapper call as e.g. in nixos-facter.

But I'd like to use the same treefmt-nix configuration as a flake check. As afaik there's no generic interface to tell a given formatter to enter "check mode", I believe we can't add such a feature to blueprint automatically.

Describe the solution you'd like

Not sure, hence this issue: I one thing could be to make the treefmt-nix wrapper expose passthru.check or so which would enable something like checks.format = perSystem.formatter.passthru.check in a quite generic way.

Describe alternatives you've considered

Maybe adapting formatter.nix to be able to return formatter and some checks? This would allow just using treefmt-nix.lib.evalModule and then treefmt.config.build.wrapper, treefmt.config.build.check, ... as needed.

Additional context

The former would of course affect treefmt-nix, happy to create a PR there, just wanted to collect feedback here as i ran into this with blueprint specifically

phaer avatar Aug 01 '24 11:08 phaer

This could be solved by having treefmt-nix add the check to the wrapper's meta.tests. Then blueprint will pick it up like any other package's meta.tests.

zimbatm avatar Jan 24 '25 15:01 zimbatm

Let's get this done 🙌

Such a great QOL improvement!

multivac61 avatar Feb 28 '25 13:02 multivac61

I've been trying to do this manually on a project of mine packages/formatter.nix

{
  flake,
  inputs,
  pkgs,
  ...
}:
let
  treefmt = {
    _file = __curPos.file;
    projectRootFile = "flake.nix";

    programs.nixpkgs-fmt.enable = true;
    programs.deadnix.enable = true;
    programs.statix.enable = true;
    programs.prettier.enable = true;
    programs.clang-format.enable = true;
    programs.shellcheck.enable = true;
    programs.shfmt.enable = true;
    programs.ruff.format = true;
    programs.ruff.check = true;
    programs.actionlint.enable = true;

    settings.formatter.clang-format.options = [ "-style=file:${flake}/.clang-format" ];

    settings.formatter.prettier.includes = [
      "*.yaml"
      "*.yml"
    ];
  };

  treefmtEval = inputs.treefmt-nix.lib.evalModule pkgs treefmt;
  formatter = treefmtEval.config.build.wrapper;
  check = treefmtEval.config.build.check flake;
in
formatter
// {
  meta = formatter.meta // {
    tests = {
      inherit check;
    };
  };
}

Formatter is registered correctly using nix fmt but the check does not catch e.g. linting errors.

multivac61 avatar Apr 10 '25 13:04 multivac61

genki in 🌐 g in juce_bluetooth on  bluez-dbus [⇣] via △ v3.31.5 via ❄️  impure (nix-shell-env)
❯ nix flake show
git+file:///home/genki/genkiinstruments/juce_bluetooth?ref=refs/heads/bluez-dbus&rev=362ae4342015feafd9b2bf07f710d3e6c2dca4bb
├───__functor: unknown
├───checks
│   ├───aarch64-linux
│   │   ├───devshell-default omitted (use '--all-systems' to show)
│   │   └───pkgs-formatter omitted (use '--all-systems' to show)
│   └───x86_64-linux
│       ├───devshell-default: derivation 'nix-shell'
│       └───pkgs-formatter: derivation 'treefmt'
├───darwinConfigurations: unknown
├───darwinModules: unknown
├───devShells
│   ├───aarch64-linux
│   │   └───default omitted (use '--all-systems' to show)
│   └───x86_64-linux
│       └───default: development environment 'nix-shell'
├───formatter
│   ├───aarch64-linux omitted (use '--all-systems' to show)
│   └───x86_64-linux: package 'treefmt'
├───homeModules: unknown
├───lib: unknown
├───modules: unknown
├───packages
│   ├───aarch64-linux
│   │   └───formatter omitted (use '--all-systems' to show)
│   └───x86_64-linux
│       └───formatter: package 'treefmt'
├───systemConfigs: unknown
└───templates
genki in 🌐 g in juce_bluetooth on  bluez-dbus [⇣] via △ v3.31.5 via ❄️  impure (nix-shell-env)
❯

see code in https://github.com/genkiinstruments/juce_bluetooth/pull/7

multivac61 avatar Apr 10 '25 13:04 multivac61

Leaving this as an example of formatter.nix where both nix fmt and nix flake check work as expected with treefmt-nix 🎉

{
  flake,
  inputs,
  pkgs,
  ...
}:
let
  treefmtEval = inputs.treefmt-nix.lib.evalModule pkgs {
    projectRootFile = "flake.nix";

    programs.deadnix.enable = true;
    programs.nixfmt.enable = true;
    # ... other treefmt-nix config
  };
  formatter = treefmtEval.config.build.wrapper;
in
formatter
// {
  passthru = formatter.passthru // {
    tests = {
      check = treefmtEval.config.build.check flake;
    };
  };
}

Here's an example repo documenting my attempts: https://github.com/multivac61/blueprint-treefmt-nix

multivac61 avatar Apr 20 '25 11:04 multivac61

Personally I think this behaviour should be opt in, maybe just have it as an example somewhere in the repo 🤗

multivac61 avatar Apr 20 '25 11:04 multivac61