rust-cli / config-rs

⚙️ Layered configuration system for Rust applications (with strong support for 12-factor applications).
https://docs.rs/config/latest/config/
Apache License 2.0
2.65k stars 214 forks source link

Re-thinking: Override values #327

Open matthiasbeyer opened 2 years ago

matthiasbeyer commented 2 years ago

Right now we support overriding values.

Do we want to support these in the future? What are the usecases? How do they differ from default values?

dnaka91 commented 2 years ago

Not just overring, but deleting values would be important, I believe.

Let's say we have several sources for a set of settings, but some of them should only come from one source. Then we could erase certain settings from lower priority layers, before we apply the higher ranked layers that are allowed to supply said settings.

szarykott commented 2 years ago

@dnaka91 is there a real-life use case for it? Does current layering mechanism not support it? After all, values from subsequent layers override those from previous.

@matthiasbeyer As for overrides, I think they should stay, as they are not a big burden and some people might be using them (backwards compatibility that this crate, AFAIK has maintained since inception). And about "how do they differ from default ones" (I assume this is not rethorical question) - overrides are values that override any other source, regardless of the order, while defaults are "lowest level layer" - any other source can override them.

martinvonz commented 1 year ago

FWIW, I've found overrides and default a bit confusing. We have defined out configs by just layering source. It seems like default values can be modeled as lower-level source and overrides can be modeled as a higher-level source. We do use overrides, but only in sources without other values. Here's how we do it: https://github.com/martinvonz/jj/blob/a2d2da4d483874258e0026d4583e7952ff21bafb/src/config.rs#L114-L147. That seems to have worked well so far. I had actually not even realized until now that there were default values too. I also had not reflected on what "override" really meant. Does an override in a lower-level layer override a config in a higher-level layer? I haven't checked explicitly but I think our tests would have failed if it worked that way.

matthiasbeyer commented 1 year ago

It seems like default values can be modeled as lower-level source and overrides can be modeled as a higher-level source.

That's exactly the way I implemented it in the rewrite! :laughing:

martinvonz commented 1 year ago

I had not heard about the rewrite before. What's the status? Will it be released as config 0.14.0?

matthiasbeyer commented 1 year ago

The progress can be seen here: https://github.com/matthiasbeyer/config-rs-ng/ but it is not near anything finished yet. Also, I am not sure whether it will be 0.14.0 or something down the road. It will be released once it is finished, but yes, if we decide that it is the right way to go, the codebase will be merged into config-rs and become config-rs!

dnaka91 commented 1 year ago

@szarykott Sorry I totally forgot to reply to this.

The use case for deleting values would be, that we could restrict certain values to only be available on a specific layer. In Trunk, we have a few settings that should only be available to be set from the UI, as they're specific to each invocation and don't make much sense to be set from a config file.

Or sometimes where there can be a user-level config file, and we don't want to load certain settings from that file, as they're considered project specific. That is not currently the case, but might be something we do in the future.

Actually, maybe deleting wouldn't even be the right choice, but eventually something like filtering patterns instead (including globbing)?