use clap::{Args, ValueEnum};
use serde::Serialize;
use homeboy::release::{self, ReleasePlan, ReleaseRun};
use super::CmdResult;
#[derive(Clone, ValueEnum)]
pub enum BumpType {
Patch,
Minor,
Major,
}
impl BumpType {
pub fn as_str(&self) -> &'static str {
match self {
BumpType::Patch => "patch",
BumpType::Minor => "minor",
BumpType::Major => "major",
}
}
}
#[derive(Args)]
pub struct ReleaseArgs {
#[arg(value_name = "COMPONENT")]
component_id: String,
#[arg(value_name = "BUMP_TYPE")]
bump_type: BumpType,
#[arg(long)]
dry_run: bool,
#[arg(long)]
no_tag: bool,
#[arg(long)]
no_push: bool,
#[arg(long, hide = true)]
json: bool,
}
#[derive(Serialize)]
#[serde(tag = "command", rename = "release")]
pub struct ReleaseOutput {
pub result: ReleaseResult,
}
#[derive(Serialize)]
pub struct ReleaseResult {
pub component_id: String,
pub bump_type: String,
pub dry_run: bool,
pub no_tag: bool,
pub no_push: bool,
#[serde(skip_serializing_if = "Option::is_none")]
pub plan: Option<ReleasePlan>,
#[serde(skip_serializing_if = "Option::is_none")]
pub run: Option<ReleaseRun>,
}
pub fn run(args: ReleaseArgs, _global: &crate::commands::GlobalArgs) -> CmdResult<ReleaseOutput> {
let options = release::ReleaseOptions {
bump_type: args.bump_type.as_str().to_string(),
dry_run: args.dry_run,
no_tag: args.no_tag,
no_push: args.no_push,
};
if args.dry_run {
let plan = release::plan_unified(&args.component_id, &options)?;
Ok((
ReleaseOutput {
result: ReleaseResult {
component_id: args.component_id,
bump_type: options.bump_type,
dry_run: true,
no_tag: args.no_tag,
no_push: args.no_push,
plan: Some(plan),
run: None,
},
},
0,
))
} else {
let run_result = release::run_unified(&args.component_id, &options)?;
Ok((
ReleaseOutput {
result: ReleaseResult {
component_id: args.component_id,
bump_type: options.bump_type,
dry_run: false,
no_tag: args.no_tag,
no_push: args.no_push,
plan: None,
run: Some(run_result),
},
},
0,
))
}
}