nixfmt-tree: refactor impl to use treefmt.withConfig

Refactor the new `nixfmt-tree` package, to make use of the new
`treefmt.withConfig` wrapper.

Breaking changes:
1. Overriding `settings` will no longer entirely replace all settings,
   instead settings are now merged as modules.
2. Adding the package to a nix shell will no longer make runtime inputs
   (such as `nixfmt`) available on the PATH, only the wrapped `treefmt`
   will be added to the shell's PATH.

Non-breaking changes:
1. Introduced `runtimeInputs`, for consistency with `treefmt.withConfig`
   and other parts of nixpkgs, such as `writeShellApplication`.
2. Introduced `nixfmtPackage` to allow specifying a different nixfmt
   package, without having to know to override `nixfmt-rfc-style`.
3. Deprecated `runtimePackages` with a warning. Use the new args
   instead.
This commit is contained in:
Matt Sturgeon
2025-04-01 12:49:00 +01:00
parent a432520986
commit a1bf64c7a5
+71 -34
View File
@@ -1,45 +1,61 @@
{
lib,
runCommand,
buildEnv,
makeWrapper,
writers,
treefmt,
nixfmt-rfc-style,
nixfmt-tree,
settings ? {
# The default is warn, which would be too annoying for people who just care about Nix
on-unmatched = "info";
# Assumes the user is using Git, fails if it's not
tree-root-file = ".git/index";
settings ? { },
runtimeInputs ? [ ],
nixfmtPackage ? nixfmt-rfc-style,
formatter.nixfmt = {
command = "nixfmt";
includes = [ "*.nix" ];
};
},
runtimePackages ? [
nixfmt-rfc-style
],
}:
buildEnv {
name = "nixfmt-tree";
# NOTE: `runtimePackages` is deprecated. Use `nixfmtPackage` and/or `runtimeInputs`.
runtimePackages ? [ nixfmtPackage ],
}@args:
let
allRuntimeInputs = runtimePackages ++ runtimeInputs;
# Allows this derivation to be used as a shell providing both treefmt and nixfmt
paths = [ treefmt ] ++ runtimePackages;
pathsToLink = [ "/bin" ];
# Tests whether a package's main program is nixfmt.
isNixfmt = p: p.meta.mainProgram or null == "nixfmt";
nativeBuildInputs = [
makeWrapper
];
treefmtWithConfig = treefmt.withConfig {
name = "nixfmt-tree";
postBuild = ''
wrapProgram $out/bin/treefmt \
--prefix PATH : $out/bin \
--add-flags "--config-file ${writers.writeTOML "treefmt.toml" settings}"
'';
settings = [
# Default settings
{
_file = ./package.nix;
# Log level for files treefmt won't format
# The default is warn, which would be too annoying for people who just care about Nix
on-unmatched = lib.mkOptionDefault "info";
# Assume the tree is a Git repository, will fail if it's not
tree-root-file = lib.mkOptionDefault ".git/index";
# NOTE: The `mkIf` condition should not be needed once `runtimePackages` is removed.
formatter.nixfmt = lib.mkIf (lib.any isNixfmt allRuntimeInputs) {
command = "nixfmt";
includes = [ "*.nix" ];
};
}
# User supplied settings
{
_file = "<nixfmt-tree args>";
imports = lib.toList settings;
}
];
runtimeInputs =
# Handle `runtimePackages` deprecation (added 2025-04-01)
lib.warnIf (args ? runtimePackages) ''
nixfmt-tree: overriding `runtimePackages` is deprecated, use `runtimeInputs` instead.
Note: you do not need to supply a nixfmt package when using `runtimeInputs`, however you can override `nixfmtPackage` to a different nixfmt package.
For additional flexibility, or to configure treefmt without nixfmt, consider using `treefmt.withConfig` instead of `nixfmt-tree`.
'' allRuntimeInputs;
};
in
treefmtWithConfig.overrideAttrs {
meta = {
mainProgram = "treefmt";
description = "Official Nix formatter zero-setup starter using treefmt";
@@ -62,7 +78,7 @@ buildEnv {
```
You can then also use `treefmt` in a pre-commit/pre-push [Git hook](https://git-scm.com/docs/githooks)
and `nixfmt` with your editors format-on-save feature.
and with your editor's format-on-save feature.
- To check formatting in CI, run the following in a checkout of your Git repository:
```
@@ -71,9 +87,30 @@ buildEnv {
For more flexibility, you can customise this package using
```nix
nixfmt-tree.override {
settings = { /* treefmt config */ };
runtimePackages = [ /* List any formatters here */ ];
pkgs.nixfmt-tree.override {
settings = { /* additional treefmt config */ };
runtimeInputs = [ /* additional formatter packages */ ];
}
```
You can achieve similar results by manually configuring `treefmt`:
```nix
pkgs.treefmt.withConfig {
runtimeInputs = [ pkgs.nixfmt-rfc-style ];
settings = {
# Log level for files treefmt won't format
on-unmatched = "info";
# Assume the tree is a Git repository, will fail if it's not
tree-root-file = ".git/index";
# Configure nixfmt for .nix files
formatter.nixfmt = {
command = "nixfmt";
includes = [ "*.nix" ];
};
};
}
```