`codex-core` had accumulated config loading, requirements parsing, constraint logic, and config-layer state handling in a single crate. This change extracts that subsystem into `codex-config` to reduce `codex-core` rebuild/test surface area and isolate future config work. ## What Changed ### Added `codex-config` - Added new workspace crate `codex-rs/config` (`codex-config`). - Added workspace/build wiring in: - `codex-rs/Cargo.toml` - `codex-rs/config/Cargo.toml` - `codex-rs/config/BUILD.bazel` - Updated lockfiles (`codex-rs/Cargo.lock`, `MODULE.bazel.lock`). - Added `codex-core` -> `codex-config` dependency in `codex-rs/core/Cargo.toml`. ### Moved config internals from `core` into `config` Moved modules to `codex-rs/config/src/`: - `core/src/config/constraint.rs` -> `config/src/constraint.rs` - `core/src/config_loader/cloud_requirements.rs` -> `config/src/cloud_requirements.rs` - `core/src/config_loader/config_requirements.rs` -> `config/src/config_requirements.rs` - `core/src/config_loader/fingerprint.rs` -> `config/src/fingerprint.rs` - `core/src/config_loader/merge.rs` -> `config/src/merge.rs` - `core/src/config_loader/overrides.rs` -> `config/src/overrides.rs` - `core/src/config_loader/requirements_exec_policy.rs` -> `config/src/requirements_exec_policy.rs` - `core/src/config_loader/state.rs` -> `config/src/state.rs` `codex-config` now re-exports this surface from `config/src/lib.rs` at the crate top level. ### Updated `core` to consume/re-export `codex-config` - `core/src/config_loader/mod.rs` now imports/re-exports config-loader types/functions from top-level `codex_config::*`. - Local moved modules were removed from `core/src/config_loader/`. - `core/src/config/mod.rs` now re-exports constraint types from `codex_config`.
55 lines
1.7 KiB
Rust
55 lines
1.7 KiB
Rust
use toml::Value as TomlValue;
|
|
|
|
pub(crate) fn default_empty_table() -> TomlValue {
|
|
TomlValue::Table(Default::default())
|
|
}
|
|
|
|
pub fn build_cli_overrides_layer(cli_overrides: &[(String, TomlValue)]) -> TomlValue {
|
|
let mut root = default_empty_table();
|
|
for (path, value) in cli_overrides {
|
|
apply_toml_override(&mut root, path, value.clone());
|
|
}
|
|
root
|
|
}
|
|
|
|
/// Apply a single dotted-path override onto a TOML value.
|
|
fn apply_toml_override(root: &mut TomlValue, path: &str, value: TomlValue) {
|
|
use toml::value::Table;
|
|
|
|
let mut current = root;
|
|
let mut segments_iter = path.split('.').peekable();
|
|
|
|
while let Some(segment) = segments_iter.next() {
|
|
let is_last = segments_iter.peek().is_none();
|
|
|
|
if is_last {
|
|
match current {
|
|
TomlValue::Table(table) => {
|
|
table.insert(segment.to_string(), value);
|
|
}
|
|
_ => {
|
|
let mut table = Table::new();
|
|
table.insert(segment.to_string(), value);
|
|
*current = TomlValue::Table(table);
|
|
}
|
|
}
|
|
return;
|
|
}
|
|
|
|
match current {
|
|
TomlValue::Table(table) => {
|
|
current = table
|
|
.entry(segment.to_string())
|
|
.or_insert_with(|| TomlValue::Table(Table::new()));
|
|
}
|
|
_ => {
|
|
*current = TomlValue::Table(Table::new());
|
|
if let TomlValue::Table(tbl) = current {
|
|
current = tbl
|
|
.entry(segment.to_string())
|
|
.or_insert_with(|| TomlValue::Table(Table::new()));
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|