use clap::builder::styling::{AnsiColor, Effects, Styles};
use clap::{Args, Parser, Subcommand};
fn styles() -> Styles {
Styles::styled()
.header(AnsiColor::Green.on_default() | Effects::BOLD)
.usage(AnsiColor::Green.on_default() | Effects::BOLD)
.literal(AnsiColor::Cyan.on_default() | Effects::BOLD)
.placeholder(AnsiColor::Cyan.on_default())
.error(AnsiColor::Red.on_default() | Effects::BOLD)
.valid(AnsiColor::Cyan.on_default() | Effects::BOLD)
.invalid(AnsiColor::Yellow.on_default() | Effects::BOLD)
}
#[derive(Args, Debug, Default)]
pub struct B2bPlanArgs {
#[arg(help = "Source branch to open the merge/pull request from")]
pub source: String,
#[arg(help = "Target branch to merge into")]
pub target: String,
#[arg(
short = 'c',
long,
help = "Categorize commits by conventional commit type and structure the description accordingly"
)]
pub conventional_commits: bool,
#[arg(
long,
help = "Path to the git repository [default: present working directory]"
)]
pub dir: Option<String>,
#[arg(long, default_value = "origin", help = "Name of the git remote to use")]
pub remote: String,
#[arg(
long,
help = "Title to use for the merge/pull request [default: 'Release Candidate vX.Y.Z']"
)]
pub title: Option<String>,
#[arg(long, help = "Description to use for the merge/pull request")]
pub description: Option<String>,
#[arg(long, help = "Only include merge commits in the discovered commits")]
pub only_merges: bool,
#[arg(
long,
help = "Do not append the 'generated by Shipit' line to the created description"
)]
pub no_sign: bool,
#[arg(
short = 'y',
long,
help = "Automatically approve all shipit command prompts"
)]
pub yes: bool,
#[arg(
long,
help = "Emit the plan as YAML to stdout (useful for piping to yq)"
)]
pub yaml: bool,
#[arg(
long,
help = "Continue even if the working directory has uncommitted changes"
)]
pub allow_dirty: bool,
}
#[derive(Args, Debug)]
pub struct B2bApplyArgs {
#[arg(help = "Name of the plan file in .shipit/plans/ to apply")]
pub plan: String,
#[arg(
long,
help = "Path to the git repository [default: present working directory]"
)]
pub dir: Option<String>,
#[arg(long, default_value = "origin", help = "Name of the git remote to use")]
pub remote: String,
#[arg(
long,
help = "Continue even if the working directory has uncommitted changes"
)]
pub allow_dirty: bool,
#[arg(
short = 'y',
long,
help = "Automatically approve all shipit command prompts"
)]
pub yes: bool,
}
#[derive(Subcommand, Debug)]
pub enum B2bSubcommand {
Plan(B2bPlanArgs),
Apply(B2bApplyArgs),
}
#[derive(Args, Debug)]
pub struct B2bArgs {
#[command(subcommand)]
pub command: B2bSubcommand,
}
#[derive(Args, Debug, Default)]
pub struct B2tPlanArgs {
#[arg(help = "Branch to create the tag on")]
pub branch: String,
#[arg(help = "Name of the tag to create")]
pub tag: Option<String>,
#[arg(
short = 'c',
long,
help = "Categorize commits by conventional commit type and structure the notes accordingly"
)]
pub conventional_commits: bool,
#[arg(
long,
help = "Path to the git repository [default: present working directory]"
)]
pub dir: Option<String>,
#[arg(long, default_value = "origin", help = "Name of the git remote to use")]
pub remote: String,
#[arg(long, help = "Description to use for the tag notes")]
pub description: Option<String>,
#[arg(long, help = "Only include merge commits in the discovered commits")]
pub only_merges: bool,
#[arg(
long,
help = "The most recent tag to compare against [default: most recent tag on the branch]"
)]
pub latest_tag: Option<String>,
#[arg(
long,
help = "Do not append the 'generated by Shipit' line to the tag notes"
)]
pub no_sign: bool,
#[arg(
short = 'y',
long,
help = "Automatically approve all shipit command prompts"
)]
pub yes: bool,
#[arg(
long,
help = "Emit the plan as YAML to stdout (useful for piping to yq)"
)]
pub yaml: bool,
#[arg(
long,
help = "Continue even if the working directory has uncommitted changes"
)]
pub allow_dirty: bool,
}
#[derive(Args, Debug)]
pub struct B2tApplyArgs {
#[arg(help = "Name of the plan file in .shipit/plans/ to apply")]
pub plan: String,
#[arg(
long,
help = "Path to the git repository [default: present working directory]"
)]
pub dir: Option<String>,
#[arg(long, default_value = "origin", help = "Name of the git remote to use")]
pub remote: String,
#[arg(
long,
help = "Continue even if the working directory has uncommitted changes"
)]
pub allow_dirty: bool,
#[arg(
short = 'y',
long,
help = "Automatically approve all shipit command prompts"
)]
pub yes: bool,
}
#[derive(Subcommand, Debug)]
pub enum B2tSubcommand {
Plan(B2tPlanArgs),
Apply(B2tApplyArgs),
}
#[derive(Args, Debug)]
pub struct B2tArgs {
#[command(subcommand)]
pub command: B2tSubcommand,
}
#[derive(Parser)]
#[command(styles = styles())]
#[command(version)]
#[command(subcommand_required = false)]
#[command(arg_required_else_help = true)]
pub struct Cli {
#[command(subcommand)]
pub command: Option<Commands>,
#[arg(
short = 'v',
long,
action = clap::ArgAction::Count,
global = true,
help = "Increase log verbosity (-v for info, -vv for debug)"
)]
pub verbose: u8,
#[arg(long, hide = true)]
pub markdown_help: bool,
}
#[derive(Subcommand, Debug)]
pub enum Commands {
#[command(visible_alias = "t2b")]
B2b(B2bArgs),
B2t(B2tArgs),
Init(InitArgs),
Claude(ClaudeArgs),
}
#[derive(Args, Debug, Default)]
pub struct InitArgs {
#[arg(
long,
help = "Directory to write the config file to [default: present working directory]"
)]
pub dir: Option<String>,
#[arg(long, help = "Platform personal access token")]
pub platform_token: Option<String>,
#[arg(long, help = "Platform domain")]
pub platform_domain: Option<String>,
#[arg(long, help = "Git remote to infer the platform domain from [default: origin]")]
pub remote: Option<String>,
#[arg(
short = 'y',
long,
help = "Automatically accept all prompts using inferred or discovered defaults"
)]
pub yes: bool,
}
#[derive(Args, Debug, Default)]
pub struct ClaudeArgs {}