mirror of
https://github.com/numtide/treefmt.git
synced 2024-08-17 04:40:27 +03:00
introduce treefmt.withConfig
This is useful if you want to configure treefmt with nix, and precisely pass all the commands from nixpkgs. Co-authored-by: Sridhar Ratnakumar <srid@srid.ca>
This commit is contained in:
parent
f2bbb89e39
commit
84677166df
26
default.nix
26
default.nix
@ -13,6 +13,18 @@ let
|
||||
|
||||
cargoToml = with builtins; (fromTOML (readFile ./Cargo.toml));
|
||||
|
||||
# Use the Nix module system to validate the treefmt config file format.
|
||||
evalModule = config:
|
||||
lib.evalModules {
|
||||
modules = [
|
||||
{
|
||||
_module.args = { inherit nixpkgs lib treefmt; };
|
||||
}
|
||||
./module-options.nix
|
||||
config
|
||||
];
|
||||
};
|
||||
|
||||
# What is used when invoking `nix run github:numtide/treefmt`
|
||||
treefmt = rustPackages.rustPlatform.buildRustPackage {
|
||||
inherit (cargoToml.package) name version;
|
||||
@ -34,6 +46,12 @@ let
|
||||
cargoLock.lockFile = ./Cargo.lock;
|
||||
|
||||
meta.description = "one CLI to format the code tree";
|
||||
|
||||
passthru.withConfig = config:
|
||||
let
|
||||
mod = evalModule config;
|
||||
in
|
||||
mod.config.build.wrapper;
|
||||
};
|
||||
|
||||
# Add all the dependencies of treefmt, plus more build tools
|
||||
@ -68,7 +86,13 @@ let
|
||||
});
|
||||
in
|
||||
{
|
||||
inherit treefmt devShell;
|
||||
inherit treefmt devShell evalModule;
|
||||
|
||||
# module that generates and wraps the treefmt config with Nix
|
||||
module = ./module-options.nix;
|
||||
|
||||
# reduce a bit of repetition
|
||||
inherit (treefmt.passthru) withConfig;
|
||||
|
||||
# A collection of packages for the project
|
||||
docs = nixpkgs.callPackage ./docs { };
|
||||
|
15
flake.nix
15
flake.nix
@ -18,9 +18,22 @@
|
||||
};
|
||||
in
|
||||
{
|
||||
inherit packages;
|
||||
# This contains a mix of packages, modules, ...
|
||||
legacyPackages = packages;
|
||||
|
||||
devShells.default = packages.devShell;
|
||||
|
||||
# In Nix 2.8 you can run `nix fmt` to format this whole repo.
|
||||
#
|
||||
# Because we load the treefmt.toml and don't define links to the
|
||||
# packages in Nix, the formatter has to run inside of `nix develop`
|
||||
# to have the various tools on the PATH.
|
||||
#
|
||||
# It also assumes that the project root has a flake.nix (override this by setting `projectRootFile`).
|
||||
formatter = packages.treefmt.withConfig {
|
||||
settings = nixpkgs.lib.importTOML ./treefmt.toml;
|
||||
projectRootFile = "flake.nix";
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
|
113
module-options.nix
Normal file
113
module-options.nix
Normal file
@ -0,0 +1,113 @@
|
||||
{ lib, nixpkgs, treefmt, ... }:
|
||||
let
|
||||
# A new kind of option type that calls lib.getExe on derivations
|
||||
exeType = lib.mkOptionType {
|
||||
name = "exe";
|
||||
description = "Path to executable";
|
||||
check = (x: lib.isString x || builtins.isPath x || lib.isDerivation x);
|
||||
merge = loc: defs:
|
||||
let res = lib.mergeOneOption loc defs; in
|
||||
if lib.isString res || builtins.isPath res then
|
||||
"${res}"
|
||||
else
|
||||
lib.getExe res;
|
||||
};
|
||||
|
||||
# The schema of the treefmt.toml data structure.
|
||||
configSchema = with lib; {
|
||||
excludes = mkOption {
|
||||
description = "A global list of paths to exclude. Supports glob.";
|
||||
type = types.listOf types.str;
|
||||
default = [ ];
|
||||
example = [ "./node_modules/**" ];
|
||||
};
|
||||
|
||||
formatter = mkOption {
|
||||
type = types.attrsOf (types.submodule [{
|
||||
options = {
|
||||
command = mkOption {
|
||||
description = "Executable obeying the treefmt formatter spec";
|
||||
type = exeType;
|
||||
};
|
||||
|
||||
options = mkOption {
|
||||
description = "List of arguments to pass to the command";
|
||||
type = types.listOf types.str;
|
||||
default = [ ];
|
||||
};
|
||||
|
||||
includes = mkOption {
|
||||
description = "List of files to include for formatting. Supports globbing.";
|
||||
type = types.listOf types.str;
|
||||
};
|
||||
|
||||
excludes = mkOption {
|
||||
description = "List of files to exclude for formatting. Supports globbing. Takes precedence over the includes.";
|
||||
type = types.listOf types.str;
|
||||
default = [ ];
|
||||
};
|
||||
};
|
||||
}]);
|
||||
default = { };
|
||||
description = "Set of formatters to use";
|
||||
};
|
||||
};
|
||||
|
||||
configFormat = nixpkgs.formats.toml { };
|
||||
in
|
||||
{
|
||||
# Schema
|
||||
options = {
|
||||
settings = configSchema;
|
||||
|
||||
package = lib.mkOption {
|
||||
description = "Package wrapped in the build.wrapper output";
|
||||
type = lib.types.package;
|
||||
default = treefmt;
|
||||
};
|
||||
|
||||
projectRootFile = lib.mkOption {
|
||||
description = ''
|
||||
File to look for to determine the root of the project in the
|
||||
build.wrapper.
|
||||
'';
|
||||
example = "flake.nix";
|
||||
};
|
||||
|
||||
# Outputs
|
||||
build = {
|
||||
configFile = lib.mkOption {
|
||||
description = ''
|
||||
Contains the generated config file derived from the settings.
|
||||
'';
|
||||
type = lib.types.path;
|
||||
};
|
||||
wrapper = lib.mkOption {
|
||||
description = ''
|
||||
The treefmt package, wrapped with the config file.
|
||||
'';
|
||||
type = lib.types.package;
|
||||
};
|
||||
};
|
||||
};
|
||||
# Config
|
||||
config.build = {
|
||||
configFile = configFormat.generate "treefmt.toml" config.settings;
|
||||
|
||||
wrapper = nixpkgs.writeShellScriptBin "treefmt" ''
|
||||
find_up() (
|
||||
ancestors=()
|
||||
while [[ ! -f "$1" ]]; do
|
||||
ancestors+=("$PWD")
|
||||
if [[ $PWD == / ]]; then
|
||||
echo "ERROR: Unable to locate the projectRootFile ($1) in any of: ''${ancestors[*]@Q}" >&2
|
||||
exit 1
|
||||
fi
|
||||
cd ..
|
||||
done
|
||||
)
|
||||
tree_root=$(find_up "${config.projectRootFile}")
|
||||
exec ${config.package}/bin/treefmt --config-file ${config.build.configFile} "$@" --tree-root "$tree_root"
|
||||
'';
|
||||
};
|
||||
};
|
Loading…
Reference in New Issue
Block a user