Unverified Commit e812a706 authored by Janne Heß's avatar Janne Heß Committed by GitHub
Browse files

nixfmt-tree: refactor impl to use `treefmt.withConfig` (#391319)

parents 31c8df71 a1bf64c7
Loading
Loading
Loading
Loading
+75 −38
Original line number Diff line number Diff line
{
  lib,
  runCommand,
  buildEnv,
  makeWrapper,
  writers,
  treefmt,
  nixfmt-rfc-style,
  nixfmt-tree,

  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 = "info";
    # Assumes the user is using Git, fails if it's not
    tree-root-file = ".git/index";
        on-unmatched = lib.mkOptionDefault "info";

    formatter.nixfmt = {
        # 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" ];
        };
  },
  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
      }
      # User supplied settings
      {
        _file = "<nixfmt-tree args>";
        imports = lib.toList settings;
      }
    ];

  postBuild = ''
    wrapProgram $out/bin/treefmt \
      --prefix PATH : $out/bin \
      --add-flags "--config-file ${writers.writeTOML "treefmt.toml" 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" ];
          };
        };
      }
      ```