use clap::Args;
use serde::Serialize;
use homeboy::context;
use homeboy::git::{self, ChangesOutput};
use homeboy::project;
use homeboy::BulkResult;
use super::CmdResult;
#[derive(Args)]
pub struct ChangesArgs {
pub target_id: Option<String>,
pub component_ids: Vec<String>,
#[arg(long)]
pub project: Option<String>,
#[arg(long)]
pub json: Option<String>,
#[arg(long)]
pub since: Option<String>,
#[arg(long)]
pub git_diffs: bool,
}
#[derive(Serialize)]
#[serde(untagged)]
pub enum ChangesCommandOutput {
Single(Box<ChangesOutput>),
Bulk(BulkResult<ChangesOutput>),
}
pub fn run(
args: ChangesArgs,
_global: &crate::commands::GlobalArgs,
) -> CmdResult<ChangesCommandOutput> {
if let Some(json) = &args.json {
let output = git::changes_bulk(json, args.git_diffs)?;
let exit_code = if output.summary.failed > 0 { 1 } else { 0 };
return Ok((ChangesCommandOutput::Bulk(output), exit_code));
}
if let Some(project_id) = &args.project {
if args.component_ids.is_empty() {
let output = git::changes_project(project_id, args.git_diffs)?;
let exit_code = if output.summary.failed > 0 { 1 } else { 0 };
return Ok((ChangesCommandOutput::Bulk(output), exit_code));
} else {
let output =
git::changes_project_filtered(project_id, &args.component_ids, args.git_diffs)?;
let exit_code = if output.summary.failed > 0 { 1 } else { 0 };
return Ok((ChangesCommandOutput::Bulk(output), exit_code));
}
}
if let Some(target_id) = &args.target_id {
if !args.component_ids.is_empty() {
let output =
git::changes_project_filtered(target_id, &args.component_ids, args.git_diffs)?;
let exit_code = if output.summary.failed > 0 { 1 } else { 0 };
return Ok((ChangesCommandOutput::Bulk(output), exit_code));
}
match git::changes(Some(target_id), args.since.as_deref(), args.git_diffs) {
Ok(output) => return Ok((ChangesCommandOutput::Single(Box::new(output)), 0)),
Err(e) => {
if project::exists(target_id) {
let output = git::changes_project(target_id, args.git_diffs)?;
let exit_code = if output.summary.failed > 0 { 1 } else { 0 };
return Ok((ChangesCommandOutput::Bulk(output), exit_code));
}
return Err(e);
}
}
}
let (ctx, _) = context::run(None)?;
let mut err = homeboy::Error::validation_invalid_argument(
"input",
"No component ID provided",
None,
None,
);
if ctx.managed && ctx.matched_components.len() == 1 {
err = err.with_hint(format!("Detected component: {}", ctx.matched_components[0]));
}
err =
err.with_hint("Run 'homeboy init' to see available components, or specify one explicitly:");
err = err.with_hint(" homeboy changes <component-id>");
Err(err)
}