#![allow(clippy::print_stdout)]
use anyhow::{Result, bail};
use semver::Version;
use crate::utils::{deprecation, git, paths};
#[derive(clap::Args, Debug)]
#[command()]
pub struct Cli {
slug: String,
#[arg(long)]
version: Option<Version>,
}
impl Cli {
pub fn exec(self) -> Result<()> {
let repo_root = paths::find_repo_root()?;
let dir = repo_root.join(deprecation::DEPRECATION_DIR);
if self.slug.contains('/') || self.slug.contains('\\') {
bail!(
"expected a deprecation slug (e.g. \"azure-monitor-logs-sink\"), not a path: {}",
self.slug
);
}
let stem = self.slug.strip_suffix(".md").unwrap_or(&self.slug);
let filename = format!("{stem}.md");
let path = dir.join(&filename);
if !path.exists() {
bail!("No deprecation fragment found at {}", path.display());
}
let entries = deprecation::read_deprecation_fragments(&dir)?;
let entry = entries
.into_iter()
.find(|e| e.filename == filename)
.ok_or_else(|| anyhow::anyhow!("Could not parse {filename}"))?;
let version = if let Some(v) = self.version {
if !v.pre.is_empty() || !v.build.is_empty() {
bail!(
"--version {v} has prerelease or build metadata; only plain X.Y.Z is allowed"
);
}
v
} else {
let latest = git::latest_release_version()?;
Version::new(latest.major, latest.minor + 1, 0)
};
if !deprecation::later_minor(&version, &entry.deprecated_since.0) {
bail!(
"removed_in ({version}) must be in a later minor release than deprecated_since ({}); \
the deprecation policy requires at least one minor release between \
the announcement and removal. \
Check --version or the fragment's `deprecated_since` field.",
entry.deprecated_since
);
}
let enacted = deprecation::EnactedEntry {
what: entry.what.clone(),
deprecated_since: entry.deprecated_since.to_string(),
removed_in: version.to_string(),
description: entry.description.clone(),
};
deprecation::append_enacted(&repo_root, enacted)?;
println!("Recorded enacted entry for: {}", entry.what);
std::fs::remove_file(&path)?;
println!("Deleted {}", path.display());
deprecation::sync_deprecations_cue(&repo_root)?;
println!(
"Updated {}",
repo_root.join(deprecation::DEPRECATIONS_JSON).display()
);
Ok(())
}
}