Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/numtide/treefmt-nix
treefmt nix configuration
https://github.com/numtide/treefmt-nix
buildbot-numtide flake-parts nix treefmt
Last synced: 2 days ago
JSON representation
treefmt nix configuration
- Host: GitHub
- URL: https://github.com/numtide/treefmt-nix
- Owner: numtide
- License: mit
- Created: 2022-09-23T09:13:45.000Z (over 2 years ago)
- Default Branch: main
- Last Pushed: 2025-01-24T11:22:59.000Z (11 days ago)
- Last Synced: 2025-01-26T04:03:33.548Z (9 days ago)
- Topics: buildbot-numtide, flake-parts, nix, treefmt
- Language: Nix
- Homepage: https://numtide.github.io/treefmt/
- Size: 421 KB
- Stars: 310
- Watchers: 9
- Forks: 91
- Open Issues: 25
-
Metadata Files:
- Readme: README.md
- License: LICENSE.md
- Support: supported-programs.sh
Awesome Lists containing this project
README
[treefmt](https://numtide.github.io/treefmt) combines file formatters for
multiple programming languages so that you can format all your project files
with a single command. With `treefmt-nix` you can specify `treefmt` build
options, dependencies and config in one place, conveniently managed by
[Nix](https://nixos.org/).`treefmt-nix` automatically installs and configures the desired formatters as
well as `treefmt` for you and integrates nicely into your Nix development
environments. It comes with sane, pre-crafted
[formatter-configs](https://github.com/numtide/treefmt-nix/tree/main/programs)
maintained by the community; each config corresponds to a section that you would
normally add to the `treefmt` config file `treefmt.toml`.Take a look at the already [supported formatters](#supported-programs) for
Python, Rust, Go, Haskell and more.## Integration into Nix
### Nix classic without flakes
To run `treefmt-nix` with nix-classic, import the repo using
[`niv`](https://github.com/nmattia/niv):```
$ niv add numtide/treefmt-nix
```Alternatively, you can download the source and run `nix-build` in the project
root directory:```
$ nix-build
```The command will return the helper functions which will be later used to produce
a derivation from the specified `treefmt-nix` configuration.After you installed treefmt-nix, specify the formatter configuration. For
instance, this one is for formatting terraform files:```nix
# myfile.nix
{ system ? builtins.currentSystem }:
let
nixpkgsSrc = builtins.fetchTarball "https://github.com/NixOS/nixpkgs/archive/refs/heads/nixos-unstable.tar.gz";
treefmt-nixSrc = builtins.fetchTarball "https://github.com/numtide/treefmt-nix/archive/refs/heads/master.tar.gz";
nixpkgs = import nixpkgsSrc { inherit system; };
treefmt-nix = import treefmt-nixSrc;
in
treefmt-nix.mkWrapper nixpkgs {
# Used to find the project root
projectRootFile = ".git/config";
# Enable the terraform formatter
programs.terraform.enable = true;
# Override the default package
programs.terraform.package = nixpkgs.terraform_1;
# Override the default settings generated by the above option
settings.formatter.terraform.excludes = [ "hello.tf" ];
}
```It's a good practice to place the configuration file in the project root
directory.Next, execute this command:
```
$ nix-build myfile.nix
```This command returns a derivation that contains a `treefmt` binary at
`./result/bin/treefmt` in your current directory. The file is actually a symlink
to the artifact in `/nix/store`.`treefmt.toml` in this case isn't generated: the binary is wrapped with the
config.### Flakes
Running treefmt-nix with flakes isn't hard. The library is exposed as the `lib`
attribute:```nix
# flake.nix
{
inputs.treefmt-nix.url = "github:numtide/treefmt-nix";outputs = { self, nixpkgs, systems, treefmt-nix }:
let
# Small tool to iterate over each systems
eachSystem = f: nixpkgs.lib.genAttrs (import systems) (system: f nixpkgs.legacyPackages.${system});# Eval the treefmt modules from ./treefmt.nix
treefmtEval = eachSystem (pkgs: treefmt-nix.lib.evalModule pkgs ./treefmt.nix);
in
{
# for `nix fmt`
formatter = eachSystem (pkgs: treefmtEval.${pkgs.system}.config.build.wrapper);
# for `nix flake check`
checks = eachSystem (pkgs: {
formatting = treefmtEval.${pkgs.system}.config.build.check self;
});
};
}
```And also add the `treefmt.nix` file (or put the content inline if you prefer):
```nix
# treefmt.nix
{ pkgs, ... }:
{
# Used to find the project root
projectRootFile = "flake.nix";
# Enable the terraform formatter
programs.terraform.enable = true;
# Override the default package
programs.terraform.package = pkgs.terraform_1;
# Override the default settings generated by the above option
settings.formatter.terraform.excludes = [ "hello.tf" ];
}
```This file is also the place to define all the treefmt parameters like includes,
excludes and formatter options.After specifying the flake, run
[`nix fmt`](https://nixos.org/manual/nix/stable/command-ref/new-cli/nix3-fmt.html):```
$ nix fmt
```Nix-fmt is a tool to format all nix files in the project, but with the specified
flake, it starts treefmt-nix and formats your project.You can also run `nix flake check` (eg: in CI) to validate that the project's
code is properly formatted.### Flake-parts
This flake exposes a [flake-parts](https://flake.parts/) module as well. To use
it:1. Add `inputs.treefmt-nix.flakeModule` to the `imports` list of your
`flake-parts` call.2. Add `treefmt = { .. }` (containing the configuration above) to your
`perSystem`.As an example, see
## Configuration
While dealing with `treefmt` outside of `nix`, the formatter configuration is
specified in a `toml` format. On the contrary, with `nix`, you write in with a
nix syntax like this:```nix
# Used to find the project root
projectRootFile = ".git/config";
# Enable the terraform formatter
programs.terraform.enable = true;
# Override the default package
programs.terraform.package = nixpkgs.terraform_1;
# Override the default settings generated by the above option
settings.formatter.terraform.excludes = [ "hello.tf" ];
```**Options:**
- `Project root file` is the git file of the project which you plan to format.
- The option `programs.terraform.enable` enables the needed formatter. You can
specify as many formatter as you want. For instance:```
programs.terraform.enable = true;
programs.gofmt.enable = true;
```- The option `programs.terraform.package` allows you to use a particular
build/version of the specified formatter.
- By setting`settings.formatter.terraform.excludes` you can mark the files which
should be excluded from formatting. You can also specify other formatter
options or includes this way.For detailed description of the options, refer to the `treefmt`
[documentation](https://treefmt.com/latest/getting-started/configure/).## Project structure
This repo contains a top-level `default.nix` that returns the library helper
functions.- `mkWrapper` is the main function which wraps treefmt with the needed
configuration.
- `mkConfigFile`
- `evalModule`
- `all-modules`## Supported programs
`treefmt-nix` currently supports 97 formatters:
* [actionlint](programs/actionlint.nix)
* [alejandra](programs/alejandra.nix)
* [asmfmt](programs/asmfmt.nix)
* [beautysh](programs/beautysh.nix)
* [biome](programs/biome.nix)
* [black](programs/black.nix)
* [buildifier](programs/buildifier.nix)
* [cabal-fmt](programs/cabal-fmt.nix)
* [clang-format](programs/clang-format.nix)
* [cljfmt](programs/cljfmt.nix)
* [cmake-format](programs/cmake-format.nix)
* [csharpier](programs/csharpier.nix)
* [cue](programs/cue.nix)
* [d2](programs/d2.nix)
* [dart-format](programs/dart-format.nix)
* [deadnix](programs/deadnix.nix)
* [deno](programs/deno.nix)
* [dhall](programs/dhall.nix)
* [dnscontrol](programs/dnscontrol.nix)
* [dos2unix](programs/dos2unix.nix)
* [dprint](programs/dprint.nix)
* [elm-format](programs/elm-format.nix)
* [erlfmt](programs/erlfmt.nix)
* [fantomas](programs/fantomas.nix)
* [fish_indent](programs/fish_indent.nix)
* [fnlfmt](programs/fnlfmt.nix)
* [formatjson5](programs/formatjson5.nix)
* [fourmolu](programs/fourmolu.nix)
* [fprettify](programs/fprettify.nix)
* [gdformat](programs/gdformat.nix)
* [genemichaels](programs/genemichaels.nix)
* [gleam](programs/gleam.nix)
* [gofmt](programs/gofmt.nix)
* [gofumpt](programs/gofumpt.nix)
* [goimports](programs/goimports.nix)
* [google-java-format](programs/google-java-format.nix)
* [hclfmt](programs/hclfmt.nix)
* [hlint](programs/hlint.nix)
* [isort](programs/isort.nix)
* [jsonfmt](programs/jsonfmt.nix)
* [jsonnet-lint](programs/jsonnet-lint.nix)
* [jsonnetfmt](programs/jsonnetfmt.nix)
* [just](programs/just.nix)
* [keep-sorted](programs/keep-sorted.nix)
* [ktfmt](programs/ktfmt.nix)
* [ktlint](programs/ktlint.nix)
* [latexindent](programs/latexindent.nix)
* [leptosfmt](programs/leptosfmt.nix)
* [mdformat](programs/mdformat.nix)
* [mdsh](programs/mdsh.nix)
* [meson](programs/meson.nix)
* [mix-format](programs/mix-format.nix)
* [muon](programs/muon.nix)
* [mypy](programs/mypy.nix)
* [nickel](programs/nickel.nix)
* [nimpretty](programs/nimpretty.nix)
* [nixfmt-classic](programs/nixfmt-classic.nix)
* [nixfmt-rfc-style](programs/nixfmt-rfc-style.nix)
* [nixfmt](programs/nixfmt.nix)
* [nixpkgs-fmt](programs/nixpkgs-fmt.nix)
* [nufmt](programs/nufmt.nix)
* [ocamlformat](programs/ocamlformat.nix)
* [odinfmt](programs/odinfmt.nix)
* [opa](programs/opa.nix)
* [ormolu](programs/ormolu.nix)
* [packer](programs/packer.nix)
* [perltidy](programs/perltidy.nix)
* [php-cs-fixer](programs/php-cs-fixer.nix)
* [pinact](programs/pinact.nix)
* [prettier](programs/prettier.nix)
* [protolint](programs/protolint.nix)
* [purs-tidy](programs/purs-tidy.nix)
* [rubocop](programs/rubocop.nix)
* [ruff-check](programs/ruff-check.nix)
* [ruff-format](programs/ruff-format.nix)
* [rufo](programs/rufo.nix)
* [rustfmt](programs/rustfmt.nix)
* [scalafmt](programs/scalafmt.nix)
* [shellcheck](programs/shellcheck.nix)
* [shfmt](programs/shfmt.nix)
* [sqlfluff](programs/sqlfluff.nix)
* [sqruff](programs/sqruff.nix)
* [statix](programs/statix.nix)
* [stylish-haskell](programs/stylish-haskell.nix)
* [stylua](programs/stylua.nix)
* [swift-format](programs/swift-format.nix)
* [taplo](programs/taplo.nix)
* [templ](programs/templ.nix)
* [terraform](programs/terraform.nix)
* [texfmt](programs/texfmt.nix)
* [toml-sort](programs/toml-sort.nix)
* [typos](programs/typos.nix)
* [typstfmt](programs/typstfmt.nix)
* [typstyle](programs/typstyle.nix)
* [yamlfmt](programs/yamlfmt.nix)
* [zig](programs/zig.nix)
* [zprint](programs/zprint.nix)For non-Nix users, you can also find the generated examples in the
[./examples](./examples) folder.### Using a custom formatter
It is also possible to use custom formatters with `treefmt-nix`. For example,
the following custom formatter formats JSON files using `yq-go`:```nix
settings.formatter = {
"yq-json" = {
command = "${pkgs.bash}/bin/bash";
options = [
"-euc"
''
for file in "$@"; do
${lib.getExe yq-go} -i --output-format=json $file
done
''
"--" # bash swallows the second argument when using -c
];
includes = [ "*.json" ];
};
};
```### Adding new formatters
PRs to add new formatters are welcome!
- The formatter should conform to the
[formatter specifications](https://numtide.github.io/treefmt/formatter-spec).
- This is not the place to debate formatting preferences. Please pick defaults
that are standard in your community -- for instance, python is usually
indented with 4 spaces, so don't add a python formatter with 2 spaces as the
default.In order to add a new formatter do the following things:
1. Create a new entry in the `./programs/` folder.
2. Consider adding yourself as the `meta.maintainer` (see below).
3. Run `./examples.sh` to update the `./examples` folder.
4. To test the program:
1. Extend the project's `./treefmt.nix` file (temporarily) to enable the new
formatter and configure it in whatever manner is appropriate.
2. Add a bunch of pertinent sources in this repo -- for instance, if the new
formatter is meant to format `*.foo` files, add a number of `*.foo` files,
some well-formatted (and therefore expected to be exempt from modification
by `treefmt`) and some badly-formatted.
3. Run `nix fmt`. Confirm that well-formatted files are unchanged and that
badly-formatted files are flagged as such. Re-run `nix fmt` and confirm
that no additional changes were made.
4. Once this is good, revert those changes.
5. Submit the PR!### Definition of a `meta.maintainer`
You can register your desire to help with a specific formatter by adding your
GitHub handle to the module's `meta.maintainers` list.That mostly means, for the given formatter:
- You get precedence if any decisions need to be made.
- Getting pinged if any issue is being found.## Commercial support
Looking for help or customization?
Get in touch with Numtide to get a quote. We make it easy for companies to work
with Open Source projects:## License
All the code and documentation is licensed with the MIT license.