|
||
---|---|---|
.github | ||
.vscode | ||
assets | ||
benches | ||
docs | ||
examples | ||
src | ||
.gitignore | ||
Cargo.lock | ||
Cargo.toml | ||
ci.sh | ||
clippy.toml | ||
default.nix | ||
devshell.toml | ||
flake-compat.nix | ||
flake.lock | ||
flake.nix | ||
README.md | ||
shell.nix | ||
treefmt.toml |
treefmt - one CLI to format the code tree
Status: experimental -- not all features described here are working yet.
Every project has different languages and set of code formatters, with different configurations. When jumping between projects, it always takes a bit of time to get accustomed to them and update the editor configuration.
This project solves that problem by proposing a unified CLI interface that
traverses the project file tree and maps each file to a different code
formatter. Type treefmt
, and it re-formats the repository.
Design decisions
We assume that the project code is checked into source control. Therefore, the
default should be to write formatter changes back in place. Options like
--dry-run
are not needed; the source control is relied upon to revert or
check for code changes.
treefmt
is responsible for traversing the file-system and mapping files to
specific code formatters.
Only one formatter per file. treefmt
enforces that only one tool is
executed per file. Guaranteeing two tools to produce idempotent outputs is
quite tricky.
Usage
$ cargo run -- --help
treefmt 0.1.0
✨ format all your language!
USAGE:
treefmt [FLAGS] [OPTIONS] [paths]...
FLAGS:
--clear-cache Clear the evaluation cache. Use in case the cache is not precise enough
--fail-on-change Exit with error if any changes were made. Useful for CI
-h, --help Prints help information
--init Create a new treefmt.toml
-q, --quiet No output printed to stdout
-V, --version Prints version information
-v, --verbose Log verbosity is based off the number of v used
OPTIONS:
--log-level <log-level> The maximum level of messages that should be logged by treefmt. [possible values:
info, warn, error] [default: debug]
--tree-root <tree-root> Set the path to the tree root directory. Defaults to the folder holding the
treefmt.toml file
-C <work-dir> Run as if treefmt was started in <work-dir> instead of the current working directory
[default: .]
ARGS:
<paths>... Paths to format. Defaults to formatting the whole tree
Configuration format
treefmt
depends on the treefmt.toml
to map file extensions to actual code
formatters. That file is searched for recursively from the current folder and
up unless the --config <path>
option is passed.
[formatter.<name>]
This section describes the integration between a single formatter and
treefmt
.
-
command
: A list of arguments to execute the formatter. This will be composed with theoptions
attribute during invocation. The first argument is the name of the executable to run. -
options
: A list of extra arguments to add to the command. This is typically project-specific arguments. -
includes
: A list of glob patterns used to select files. Usually this would be something like[ "*.sh" ]
to select all the shell scripts. Sometimes, full filenames can be passed. Eg:[ "Makefile" ]
. -
excludes
: A list of glob patterns to deny. If any of these patterns match, the file will be excluded.
Use cases
CLI usage
As a developer, I want to run treefmt
in any folder and it would
automatically format all of the code, configured for the project. I don't want
to remember what tool to use, or their magic incantation.
Editor integration
TODO: not supported yet.
Editors often want to be able to format a file, before it gets written to disk.
Ideally, the editor would pipe the code in, pass the filename, and get the
formatted code out. Eg: cat ./my_file.sh | treefmt --stdin my_file.sh > formatted_file.sh
CI integration
The --fail-on-change
flag can be used to exit with error if any files were
re-formatted.
Eg:
#!/usr/bin/env bash
set -euo pipefail
# Format all of the code and exit with error if there are any changes
treefmt --fail-on-change
Interfaces
In order to keep the design of treefmt simple, we ask code formatters to adhere to the following specification.
If they don't, the best is to create a wrapper script that transforms the usage to match that spec.
Related projects
- EditorConfig: unifies file indentations configuration on a per-project basis.
- prettier: and opinionated code formatter for a number of languages.
Contributing
All contributions are welcome! We try to keep the project simple and focused so not everything will be accepted. Please open an issue to discuss before working on a big item.
If you want to discuss, we have a public Matrix channel: #treefmt:numtide.com
License
MIT - (c) 2021 NumTide Ltd and contributors.