use bomper::error::Result;
use bomper::versioning::{determine_increment, Commit, VersionIncrement};
use clap::Parser;
use std::path::PathBuf;
#[derive(Parser, Debug)]
#[command(author, about, version)]
pub struct Args {
#[clap(flatten)]
pub base_args: BaseArgs,
#[clap(subcommand)]
pub command: Commands,
}
#[derive(clap::Args, Debug)]
pub(crate) struct BaseArgs {
#[arg(short, long)]
pub config_file: Option<PathBuf>,
#[arg(short, long)]
pub repository: Option<PathBuf>,
}
#[derive(clap::Subcommand, Debug)]
pub(crate) enum Commands {
RawBump(RawBump),
Bump(Bump),
Changelog(Changelog),
}
#[derive(clap::Args, Debug)]
pub(crate) struct RawBump {
pub old_version: String,
pub new_version: String,
#[arg(short, long)]
pub dry_run: bool,
}
#[derive(clap::Args, Debug)]
pub(crate) struct Bump {
#[clap(flatten)]
pub options: BumpOptions,
#[arg(short, long)]
pub comment: bool,
#[arg(short, long)]
pub dry_run: bool,
}
#[derive(clap::Args, Debug)]
pub(crate) struct Changelog {
#[arg(long)]
pub at: Option<semver::Version>,
#[arg(short, long)]
pub no_decorations: bool,
#[arg(short, long, requires = "no_decorations")]
pub only_current_version: bool,
}
#[derive(clap::Args, Debug)]
#[command(group = clap::ArgGroup::new("bump-type").required(true))]
#[allow(clippy::struct_excessive_bools)]
pub(crate) struct BumpOptions {
#[arg(short, long, group = "bump-type")]
pub version: Option<String>,
#[arg(short, long, group = "bump-type")]
pub automatic: bool,
#[arg(short = 'M', long, group = "bump-type")]
pub major: bool,
#[arg(short, long, group = "bump-type")]
pub minor: bool,
#[arg(short, long, group = "bump-type")]
pub patch: bool,
}
impl BumpOptions {
pub(crate) fn determine_increment<'a, I: IntoIterator<Item = &'a Commit>>(
&self,
commits: I,
current_version: &semver::Version,
) -> Result<VersionIncrement> {
match &self.version {
Some(version) => Ok(VersionIncrement::Manual(semver::Version::parse(version)?)),
None if self.automatic => {
let conventional_commits = commits.into_iter().map(std::convert::AsRef::as_ref);
Ok(determine_increment(conventional_commits, current_version))
}
None if self.major => Ok(VersionIncrement::Major),
None if self.minor => Ok(VersionIncrement::Minor),
None if self.patch => Ok(VersionIncrement::Patch),
_ => unreachable!(),
}
}
}