As more tools become available to the rust community, each tool adopts a new mytool.toml
configuration file, which leads to a proliferation of config files at the root of a typical project (or sometimes subproject in a workspace).
Intuitively, I prefer to minimize the number of configuration files present at the root of my project. I'll try to put that intuition a bit into words, but hopefully others will also be able to come along with more directly informed experiences to reinforce the motivation.
-
More files, particularly at a project root, can make it more difficult for a newcomer to scan a explore a project's file directory to figure out where to get started.
-
Particularily, if each tool adopts its own non-standard config file naming scheme it beomes more difficult for scan for files of a particular file you may be looking for.
Documentation files tend to be easy to read by adopting a consistent naming scheme, e.g.
README
,CONTRIBUTING
, andLICENSE
. These particularly also benefit from being widely adopted outside of the rust community. Additionally, it is desirable for documentation to be separated in this way to accommodate the different use cases that are common for newcomers to the project (How do I use this? How do I add to this? Am I allowed to use this?).Common config files (at least so far) have much less consistent naming, and even sometimes specifically support variable naming for backwards compatibility purposes: e.g.
Cargo.toml
,.rustfmt.toml
,my-tool.toml
,another_tool.toml
,ThirdTool.toml
.Comparative to documenation files, tool configuration files have a much narrower use-- the most common is that a user doesn't care and shouldn't need to look at tool configuration files. Ideally the configuration is written once, read never, and the tooling performs all of the relevant work on behalf of users.
The two use cases I see most common that you'd want to look at configuration files are:
-
A contributor would like to see what workflows this project uses beyond/differently than the base common tooling. In this scenario, if the majority of the configuration is in one file, a developer can look in one place and be made aware of all differences. Similarly if a project is using a custom tool, it could be called out as a tool explicitly rather than the higher learning curve of "what is
frobulator.toml
for"? -
A contributor would like to change project workflows.
-
-
More "community standard" configuration files increases the learning curve around project organization for newcomers to rust; although this is specifically when stepping in to an existing project, rather than learning via
cargo new
which doesn't impose any knowledge on the subject.
This problem is substantially mitigated, because Rust tools tend to reach a very high bar in terms of design and usability before becoming widely adopted by the community; and additionally tend to have widely applicable defaults that are useful for a majority of cases. However desiring just a single custom config rule leads to managing/teaching about a new config file.
Prior work
The NPM community (known perhaps for have too much and non-standardized tooling)
has nonetheless come up with the prior art of supporting the majority of lint/test/format
configuration in the package.json
file (most equivalent to Cargo.toml
, specifically dependency management). The NPM communities approach to this is fragmented because
it is a de-facto rather than explicit standard; in particular the config subsections are inconsistently named (e.g. eslintConfig
, browserlist
, jest
).
Idea - Add [tools]
section in Cargo.toml
N.B. as noted in @sflacker's and @steveklabnik's quick feedback, there is an existing
[package.metadata]
section which behaves in the same way as described below.Instead--- would we want to update
rustfmt
andclippy
to support loading their configuration from this section, and update surrounding documentation to encourage new tools to do the same.Perhaps we could add develop a
cargo-config
crate which automates a community recommended configuration config standard which could for example, automatically look inCargo.toml
formetadata
as well as.<tool>.toml
andtool.toml
like rustfmt and clippy do currently.
A tools section in the cargo manifest would provide a standard place to store config files for both community blesses as well as custom or experimental tools.
Documentation about the [tools]
section in the cargo manifest will inform the normative
behavior for naming the config subsection to be [tools.<tool_name>]
, e.g. [tools.rustfmt]
or [tools.clippy]
. Cargo would mostly ignore this section, but other optional standards
could also be introduced to integrate the tools.
Example:
[package]
name = "mycrate"
[tools.rustfmt]
reorder_imports = false
[tools.clippy]
blacklisted-names = ["toto", "tata", "titi"]
In many, I feel this is similar extension compared to tool lints and attributes.
Alternative - More configuration as code
Another reasonable alternative is to try to continue to expand the capabilities or
just standardization of the "configuration as code pattern" (largely used by clippy
in the form of tool_lints
, although it also has its own config file for some things
which I believe cannot be expressed as attributes such as clippy's
blacklisted-names
).
Specifically, we could move more tool configuration in to {main,lib}.rs
attributes.
Possible syntax:
#![rustfmt::config(reorder_imports = false)]
Looking forward to feedback!