chore(config): leverage proc macros (#9111)
### Description
This PR leverages
[derive_setters](https://crates.io/crates/derive_setters) and
[merge](https://docs.rs/merge/latest/merge/index.html) to reduce the
amount of changes required when adding a field to the configuration
options.
The manual setup is error prone as there are 4 places that need to be
updated and forgetting the final place will result in code compiling,
but the field never getting layered properly.
### Testing Instructions
Existing unit & integration tests, but also looking what the proc macros
are generating (outputs shown are produced using `rust-analyzer`'s
[Expand
macro](https://rust-analyzer.github.io/manual.html#expand-macro-recursively)
feature:
Output of `#[derive(Setters)]`
```
impl TurborepoConfigBuilder {
pub fn with_api_url(mut self, value: Option<String>) -> Self {
self.override_config.api_url = value;
self
}
...
```
Which exactly matches what `create_builder` would produce:
```
pub fn with_api_url(mut self, value: Option<String>) -> Self {
self.override_config.api_url = value;
self
}
```
`#derive(Merge)` produces
```
impl ::merge::Merge for ConfigurationOptions {
fn merge(&mut self, other: Self) {
::merge::Merge::merge(&mut self.api_url, other.api_url);
...
```
and `Merge` is defined for `Option` as :
```
impl<T> Merge for Option<T> {
fn merge(&mut self, mut other: Self) {
if !self.is_some() {
*self = other.take();
}
}
}
```
[source](https://docs.rs/merge/latest/src/merge/lib.rs.html#139-145)
So `self.api_url` will only be set to `other.api_url` if there isn't a
value present which is the behavior we want since we merge configs from
highest to lowest precedence.
---------
Co-authored-by: Nicholas Yang <nicholas.yang@vercel.com>