Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improving flake formatting experience #273

Open
GaetanLepage opened this issue Dec 23, 2024 · 4 comments
Open

Improving flake formatting experience #273

GaetanLepage opened this issue Dec 23, 2024 · 4 comments

Comments

@GaetanLepage
Copy link

GaetanLepage commented Dec 23, 2024

In order to have your flake formatted with nixfmt-rfc-style, one has two options:

  1. Setting formatter = pkgs.nixfmt-rfc-style;. This solution is concise (ignoring the fact that the name "nixfmt-rfc-style" is not really intuitive compared to simply "nixfmt").
    However, this is not expected to be supported for long as: Passing directories or non-Nix files (such as ".") is deprecated and will be unsupported soon, please use https://treefmt.com/ instead, e.g. via https://github.com/numtide/treefmt-nix.
  2. Using treefmt-nix. While it is for sure a great, very flexible and powerful tool, it is quite overkilled if you simply want to format a small nix-only code base. It's major con is having to add both several lines of code and an extra dependency, simply to achieve what the first solution is doing.

I think it should be great to support the existing formatter = pkgs.nixfmt[-rfc-style]; syntax as it gives a very efficient and user-friendly way to format a flake while keeping it lean code and input wise.

In the long term, I could see the benefit of further "officializing" the nixfmt formatter and having a format = true; flag to automatically format the flake. This would have to be thought more.

cc @infinisil

@MattSturgeon
Copy link

That one is kinda awkward, since it was already decided that recursively finding nix files to be formatted is a non-trivial issue that is kinda out-of-scope for a tool that just wants to be able to format a nix file.

IIRC, the main complexities come from ignoring .git and respecting .gitignore.

Maybe this could be worked around by renaming pkgs.nixfmt-rfc-style something like pkgs.nixfmt-unwrapped and having a wrapper package that handles the logic required to format a directory recursively?

The wrapper package could of course use an existing lib/tool to implement that. And treefmt users should probably be able to use either the wrapped or unwrapped package.

@eclairevoyant
Copy link

It seems quite trivial, actually; this decision comes off more like it's just intentionally making it harder to use flakes. Using a random third-party tool just to be able to use the official formatter with official nix is a nonstarter IMO. And there's some irony here that the nix docs still give the example of setting formatter.<system> to nixfmt... plus if we're talking about scope, nix even having a fmt subcommand is a strange scope creep, though it's certainly offtopic here to go further into that rabbithole.

In any case, as amusing as whining about nix* community dysfunction is, since I'd rather just get things done, fd is my tool of choice for this sort of thing:

fd -t f -e nix -x nixfmt '{}'

I specifically chose fd over find, as fd ignores hidden files/dirs and respects .gitignore the way one would hope nix fmt to operate. Also note this only includes regular files. And I do expect fd to be better-maintained, better-documented, and stabler in behaviour and API than treefmt or other third-party nix ecosystem tools.

To be able to effectively use nix fmt rather than hardcoding the formatter in the command, of course, one can substitute nixfmt with nix fmt in the command above; alternatively, since I'd rather the search-and-format details be properly encapsulated within the formatter package, I prefer to use a wrapper script around nixfmt via writeShellApplication:

  formatter.x86_64-linux =
    let
      pkgs = nixpkgs.legacyPackages.x86_64-linux;
    in
    pkgs.writeShellApplication {
      name = "nixfmt-wrapper";

      runtimeInputs = [
        pkgs.fd
        pkgs.nixfmt-rfc-style
      ];

      text = ''
        fd "$@" -t f -e nix -x nixfmt '{}'
      '';
    };

The args that are passed (to the formatter package's executable) appear to be the path(s) that are (im/ex)plicitly passed to nix fmt; if no args are explicitly passed, the CWD is implicitly passed. (Arguably it should be the flake enclosing the CWD, since that's the implicit flake that is passed to any other nix3 command by default, but...)

@GaetanLepage
Copy link
Author

Yes, the observation behind this issue was that is should be dead simple to format a flake the "official way".
It should not require to rely on external tool.
Again, in an ideal world, I would say that running nix fmt should work OOTB on any flake and would run nixfmt on the code base.
Of course, users would still be free to override the formatters flake output (so as to use treefmt-nix, alejandra...).

@eclairevoyant
Copy link

eclairevoyant commented Dec 28, 2024

Sure, I'm not entirely disagreeing that having nixfmt behave differently from the other formatters is surprising; I just wanted to share (with anyone watching this issue) a straightforward workaround that works today and will continue to work even if directory support is removed from nixfmt entirely.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
Status: Todo
Development

No branches or pull requests

3 participants