Remove hook commands identified by `command_prefix` from `hooks_key` in `target`, without needing the original manifest file. Used by receipt-driven integration uninstalls, where the receipt records `(target, hooks_key, command_prefix)` but the package may no longer exist on disk.
(
target: &Path,
hooks_key: &str,
command_prefix: &str,
)
| 187 | /// `(target, hooks_key, command_prefix)` but the package may no longer exist |
| 188 | /// on disk. |
| 189 | pub fn uninstall_prefixed( |
| 190 | target: &Path, |
| 191 | hooks_key: &str, |
| 192 | command_prefix: &str, |
| 193 | ) -> AgentResult<ManifestOutcome> { |
| 194 | if !target.exists() { |
| 195 | return Ok(ManifestOutcome { |
| 196 | target: target.to_path_buf(), |
| 197 | added: 0, |
| 198 | removed: 0, |
| 199 | }); |
| 200 | } |
| 201 | |
| 202 | let mut root = read_json_object(target)?; |
| 203 | let mut removed = 0; |
| 204 | if let Some(hooks) = root.get_mut(hooks_key).and_then(Value::as_object_mut) { |
| 205 | removed = remove_prefixed(hooks, command_prefix); |
| 206 | } |
| 207 | |
| 208 | write_json_object(target, &root)?; |
| 209 | |
| 210 | Ok(ManifestOutcome { |
| 211 | target: target.to_path_buf(), |
| 212 | added: 0, |
| 213 | removed, |
| 214 | }) |
| 215 | } |
| 216 | |
| 217 | fn read_manifest(path: &Path) -> AgentResult<HookManifest> { |
| 218 | let content = std::fs::read_to_string(path).map_err(|e| AgentError::ConfigError { |
no test coverage detected