diff options
| author | nsfisis <nsfisis@gmail.com> | 2026-05-09 00:09:58 +0900 |
|---|---|---|
| committer | nsfisis <nsfisis@gmail.com> | 2026-05-09 00:09:58 +0900 |
| commit | 4ab0a1d6ffe9f42a302806ad970bed03a0e1fd86 (patch) | |
| tree | 75380ffe5ed7f473578f886d92a0a924eb3eba15 /crates/mozart/src/commands/config_helpers.rs | |
| parent | d0d8d43ba37d2179c4bd92018169d48f6633d14e (diff) | |
| download | php-mozart-4ab0a1d6ffe9f42a302806ad970bed03a0e1fd86.tar.gz php-mozart-4ab0a1d6ffe9f42a302806ad970bed03a0e1fd86.tar.zst php-mozart-4ab0a1d6ffe9f42a302806ad970bed03a0e1fd86.zip | |
fix(config): align with Composer's ConfigCommand pipeline
- A1: stub auth keys (bitbucket-oauth.X etc.) with actionable error
- A2: audit.ignore / audit.ignore-abandoned writers with --json/--merge
- A3: scripts.X writer (scalar vs array) and --unset support
- A4: top-level --unset fallback for unknown single-segment keys
- A5: bare --unset extra / suggest / audit support
- A6/A13: disable-tls enable/disable user-visible messages
- A7: editor fallback chain (editor/vim/vi/nano/pico/ed)
- A8: --editor --auth opens auth.json
- A9: silent exit 0 when no setting-key and no --list
- A10: cache-files-maxsize regex validation
- A11: cafile/capath existence check + "null" clearing
- A14: merge_json_values object merge uses existing-wins (PHP `+`)
- A16: repositories.<name>.url sub-path support
- A17: wording "cannot" → "can not" to match Composer exactly
- A19: add_repository normalizes assoc repos, injects name field,
strips stale disable entries
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Diffstat (limited to 'crates/mozart/src/commands/config_helpers.rs')
| -rw-r--r-- | crates/mozart/src/commands/config_helpers.rs | 44 |
1 files changed, 41 insertions, 3 deletions
diff --git a/crates/mozart/src/commands/config_helpers.rs b/crates/mozart/src/commands/config_helpers.rs index f0aacbb..fb626f6 100644 --- a/crates/mozart/src/commands/config_helpers.rs +++ b/crates/mozart/src/commands/config_helpers.rs @@ -115,23 +115,61 @@ pub(crate) fn normalize_repositories(value: &serde_json::Value) -> Vec<serde_jso /// Add a repository entry to the `repositories` array in json. /// If `append` is true, push to end; otherwise insert at beginning. /// Removes any existing entry with the same name first. +/// Handles both array and associative-object repository forms (A19). pub(crate) fn add_repository( json: &mut serde_json::Value, name: &str, config: serde_json::Value, append: bool, ) { + // Normalize assoc-keyed repositories to list form (A19) + if json["repositories"].is_object() { + let normalized = normalize_repositories(&json["repositories"].clone()); + json["repositories"] = serde_json::Value::Array(normalized); + } if !json["repositories"].is_array() { json["repositories"] = serde_json::json!([]); } - remove_repository(json, name); + // Build the entry, injecting "name" when absent (A19, mirrors Composer 108-110) + let entry = if config == serde_json::Value::Bool(false) { + // Disable entry: {name: false} + let mut m = serde_json::Map::new(); + m.insert(name.to_string(), serde_json::Value::Bool(false)); + serde_json::Value::Object(m) + } else if let Some(obj) = config.as_object() + && !obj.contains_key("name") + && !name.is_empty() + { + let mut new_map = serde_json::Map::new(); + new_map.insert("name".to_string(), serde_json::json!(name)); + for (k, v) in obj { + new_map.insert(k.clone(), v.clone()); + } + serde_json::Value::Object(new_map) + } else { + config + }; + + // Remove stale entries (by name or {name: false} disable) (A19) + if let Some(repos) = json["repositories"].as_array_mut() { + repos.retain(|val| { + if let Some(entry_name) = val.get("name").and_then(|n| n.as_str()) { + entry_name != name + } else { + // {name: false} disable entry + !val.as_object() + .map(|obj| obj.contains_key(name)) + .unwrap_or(false) + } + }); + } let repos = json["repositories"].as_array_mut().unwrap(); if append { - repos.push(config); + repos.push(entry); } else { - repos.insert(0, config); + repos.insert(0, entry); } } |
