Skip to content

Switch to figment for configuration management #476

@BD103

Description

@BD103

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:

  1. Reading from Cargo.toml metadata
    • Either through cargo metadata or manually parsing Cargo.toml. We currently do the prior, as we already use the metadata for other logic.
  2. Selecting configuration based on based on the profile (dev / release) and target (native / web).
  3. Merging configuration from multiple profiles and targets.

What about nice-to-haves?

We may also want the following features in the future:

  1. Merging configuration from the crate Cargo.toml and workspace Cargo.toml.
  2. 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.
  3. Reading configuration from .cargo/config.toml.
  4. 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:

  1. The documentation is fantastic! It's quite extensive with well-taught concepts and good examples.
  2. 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.
  3. 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!
  4. It provides a structure that assists with unit testing different configuration setups.
  5. It lets us define custom Providers, which are individual types that configuration can be loaded from.
  6. figment is depended on by the popular crates rocket and taplo, 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.

Metadata

Metadata

Assignees

Labels

A-CLIRelated to the main CLI and not a more specific subcommandC-Code-QualityAn improvement of readability or qualityC-DependenciesA change related to dependenciesC-FeatureMake something new possibleD-ModestA "normal" level of difficulty; suitable for simple features or challenging fixesS-Needs-DesignThis issue requires design work to think about how it would best be accomplished

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions