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.
This commit is contained in:
@@ -21,7 +21,7 @@ let
|
||||
treefmtWithConfig = treefmt.withConfig {
|
||||
name = "nixfmt-tree";
|
||||
|
||||
settings = [
|
||||
settings = lib.mkMerge [
|
||||
# Default settings
|
||||
{
|
||||
_file = ./package.nix;
|
||||
|
||||
@@ -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 = "<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;
|
||||
};
|
||||
}
|
||||
@@ -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 = "<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;
|
||||
};
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
{
|
||||
_class = "treefmtConfig";
|
||||
|
||||
imports = [
|
||||
./options.nix
|
||||
./settings.nix
|
||||
./wrapper.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;
|
||||
};
|
||||
};
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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"
|
||||
'';
|
||||
}
|
||||
@@ -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 { };
|
||||
};
|
||||
|
||||
@@ -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 = "<treefmt.withConfig settings arg>";
|
||||
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"
|
||||
''
|
||||
Reference in New Issue
Block a user