use clap::{ArgAction, Args, Parser, Subcommand, ValueEnum};
use std::error::Error;
#[derive(Parser, Debug)]
#[command(author, version, about, long_about = None)]
pub struct JirustCliArgs {
#[clap(subcommand)]
pub subcmd: Commands,
}
#[derive(Subcommand, Debug)]
pub enum Commands {
Config(ConfigArgs),
Issue(IssueArgs),
Project(ProjectArgs),
Transition(TransitionArgs),
Version(VersionArgs),
}
#[derive(Args, Debug)]
pub struct PaginationArgs {
#[clap(
long,
short = 'l',
value_name = "page_size",
help = "page size for lists"
)]
pub page_size: Option<i32>,
#[clap(
long,
short = 's',
value_name = "page_offset",
help = "page offset for list"
)]
pub page_offset: Option<i64>,
}
#[derive(ValueEnum, Debug, Clone, Copy)]
#[value(rename_all = "kebab-case")]
pub enum OutputValues {
#[value(name = "table", help = "Print output in table format")]
Table,
#[value(name = "json", help = "Print output in json format")]
Json,
}
#[derive(Args, Debug)]
pub struct OutputArgs {
#[clap(long, short = 'o', value_name = "table|json", help = "Output format")]
pub output: Option<OutputValues>,
}
#[derive(Args, Debug)]
pub struct ConfigArgs {
#[arg(
value_name = "auth|jira|setup|show",
help_heading = "Configuration management"
)]
pub cfg_act: ConfigActionValues,
}
#[derive(ValueEnum, Debug, Clone, Copy)]
#[value(rename_all = "kebab-case")]
pub enum ConfigActionValues {
#[value(name = "auth", help = "Set Jira API authentication (username, apikey)")]
Auth,
#[value(name = "jira", help = "Set Jira API base URL")]
Jira,
#[value(
name = "setup",
help = "Setup Jira API configuration (authentication data, jira base URL, etc.)"
)]
Setup,
#[value(name = "show", help = "Show current configuration")]
Show,
}
#[derive(Args, Debug)]
pub struct VersionArgs {
#[arg(
value_name = "archive|create|delete|list|release|update",
help_heading = "Jira Project version management"
)]
pub version_act: VersionActionValues,
#[clap(
long,
short = 'k',
value_name = "project_key",
required = true,
help = "Jira Project key"
)]
pub project_key: String,
#[clap(long, short = 'i', value_name = "project_id", help = "Jira Project ID")]
pub project_id: Option<i64>,
#[clap(
long,
short = 'v',
value_name = "version_id",
help = "Jira Project version ID"
)]
pub version_id: Option<String>,
#[clap(
long,
short = 'n',
value_name = "version_name",
help = "Jira Project version name"
)]
pub version_name: Option<String>,
#[clap(
long,
short = 'd',
value_name = "version_description",
help = "Jira Project version description"
)]
pub version_description: Option<String>,
#[clap(
long,
value_name = "version_start_date",
help = "Jira Project version start date"
)]
pub version_start_date: Option<String>,
#[clap(
long,
value_name = "version_release_date",
help = "Jira Project version release date"
)]
pub version_release_date: Option<String>,
#[clap(
long,
short = 'a',
value_name = "version_archived",
help = "Jira Project version archived"
)]
pub version_archived: Option<bool>,
#[clap(
long,
short = 'r',
value_name = "version_released",
help = "Jira Project version released"
)]
pub version_released: Option<bool>,
#[clap(
long,
short = 'c',
value_name = "changelog_file",
help = "changelog file path to be used for automatic description generation (if set the script detects automatically the first tagged block in the changelog and use it as description)"
)]
pub changelog_file: Option<String>,
#[clap(
long,
short = 't',
action = ArgAction::SetTrue,
value_name = "resolve_issues",
help = "if changelog is set and this flag is set, the script will transition all issues in the changelog of the current version release to the \"resolved\" status setting the version as \"fixVersion\""
)]
pub transition_issues: Option<bool>,
#[clap(
long,
short = 'u',
value_name = "transition_assignee",
help = "if changelog is set and the resolve_issues flag is set, the script will assigned all the resolved issue to the user specified in this field (if not set the assignee will not be changed)"
)]
pub transition_assignee: Option<String>,
#[clap(flatten)]
pub pagination: PaginationArgs,
#[clap(flatten)]
pub output: OutputArgs,
}
#[derive(ValueEnum, Debug, Clone, Copy)]
#[value(rename_all = "kebab-case")]
pub enum VersionActionValues {
#[value(name = "archive", help = "Archive a Jira Project version")]
Archive,
#[value(name = "create", help = "Create a Jira Project version")]
Create,
#[value(name = "delete", help = "Delete a Jira Project version")]
Delete,
#[value(name = "list", help = "List Jira Project versions")]
List,
#[value(name = "release", help = "Release a Jira Project version")]
Release,
#[value(name = "update", help = "Update a Jira Project version")]
Update,
}
#[derive(Args, Debug)]
pub struct ProjectArgs {
#[arg(
value_name = "get-issue-types|get-issue-type-fields|list",
help_heading = "Jira Project management",
required = true
)]
pub project_act: ProjectActionValues,
#[clap(
long,
short = 'k',
value_name = "project_key",
help = "Jira Project key",
required = true
)]
pub project_key: Option<String>,
#[clap(
long,
short = 'i',
value_name = "project_issue_type",
help = "Jira Project issue type ID"
)]
pub project_issue_type: Option<String>,
#[clap(flatten)]
pub pagination: PaginationArgs,
#[clap(flatten)]
pub output: OutputArgs,
}
#[derive(ValueEnum, Debug, Clone, Copy)]
#[value(rename_all = "kebab-case")]
pub enum ProjectActionValues {
#[value(
name = "get-issue-types",
help = "Get Jira Project issue types by Jira project key"
)]
GetIssueTypes,
#[value(
name = "get-issue-type-fields",
help = "Get Jira Project issue type fields by Jira project key and issue type ID"
)]
GetIssueTypeFields,
#[value(name = "list", help = "List Jira Projects")]
List,
}
#[derive(Args, Debug)]
pub struct IssueArgs {
#[arg(
value_name = "assign|create|delete|get|transition|update",
help_heading = "Jira Project issue management"
)]
pub issue_act: IssueActionValues,
#[clap(
long,
short = 'p',
value_name = "project_key",
help = "Jira Project key",
required = true
)]
pub project_key: String,
#[clap(
long,
short = 'i',
value_name = "issue_key",
help = "Jira Project issue key",
required = true
)]
pub issue_key: Option<String>,
#[clap(long,
short = 'f',
value_name = "issue_fields",
value_parser = parse_key_val::<String, String>,
help = "Jira Project issue fields (field_name=value)")]
pub issue_fields: Option<Vec<(String, String)>>,
#[clap(
long,
short = 't',
value_name = "transition_to",
help = "Jira Project issue transition to"
)]
pub transition_to: Option<String>,
#[clap(
long,
short = 'a',
value_name = "assignee",
help = "Jira Project issue assignee"
)]
pub assignee: Option<String>,
#[clap(flatten)]
pub pagination: PaginationArgs,
#[clap(flatten)]
pub output: OutputArgs,
}
#[derive(ValueEnum, Debug, Clone, Copy)]
#[value(rename_all = "kebab-case")]
pub enum IssueActionValues {
#[value(name = "assign", help = "Assign a Jira Project issue")]
Assign,
#[value(name = "create", help = "Create a Jira Project issue")]
Create,
#[value(name = "delete", help = "Delete a Jira Project issue")]
Delete,
#[value(name = "get", help = "Get a specific Jira Project issue")]
Get,
#[value(name = "transition", help = "Transition a Jira Project issue")]
Transition,
#[value(name = "update", help = "Update a Jira Project issue")]
Update,
}
#[derive(Args, Debug)]
pub struct TransitionArgs {
#[arg(value_name = "list", help_heading = "Jira issue transition list")]
pub transition_act: TransitionActionValues,
#[clap(
long,
short = 'i',
value_name = "issue_key",
help = "Jira Project issue key",
required = true
)]
pub issue_key: String,
#[clap(flatten)]
pub output: OutputArgs,
}
#[derive(ValueEnum, Debug, Clone, Copy)]
#[value(rename_all = "kebab-case")]
pub enum TransitionActionValues {
#[value(name = "list", help = "List Jira issue available transitions")]
List,
}
fn parse_key_val<T, U>(s: &str) -> Result<(T, U), Box<dyn Error + Send + Sync + 'static>>
where
T: std::str::FromStr,
T::Err: Error + Send + Sync + 'static,
U: std::str::FromStr,
U::Err: Error + Send + Sync + 'static,
{
let pos = s
.find('=')
.ok_or_else(|| format!("invalid KEY=value: no `=` found in `{s}`"))?;
Ok((s[..pos].parse()?, s[pos + 1..].parse()?))
}