diff --git a/pkgs/by-name/tr/treefmt/build-config.nix b/pkgs/by-name/tr/treefmt/build-config.nix new file mode 100644 index 0000000000000..65fe7ca8f0890 --- /dev/null +++ b/pkgs/by-name/tr/treefmt/build-config.nix @@ -0,0 +1,29 @@ +{ + lib, + formats, +}: +module: +let + settingsFormat = formats.toml { }; + configuration = lib.evalModules { + modules = [ + { + _file = ./build-config.nix; + freeformType = settingsFormat.type; + } + { + # Wrap user's modules with a default file location + _file = ""; + imports = lib.toList module; + } + ]; + }; + settingsFile = settingsFormat.generate "treefmt.toml" configuration.config; +in +settingsFile.overrideAttrs { + passthru = { + format = settingsFormat; + settings = configuration.config; + inherit (configuration) _module options type; + }; +} diff --git a/pkgs/by-name/tr/treefmt/package.nix b/pkgs/by-name/tr/treefmt/package.nix index 0aca91e20c5c9..abaf85a49436d 100644 --- a/pkgs/by-name/tr/treefmt/package.nix +++ b/pkgs/by-name/tr/treefmt/package.nix @@ -1,6 +1,8 @@ { lib, buildGoModule, + callPackage, + callPackages, fetchFromGitHub, }: buildGoModule rec { @@ -27,13 +29,46 @@ buildGoModule rec { "-X github.com/numtide/treefmt/v2/build.Version=v${version}" ]; + passthru = { + /** + Wrap treefmt, configured using structured settings. + + # Type + + ``` + AttrSet -> Derivation + ``` + + # Inputs + + - `name`: `String` (default `"treefmt-configured"`) + - `settings`: `Module` (default `{ }`) + - `runtimeInputs`: `[Derivation]` (default `[ ]`) + */ + withConfig = callPackage ./with-config.nix { }; + + /** + Build a treefmt config file from structured settings. + + # Type + + ``` + Module -> Derivation + ``` + */ + buildConfig = callPackage ./build-config.nix { }; + + tests = callPackages ./tests.nix { }; + }; + meta = { description = "one CLI to format the code tree"; homepage = "https://github.com/numtide/treefmt"; license = lib.licenses.mit; - maintainers = [ - lib.maintainers.brianmcgee - lib.maintainers.zimbatm + maintainers = with lib.maintainers; [ + brianmcgee + MattSturgeon + zimbatm ]; mainProgram = "treefmt"; }; diff --git a/pkgs/by-name/tr/treefmt/tests.nix b/pkgs/by-name/tr/treefmt/tests.nix new file mode 100644 index 0000000000000..763bb14e5656a --- /dev/null +++ b/pkgs/by-name/tr/treefmt/tests.nix @@ -0,0 +1,110 @@ +{ + lib, + runCommand, + testers, + treefmt, + nixfmt-rfc-style, +}: +let + inherit (treefmt) buildConfig withConfig; + + testEqualContents = + args: + testers.testEqualContents ( + args + // lib.optionalAttrs (builtins.isString args.expected) { + expected = builtins.toFile "expected" args.expected; + } + ); + + nixfmtExampleConfig = { + on-unmatched = "info"; + tree-root-file = ".git/index"; + + formatter.nixfmt = { + command = "nixfmt"; + includes = [ "*.nix" ]; + }; + }; + + nixfmtExamplePackage = withConfig { + settings = nixfmtExampleConfig; + runtimeInputs = [ nixfmt-rfc-style ]; + }; +in +{ + buildConfigEmpty = testEqualContents { + assertion = "`buildConfig { }` builds an empty config file"; + actual = buildConfig { }; + expected = ""; + }; + + buildConfigExample = testEqualContents { + assertion = "`buildConfig` builds the example config"; + actual = buildConfig nixfmtExampleConfig; + expected = '' + on-unmatched = "info" + tree-root-file = ".git/index" + [formatter.nixfmt] + command = "nixfmt" + includes = ["*.nix"] + ''; + }; + + buildConfigModules = testEqualContents { + assertion = "`buildConfig` evaluates modules to build a config"; + actual = buildConfig [ + nixfmtExampleConfig + { tree-root-file = lib.mkForce "overridden"; } + ]; + expected = '' + on-unmatched = "info" + tree-root-file = "overridden" + [formatter.nixfmt] + command = "nixfmt" + includes = ["*.nix"] + ''; + }; + + runNixfmtExample = + runCommand "run-nixfmt-example" + { + nativeBuildInputs = [ nixfmtExamplePackage ]; + passAsFile = [ + "input" + "expected" + ]; + input = '' + { + foo="bar"; + attrs={}; + list=[]; + } + ''; + expected = '' + { + foo = "bar"; + attrs = { }; + list = [ ]; + } + ''; + } + '' + export XDG_CACHE_HOME=$(mktemp -d) + # The example config assumes the tree root has a .git/index file + mkdir .git && touch .git/index + + # Copy the input file, then format it using the wrapped treefmt + cp $inputPath input.nix + treefmt + + # Assert that input.nix now matches expected + if diff -u $expectedPath input.nix; then + touch $out + else + echo + echo "treefmt did not format input.nix as expected" + exit 1 + fi + ''; +} diff --git a/pkgs/by-name/tr/treefmt/with-config.nix b/pkgs/by-name/tr/treefmt/with-config.nix new file mode 100644 index 0000000000000..9d3f73c1e6b27 --- /dev/null +++ b/pkgs/by-name/tr/treefmt/with-config.nix @@ -0,0 +1,31 @@ +{ + lib, + runCommand, + treefmt, + makeBinaryWrapper, +}: +{ + name ? "treefmt-with-config", + settings ? { }, + runtimeInputs ? [ ], +}: +runCommand name + { + nativeBuildInputs = [ makeBinaryWrapper ]; + treefmtExe = lib.getExe treefmt; + binPath = lib.makeBinPath runtimeInputs; + configFile = treefmt.buildConfig { + # Wrap user's modules with a default file location + _file = ""; + imports = lib.toList settings; + }; + inherit (treefmt) meta version; + } + '' + mkdir -p $out/bin + makeWrapper \ + $treefmtExe \ + $out/bin/treefmt \ + --prefix PATH : "$binPath" \ + --add-flags "--config-file $configFile" + ''