use anyhow::{
Context,
Result,
};
use cargo_plugin_utils::common::get_owner_repo;
use clap::Parser;
use crate::github;
use crate::version::{
format_tag,
parse_version,
};
#[derive(Parser, Debug)]
pub struct NextArgs {
#[arg(long)]
owner: Option<String>,
#[arg(long)]
repo: Option<String>,
#[arg(long, env = "GITHUB_TOKEN")]
github_token: Option<String>,
#[arg(long, default_value = "version")]
format: String,
#[arg(long, env = "GITHUB_OUTPUT")]
github_output: Option<String>,
}
pub fn next(args: NextArgs) -> Result<()> {
let (owner, repo) = get_owner_repo(args.owner, args.repo)?;
let github_token = args.github_token.as_deref();
let rt = tokio::runtime::Runtime::new().context("Failed to create tokio runtime")?;
let (latest, next) =
rt.block_on(github::calculate_next_version(&owner, &repo, github_token))?;
let next_tag = {
let (major, minor, patch) = parse_version(&next)?;
format_tag(major, minor, patch)
};
match args.format.as_str() {
"version" => println!("{}", next),
"tag" => println!("{}", next_tag),
"json" => {
println!(
"{{\"latest\":\"{}\",\"next\":\"{}\",\"next_tag\":\"{}\"}}",
latest, next, next_tag
);
}
"github-actions" => {
let output_file = args.github_output.as_deref().unwrap_or("/dev/stdout");
let output = format!(
"latest_version={}\nnext_version={}\nnext_tag={}\n",
latest, next, next_tag
);
std::fs::write(output_file, output)
.with_context(|| format!("Failed to write to {}", output_file))?;
}
_ => anyhow::bail!("Invalid format: {}", args.format),
}
Ok(())
}