treefmt icon indicating copy to clipboard operation
treefmt copied to clipboard

add treefmt.withConfig

Open zimbatm opened this issue 2 years ago • 14 comments

This is useful if you want to configure treefmt with nix, and precisely pass all the commands from nixpkgs.

zimbatm avatar May 20 '22 14:05 zimbatm

cf https://github.com/numtide/treefmt/issues/165#issuecomment-1124036328

srid avatar May 29 '22 13:05 srid

@zimbatm What do you think of exposing a flakeModule (a la https://github.com/cachix/pre-commit-hooks.nix/pull/130) so that projects that already use flake-parts can use this directly, thus resolving #165?

srid avatar May 29 '22 13:05 srid

Sounds good, the flake module probably can call treefmt.withConfig with its resulting schema at the end.

zimbatm avatar May 30 '22 08:05 zimbatm

Sounds good, the flake module probably can call treefmt.withConfig with its resulting schema at the end.

Great; I'd be happy to test it out here:

https://github.com/srid/haskell-template/blob/6c9e2eb0870b108731df87cdcbb016c064e55041/flake.nix#L19-L25

srid avatar May 30 '22 13:05 srid

@srid ok this is ready if you want to give it a try

zimbatm avatar Jun 07 '22 16:06 zimbatm

@zimbatm Trying it out on haskell-template,

diff --git a/flake.nix b/flake.nix
index 9918a57..684242e 100644
--- a/flake.nix
+++ b/flake.nix
@@ -5,22 +5,23 @@
     flake-parts.url = "github:hercules-ci/flake-parts";
     flake-parts.inputs.nixpkgs.follows = "nixpkgs";
     haskell-flake.url = "github:srid/haskell-flake";
+    treefmt.url = "github:numtide/treefmt/withConfig";
+    treefmt.flake = false;
   };
 
-  outputs = { self, nixpkgs, flake-parts, haskell-flake, ... }:
+  outputs = inputs@{ self, nixpkgs, flake-parts, haskell-flake, treefmt, ... }:
     flake-parts.lib.mkFlake { inherit self; } {
       systems = nixpkgs.lib.systems.flakeExposed;
       imports = [
         haskell-flake.flakeModule
       ];
-      perSystem = { self', pkgs, ... }: {
+      perSystem = { self', system, pkgs, ... }: {
         haskellProjects.default = {
           root = ./.;
           buildTools = hp: {
-            # TODO: Use https://github.com/numtide/treefmt/pull/169
             inherit (pkgs)
-              treefmt
               nixpkgs-fmt;
+            treefmt = (import treefmt { inherit system; nixpkgs = pkgs; }).treefmt.withConfig (pkgs.lib.importTOML ./treefmt.toml);
             inherit (hp)
               cabal-fmt
               fourmolu;

I see:

srid on now haskell-template on  master [!] via λ 9.0.2 via ❄️  impure (ghc-shell-for-haskell-template-0.1.0.0) 
❯ more $(which treefmt)
#!/nix/store/14lypyys4gfcl982rjddxa6jg7msqz9q-bash-5.1-p16/bin/bash
exec /nix/store/d88p6rcrpp83ir7i6lasljf871j34g25-treefmt/bin/treefmt --config-file /nix/store/vfblhmhr809df21cvcnh7mdwpqn0nv9w-treefmt.toml "$@"


srid on now haskell-template on  master [!] via λ 9.0.2 via ❄️  impure (ghc-shell-for-haskell-template-0.1.0.0) 
❯ treefmt
[ERR]: If --config-file is set, --tree-root must also be set

I wanted to see how importTOML behaved before switching to config defined entirely in Nix, but as you can see it looks like I need this PRJ_ROOT env var and pass it via --tree-root, which in turn would require direnv or devshell. Therefore, it seems to me that treefmt.withConfig as it is implemented currently wouldn't work with projects that use neither direnv nor devshell.

EDIT: I suppose we could add PRJ_ROOT to shellHook, but that would still add 'low-level' nix to flake.nix.

srid avatar Jun 11 '22 00:06 srid

agreed. And since the absolute path to the project root would vary from machine to machine, I don't have a really good solution for it. Unless maybe the function also takes a command that points to the project root, like git rev-parse --show-toplevel

zimbatm avatar Jun 15 '22 13:06 zimbatm

What if we had a wrapper script to determine the project root by traversing until a parent directory with a flake.nix in it? It does assume that the project has no sub-flakes in it.

srid avatar Aug 17 '22 18:08 srid

What if we had a wrapper script to determine the project root by traversing until a parent directory with a flake.nix in it? It does assume that the project has no sub-flakes in it.

We can refine this idea to avoid the sub-flake assumption as follows:

formatter = pkgs.treefmt.withConfig (nixpkgs.lib.importTOML ./treefmt.toml) { projectRootFile = "flake.nix" };

Basically, this tells the wrapper script to cd ../. until the projectRootFile can be located. If the project has sub-flakes, the user can set it to an alternative file, like { projectRootFile = "cabal.project"; }.

@zimbatm If we can get this feature merged, it would be useful in https://github.com/srid/treefmt-flake/issues/1. Ultimately, I imagine that treemfmt-flake can be upstreamed to the flake.nix of this repo.

srid avatar Aug 17 '22 22:08 srid

yeah, that makes sense. Do you have the time to finish this PR so it takes pkgs.treefmt.withConfig { config = ...; projectRootFile = "..."; }, all of this gets passed to the module system, and it outputs the wrapper?

zimbatm avatar Aug 18 '22 08:08 zimbatm

@zimbatm Let me know what you think: https://github.com/numtide/treefmt/pull/177

srid avatar Aug 23 '22 16:08 srid

ok, I think this is ready now. Any last words/feedback?

zimbatm avatar Aug 23 '22 17:08 zimbatm

ok, I think this is ready now. Any last words/feedback?

I've tested it to work after applying #178

Looks good to merge. I'd only suggest making wrapper.projectRootFile = "flake.nix"; the default so the user doesn't have to specify it explicitly on every project using flakes (but without a sub-flake, as is usually the case).

srid avatar Aug 23 '22 19:08 srid

Rebased. It looks like flake.parts doesn't support the formatter option yet. I will give it another shot next week.

zimbatm avatar Aug 24 '22 10:08 zimbatm

Blocked on https://github.com/hercules-ci/flake-parts/pull/56

zimbatm avatar Sep 19 '22 15:09 zimbatm

ok, I think this is ready

zimbatm avatar Sep 21 '22 15:09 zimbatm

@zimbatm Will this (withConfig) be upstreamed to nixpkgs at some point?

srid avatar Sep 21 '22 18:09 srid

I'm unsure about the policy regarding nix modules in the pkgs/ tree. Are there any precedents?

zimbatm avatar Sep 21 '22 19:09 zimbatm

I have seen passthru used by certain packages, eg: https://github.com/NixOS/nixpkgs/blob/45b92369d6fafcf9e462789e98fbc735f23b5f64/nixos/modules/services/networking/stubby.nix#L31

srid avatar Sep 21 '22 21:09 srid

that's not quite the same, plus it's using IFD :-D

With @Mic92 we discussed moving this to another repo, so all the module systems could live separate from the code, and include pre-made samples for the various programs.

zimbatm avatar Sep 23 '22 08:09 zimbatm

Now live at https://github.com/numtide/treefmt-nix . Looking for feedback!

zimbatm avatar Sep 23 '22 11:09 zimbatm

Looking for feedback!

Sure: https://github.com/numtide/treefmt-nix/issues/2

srid avatar Sep 23 '22 17:09 srid