-
Notifications
You must be signed in to change notification settings - Fork 30
Description
figment
is a configuration management crate that supports loading configuration from multiple sources, such as files and environmental variables.
Why use an external crate?
Right now we handle configuration by hand. While it works well, this requires updating multiple locations when adding or changing configuration, which could result in uncaught mistakes.
More than anything else, using an external crate means a reduced maintenance burden, better documentation on how our configuration system works, simpler code, and potentially more features.
What are our requirements?
As a baseline, an external crate should support the same features we currently do. This means:
- Reading from
Cargo.toml
metadata- Either through
cargo metadata
or manually parsingCargo.toml
. We currently do the prior, as we already use the metadata for other logic.
- Either through
- Selecting configuration based on based on the profile (dev / release) and target (native / web).
- Merging configuration from multiple profiles and targets.
What about nice-to-haves?
We may also want the following features in the future:
- Merging configuration from the crate
Cargo.toml
and workspaceCargo.toml
. - Make some CLI flags hook into the configuration system.
- Some good candidates are
--features
,--rustflags
,--profile
,--target
, and--verbose
. This lets us handle merging these options all in one place, instead of handling CLI flags separately.
- Some good candidates are
- Reading configuration from
.cargo/config.toml
.- This will let us fix
rustflags
inconfig.toml
are overwritten instead of merged #444.
- This will let us fix
- Reading configuration from environmental variables.
Why figment
?
figment
checks the boxes for all of our requirements (notably profiles and array merging), and even should make it easy to tackle the nice-to-haves! Additionally, I recommend it because:
- The documentation is fantastic! It's quite extensive with well-taught concepts and good examples.
- It tracks the location of each configuration value, which lets us tell users where each value is coming from and helps them easily debug misconfigurations.
- It supports paths relative to the file they were defined in. This is easier for the user to understand, since making paths relative to the current working directory (the default) can be confusing!
- It provides a structure that assists with unit testing different configuration setups.
- It lets us define custom
Provider
s, which are individual types that configuration can be loaded from. figment
is depended on by the popular cratesrocket
andtaplo
, which gives it credibility.
Why not figment
?
The author is the sole maintainer, and has been mostly inactive for the past 9 months. figment
should be considered passively maintained. I haven't seen any large bugs in the issue tracker and none of the open pull requests are features I think we desperately need, but if we ever need changes we'll need to somehow contact the author or fork figment
.
Additionally, the enhanced errors don't work correctly with #[serde(flatten)]
. I don't think this will be a problem, but it's something I noticed.
Why not config
?
While config
has better maintenance, it doesn't support merging arrays from multiple sources. (See #462 (comment).) I consider this a dealbreaker, as we currently support this.
Why not mergeme
?
I opened #452 to use mergeme
, a crate I wrote, to reduce the boilerplate of merging structures. mergeme
doesn't handle loading the configuration, just merging it, so it won't simplify our code as much as figment
could.