diff --git a/pkgs/by-name/ni/nixfmt-tree/package.nix b/pkgs/by-name/ni/nixfmt-tree/package.nix index eaf6b2ab05d34..a9478757585a8 100644 --- a/pkgs/by-name/ni/nixfmt-tree/package.nix +++ b/pkgs/by-name/ni/nixfmt-tree/package.nix @@ -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"; - - formatter.nixfmt = { - command = "nixfmt"; - includes = [ "*.nix" ]; - }; - }, - runtimePackages ? [ - nixfmt-rfc-style - ], -}: -buildEnv { - name = "nixfmt-tree"; - - # Allows this derivation to be used as a shell providing both treefmt and nixfmt - paths = [ treefmt ] ++ runtimePackages; - pathsToLink = [ "/bin" ]; - - nativeBuildInputs = [ - makeWrapper - ]; - - postBuild = '' - wrapProgram $out/bin/treefmt \ - --prefix PATH : $out/bin \ - --add-flags "--config-file ${writers.writeTOML "treefmt.toml" settings}" - ''; + settings ? { }, + runtimeInputs ? [ ], + nixfmtPackage ? nixfmt-rfc-style, + + # NOTE: `runtimePackages` is deprecated. Use `nixfmtPackage` and/or `runtimeInputs`. + runtimePackages ? [ nixfmtPackage ], +}@args: +let + allRuntimeInputs = runtimePackages ++ runtimeInputs; + + # Tests whether a package's main program is nixfmt. + isNixfmt = p: p.meta.mainProgram or null == "nixfmt"; + + treefmtWithConfig = treefmt.withConfig { + name = "nixfmt-tree"; + + 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 = ""; + 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" ]; + }; + }; } ```