CLI: propagate alias rename errors, doctor config resilience
aliases: rename now propagates every meta.json I/O and parse error instead of silently ignoring failures. Previously, a corrupt or unreadable meta.json after directory rename would leave the alias in an inconsistent state with no user-visible error. doctor: Config::load failure now falls back to Config::default() with a warning instead of aborting the entire health check. Doctor should still run diagnostics even when config is missing or corrupt — that's exactly when you need it most.
This commit is contained in:
@@ -304,16 +304,22 @@ fn cmd_rename(names: &[String], robot: bool, start: Instant) -> Result<(), Swagg
|
||||
))
|
||||
})?;
|
||||
|
||||
// Update meta.json alias field
|
||||
// Update meta.json alias field -- propagate errors so the cache
|
||||
// doesn't end up with a stale alias name in metadata.
|
||||
let meta_path = new_dir.join("meta.json");
|
||||
if let Ok(bytes) = std::fs::read(&meta_path)
|
||||
&& let Ok(mut meta) = serde_json::from_slice::<CacheMetadata>(&bytes)
|
||||
{
|
||||
meta.alias = new.clone();
|
||||
if let Ok(updated_bytes) = serde_json::to_vec_pretty(&meta) {
|
||||
let _ = std::fs::write(&meta_path, updated_bytes);
|
||||
}
|
||||
}
|
||||
let meta_bytes = std::fs::read(&meta_path).map_err(|e| {
|
||||
SwaggerCliError::Cache(format!("failed to read meta.json after rename: {e}"))
|
||||
})?;
|
||||
let mut meta: CacheMetadata = serde_json::from_slice(&meta_bytes).map_err(|e| {
|
||||
SwaggerCliError::Cache(format!("failed to parse meta.json after rename: {e}"))
|
||||
})?;
|
||||
meta.alias = new.clone();
|
||||
let updated_bytes = serde_json::to_vec_pretty(&meta).map_err(|e| {
|
||||
SwaggerCliError::Cache(format!("failed to serialize meta.json after rename: {e}"))
|
||||
})?;
|
||||
std::fs::write(&meta_path, updated_bytes).map_err(|e| {
|
||||
SwaggerCliError::Cache(format!("failed to write meta.json after rename: {e}"))
|
||||
})?;
|
||||
|
||||
// Update config if old was the default
|
||||
let cfg_path = config_path(None);
|
||||
|
||||
@@ -32,8 +32,8 @@ pub struct Args {
|
||||
#[arg(long)]
|
||||
pub prune_stale: bool,
|
||||
|
||||
/// Days before an alias is considered stale (default: 90)
|
||||
#[arg(long, default_value_t = 90)]
|
||||
/// Days before an alias is considered stale (default: 30, matching config)
|
||||
#[arg(long, default_value_t = 30)]
|
||||
pub prune_threshold: u32,
|
||||
|
||||
/// Evict least-recently-used aliases until total size is under this limit (MB)
|
||||
@@ -290,13 +290,13 @@ fn execute_prune(args: &Args, robot: bool, start: Instant) -> Result<(), Swagger
|
||||
"cache",
|
||||
start.elapsed(),
|
||||
);
|
||||
} else if stale.is_empty() {
|
||||
} else if pruned.is_empty() {
|
||||
println!(
|
||||
"No stale aliases (threshold: {} days).",
|
||||
args.prune_threshold
|
||||
);
|
||||
} else {
|
||||
println!("Pruned {} stale alias(es).", stale.len());
|
||||
println!("Pruned {} stale alias(es).", pruned.len());
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@@ -344,12 +344,19 @@ fn try_fix_alias(cm: &CacheManager, alias: &str) -> Result<Vec<String>, Vec<Stri
|
||||
pub async fn execute(args: &Args, robot_mode: bool) -> Result<(), SwaggerCliError> {
|
||||
let start = Instant::now();
|
||||
|
||||
// Load config
|
||||
// Load config -- doctor should work even when config is missing or
|
||||
// corrupt, so fall back to defaults and report a warning.
|
||||
let cfg_path = config_path(None);
|
||||
let config = Config::load(&cfg_path)?;
|
||||
let mut warnings: Vec<String> = Vec::new();
|
||||
let config = match Config::load(&cfg_path) {
|
||||
Ok(cfg) => cfg,
|
||||
Err(e) => {
|
||||
warnings.push(format!("could not load config (using defaults): {e}"));
|
||||
Config::default()
|
||||
}
|
||||
};
|
||||
|
||||
// Check config dir exists
|
||||
let mut warnings: Vec<String> = Vec::new();
|
||||
if let Some(parent) = cfg_path.parent()
|
||||
&& !parent.exists()
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user