From 0858f1bc43aa2c897717bb4cf188aefea55e1971 Mon Sep 17 00:00:00 2001 From: Matt Sturgeon Date: Mon, 19 May 2025 16:22:32 +0100 Subject: [PATCH] treefmt: refactor `withConfig` and `buildConfig` to use `evalConfig` (#406685) Introduces a new modules-based implementation that is used by both `withConfig` and `buildConfig`. Previously we used a module eval for `settings`. This PR makes it so that all args passed to `withConfig` are now module options. `settings` is now a submodule of the wider `evalConfig` configuration. As well as being a better overall design (IMO), using a module eval enables adding additional options in the future. E.g. we could add `programs` options similar to those maintained by treefmt-nix. --- pkgs/by-name/ni/nixfmt-tree/package.nix | 2 +- pkgs/by-name/tr/treefmt/build-config.nix | 30 ------ pkgs/by-name/tr/treefmt/lib.nix | 98 ++++++++++++++++++++ pkgs/by-name/tr/treefmt/modules/default.nix | 9 ++ pkgs/by-name/tr/treefmt/modules/options.nix | 40 ++++++++ pkgs/by-name/tr/treefmt/modules/settings.nix | 26 ++++++ pkgs/by-name/tr/treefmt/modules/wrapper.nix | 40 ++++++++ pkgs/by-name/tr/treefmt/package.nix | 33 +------ pkgs/by-name/tr/treefmt/with-config.nix | 32 ------- 9 files changed, 219 insertions(+), 91 deletions(-) delete mode 100644 pkgs/by-name/tr/treefmt/build-config.nix create mode 100644 pkgs/by-name/tr/treefmt/lib.nix create mode 100644 pkgs/by-name/tr/treefmt/modules/default.nix create mode 100644 pkgs/by-name/tr/treefmt/modules/options.nix create mode 100644 pkgs/by-name/tr/treefmt/modules/settings.nix create mode 100644 pkgs/by-name/tr/treefmt/modules/wrapper.nix delete mode 100644 pkgs/by-name/tr/treefmt/with-config.nix diff --git a/pkgs/by-name/ni/nixfmt-tree/package.nix b/pkgs/by-name/ni/nixfmt-tree/package.nix index 08a17f465649..f9a7991544ef 100644 --- a/pkgs/by-name/ni/nixfmt-tree/package.nix +++ b/pkgs/by-name/ni/nixfmt-tree/package.nix @@ -21,7 +21,7 @@ let treefmtWithConfig = treefmt.withConfig { name = "nixfmt-tree"; - settings = [ + settings = lib.mkMerge [ # Default settings { _file = ./package.nix; diff --git a/pkgs/by-name/tr/treefmt/build-config.nix b/pkgs/by-name/tr/treefmt/build-config.nix deleted file mode 100644 index c4eb298a051c..000000000000 --- a/pkgs/by-name/tr/treefmt/build-config.nix +++ /dev/null @@ -1,30 +0,0 @@ -{ - 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; - optionType = configuration.type; - }; -} diff --git a/pkgs/by-name/tr/treefmt/lib.nix b/pkgs/by-name/tr/treefmt/lib.nix new file mode 100644 index 000000000000..a9b06eae4f27 --- /dev/null +++ b/pkgs/by-name/tr/treefmt/lib.nix @@ -0,0 +1,98 @@ +{ + lib, + pkgs, + treefmt, +}: +{ + /** + Evaluate a treefmt configuration. + + # Type + + ``` + Module -> Configuration + ``` + + # Inputs + + `module` + : A treefmt module, configuring options that include: + - `name`: `String` (default `"treefmt-with-config"`) + - `settings`: `Module` (default `{ }`) + - `runtimeInputs`: `[Derivation]` (default `[ ]`) + */ + evalConfig = + module: + lib.evalModules { + class = "treefmtConfig"; + specialArgs.modulesPath = ./modules; + modules = [ + { + _file = "treefmt.evalConfig"; + _module.args.pkgs = lib.mkOptionDefault pkgs; + package = lib.mkOptionDefault treefmt; + } + { + _file = ""; + imports = lib.toList module; + } + ./modules/default.nix + ]; + }; + + /** + Wrap treefmt, configured using structured settings. + + # Type + + ``` + Module -> Derivation + ``` + + # Inputs + + `module` + : A treefmt module, configuring options that include: + - `name`: `String` (default `"treefmt-with-config"`) + - `settings`: `Module` (default `{ }`) + - `runtimeInputs`: `[Derivation]` (default `[ ]`) + */ + withConfig = + module: + let + configuration = treefmt.evalConfig { + _file = ""; + imports = lib.toList module; + }; + in + configuration.config.result; + + /** + Build a treefmt config file from structured settings. + + # Type + + ``` + Module -> Derivation + ``` + + # Inputs + + `settings` + : A settings module, used to build a treefmt config file + */ + buildConfig = + module: + let + configuration = treefmt.evalConfig { + _file = ""; + settings.imports = lib.toList module; + }; + in + configuration.config.configFile.overrideAttrs { + passthru = { + inherit (configuration.config) settings; + options = (opt: opt.type.getSubOptions opt.loc) configuration.options.settings; + }; + }; +} diff --git a/pkgs/by-name/tr/treefmt/modules/default.nix b/pkgs/by-name/tr/treefmt/modules/default.nix new file mode 100644 index 000000000000..449f2b9ff88c --- /dev/null +++ b/pkgs/by-name/tr/treefmt/modules/default.nix @@ -0,0 +1,9 @@ +{ + _class = "treefmtConfig"; + + imports = [ + ./options.nix + ./settings.nix + ./wrapper.nix + ]; +} diff --git a/pkgs/by-name/tr/treefmt/modules/options.nix b/pkgs/by-name/tr/treefmt/modules/options.nix new file mode 100644 index 000000000000..eff5c97a5351 --- /dev/null +++ b/pkgs/by-name/tr/treefmt/modules/options.nix @@ -0,0 +1,40 @@ +{ lib, config, ... }: +{ + options = { + name = lib.mkOption { + type = lib.types.str; + default = lib.getName config.package + "-with-config"; + defaultText = lib.literalExpression "\"\${getName package}-with-config\""; + description = '' + Name to use for the wrapped treefmt package. + ''; + }; + + runtimeInputs = lib.mkOption { + type = with lib.types; listOf package; + default = [ ]; + description = '' + Packages to include on treefmt's PATH. + ''; + }; + + configFile = lib.mkOption { + type = lib.types.path; + # Ensure file is copied to the store + apply = file: if lib.isDerivation file then file else "${file}"; + defaultText = lib.literalMD "generated from [](#opt-treefmt-settings)"; + description = '' + The treefmt config file. + ''; + }; + + package = lib.mkOption { + type = lib.types.package; + defaultText = lib.literalExpression "pkgs.treefmt"; + description = '' + The treefmt package to wrap. + ''; + internal = true; + }; + }; +} diff --git a/pkgs/by-name/tr/treefmt/modules/settings.nix b/pkgs/by-name/tr/treefmt/modules/settings.nix new file mode 100644 index 000000000000..eeb947c8e928 --- /dev/null +++ b/pkgs/by-name/tr/treefmt/modules/settings.nix @@ -0,0 +1,26 @@ +{ + lib, + pkgs, + config, + modulesPath, + ... +}: +let + settingsFormat = pkgs.formats.toml { }; +in +{ + options.settings = lib.mkOption { + type = lib.types.submoduleWith { + specialArgs = { inherit modulesPath; }; + modules = [ + { freeformType = settingsFormat.type; } + ]; + }; + default = { }; + description = '' + Settings used to build a treefmt config file. + ''; + }; + + config.configFile = lib.mkOptionDefault (settingsFormat.generate "treefmt.toml" config.settings); +} diff --git a/pkgs/by-name/tr/treefmt/modules/wrapper.nix b/pkgs/by-name/tr/treefmt/modules/wrapper.nix new file mode 100644 index 000000000000..bb5c47c76f60 --- /dev/null +++ b/pkgs/by-name/tr/treefmt/modules/wrapper.nix @@ -0,0 +1,40 @@ +{ + lib, + pkgs, + config, + options, + ... +}: +{ + options.result = lib.mkOption { + type = lib.types.package; + description = '' + The wrapped treefmt package. + ''; + readOnly = true; + internal = true; + }; + + config.result = + pkgs.runCommand config.name + { + nativeBuildInputs = [ pkgs.makeBinaryWrapper ]; + env = { + inherit (config) configFile; + binPath = lib.makeBinPath config.runtimeInputs; + }; + passthru = { + inherit (config) runtimeInputs; + inherit config options; + }; + inherit (config.package) meta version; + } + '' + mkdir -p $out/bin + makeWrapper \ + ${lib.getExe config.package} \ + $out/bin/treefmt \ + --prefix PATH : "$binPath" \ + --add-flags "--config-file $configFile" + ''; +} diff --git a/pkgs/by-name/tr/treefmt/package.nix b/pkgs/by-name/tr/treefmt/package.nix index 5f9ed74e5c52..1a4873157f0c 100644 --- a/pkgs/by-name/tr/treefmt/package.nix +++ b/pkgs/by-name/tr/treefmt/package.nix @@ -1,7 +1,6 @@ { lib, buildGoModule, - callPackage, callPackages, fetchFromGitHub, }: @@ -30,33 +29,11 @@ buildGoModule rec { ]; 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 { }; + inherit (callPackages ./lib.nix { }) + evalConfig + withConfig + buildConfig + ; tests = callPackages ./tests.nix { }; }; diff --git a/pkgs/by-name/tr/treefmt/with-config.nix b/pkgs/by-name/tr/treefmt/with-config.nix deleted file mode 100644 index bf139f07d9dd..000000000000 --- a/pkgs/by-name/tr/treefmt/with-config.nix +++ /dev/null @@ -1,32 +0,0 @@ -{ - lib, - runCommand, - treefmt, - makeBinaryWrapper, -}: -{ - name ? "treefmt-with-config", - settings ? { }, - runtimeInputs ? [ ], -}: -runCommand name - { - nativeBuildInputs = [ makeBinaryWrapper ]; - treefmtExe = lib.getExe treefmt; - binPath = lib.makeBinPath runtimeInputs; - passthru = { inherit 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" - ''