Unverified Commit 0858f1bc authored by Matt Sturgeon's avatar Matt Sturgeon Committed by GitHub
Browse files

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.
parent 6f5afe34
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -21,7 +21,7 @@ let
  treefmtWithConfig = treefmt.withConfig {
    name = "nixfmt-tree";

    settings = [
    settings = lib.mkMerge [
      # Default settings
      {
        _file = ./package.nix;
+0 −30
Original line number Diff line number Diff line
{
  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 = "<treefmt.buildConfig args>";
        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;
  };
}
+98 −0
Original line number Diff line number Diff line
{
  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 = "<treefmt.evalConfig args>";
          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 = "<treefmt.withConfig args>";
        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 = "<treefmt.buildConfig args>";
        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;
      };
    };
}
+9 −0
Original line number Diff line number Diff line
{
  _class = "treefmtConfig";

  imports = [
    ./options.nix
    ./settings.nix
    ./wrapper.nix
  ];
}
+40 −0
Original line number Diff line number Diff line
{ 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;
    };
  };
}
Loading