cargo-dist
cargo-dist copied to clipboard
config 1.0 backend
half of #841 (see that for high level design docs)
- [x] move current config to v0 module
- [ ] create v1 config
- [x] definitions
- [x] inheritance (workspace -> package)
- [x] inheritance (installer -> installer.shell)
- [x] simple defaults
- [x] make_relative_to
- [ ] complex defaults ("enable build cache if config x or y are enabled")
- [ ] complex validation ("you flipped on x and y this makes no sense")
- [x] toml deserialization (impl'd but untested)
- [ ] toml serialization (the code
initdoes with toml-edit) - [ ] 1 million doc comments
- [ ] use v1 config internally
- [x] create v0_to_v1 translation layer
- [x] apply translation layer to current v0 config to also construct v1 in parallel
- [ ] change internal code that uses workspace config to use v1
- [x] change internal code that uses package config to use v1
- [ ] expose v1 config to end-users (probably not in this PR)
- [ ] read either v0 or v1 in, branching on which it is
- [ ] create v1 with init
- [ ] auto-translate v0 to v1 in init
Right now the biggest issue I'm running into is how "random" it is that something is a global setting or not, and the fact that a global setting vs a package-local setting requires a bunch of duplicated definitions/logic. I tried to do a cheeky split of "only ci config is global" but a lot of not-actually-ci-config is defacto-ci-config like github releases or build dependencies.
I'm going to try to do the package-local settings first to see if they're easier to migrate.
complex defaults ("enable build cache if config x or y are enabled")
This design is based entirely on the config overhaul i did in oranda last year, and it also had a last-step freeform system for Complex Defaults:
https://github.com/axodotdev/oranda/blob/0044504916cfbeaf5a830d8703828a81375b3362/src/config/mod.rs#L260-L271
My main annoyance here is that "defaults last" means some things have to be Options in the final config (or we add a 4th fucking copy of every struct ;-;). In practice a few extra options you have to unwrap is..... Probably Fine.
This doc-comment in oranda is quite informative about the basic idea of the design: https://github.com/axodotdev/oranda/blob/0044504916cfbeaf5a830d8703828a81375b3362/src/config/mod.rs#L1
What this design adds is an extra "Inheritable" thing between Config and Layer to represent the delayed application of inherited values like installers.install_path onto installers.shell.install_path.
This results in there being 4 possible values any given setting can come from, which need to apply in this exact preference order
- workspace.publish.prerelease
- workspace.publish.cargo.prerelease
- package.publish.prerelease
- package.publish.cargo.prerelease
you need the accursed middle struct to handle cases like
- workspace.publish.prelease = true
- package.publish.cargo = true
(cargo is enabled within a package, but doesn't specify its prerelease preferences, so the prerelease setting needs to be inherited from the workspace all-publishes setting. The workspace.publish.prerelease setting therefore can't be eagerly merged into workspace.publish.cargo.prerelease, because workspace.publish.cargo = None.)