treefmt
treefmt copied to clipboard
Using treefmt in flake projects
I'd like to minimize the Nix stub required to use treefmt in my projects. Presently, there is a ~40 line nix that provides me nix run .#format
(runs treefmt in project tree) as well a flake check that is built in CI. Could these be upstreamed to treefmt's flake in some way such that I can use it as a flake input, and directly use those app and check without replicating it in every project? Or is there a better approach to this?
Here's the ~40 line Nix:
{ inputs, system, pkgs }:
# Uses https://github.com/numtide/treefmt to provide auto-formating for multiple
# languages. Configure the behaviour in treefmt.toml at project root.
rec {
dependencies = [
pkgs.haskellPackages.cabal-fmt
pkgs.haskellPackages.fourmolu
pkgs.treefmt
];
apps = {
format = {
type = "app";
program = pkgs.writeShellApplication
{
name = "format";
runtimeInputs = dependencies;
text = "treefmt";
} + "/bin/format";
};
};
checks = {
# Checks that the project tree is *already* formatted.
format = pkgs.runCommandLocal "format-check"
{
buildInputs = dependencies;
} ''
set -e
# treefmt maintains a cache at ~/.cache; so use $TMP as home.
# treefmt 0.4 has a --no-cache option, but our nixpkgs has only 0.3
export HOME=$TMP
treefmt -vvv --clear-cache --fail-on-change -C ${inputs.self}
touch $out
'';
};
}
I imagine we want to parameterize this over 'dependencies'.
What if even the config could be declared in Nix.
pkgs.treefmt.withConfig {
formatters.ruby = {
command = ["${pkgs.rubocop}/bin/rubocop"];
includes = [ "*.rb" ];
};
}
@zimbatm That's a great idea ... but, while it would get rid of dependencies
, I'd still have to hand-write apps.format
and checks.format
.
Yup. That shape depends on how the systems get abstracted away.
Nix 2.8 also has a formatters.<system> = <installable>
interface so you could run nix fmt
that then invokes treefmt
, that then invokes the rest :p (not saying it's a great idea, just reporting for now)
I would prefer to see nix fmt
win, seems like the right approach.
IIUC nix fmt
is about formatting *.nix files only, and not other languages?
Unless we make nix fmt
language-agnostic, but that may well involve upstreaming treefmt as the 'backend' to implement it in nixpkgs.
Technically, nix fmt
leaves the filesystem traversal up to the tool. But I don't know if that is an invariant or not. (and also if it's a good idea).
I think we can retire this issue. https://github.com/numtide/treefmt-nix + flake-parts is now a pretty answer to this question, thanks to the help of @srid