use clap::{arg, Args, Parser, Subcommand};
use dotenv::dotenv;
use rujira::{agile, api, Rujira};
use serde_json::json;
use tracing_subscriber::{fmt, EnvFilter};
#[derive(Parser, Debug)]
#[command(name = "itcast")]
pub struct Cli {
#[command(subcommand)]
command: Commands,
}
#[derive(Debug, Subcommand)]
enum Commands {
Project(ProjectArgs),
Issue(IssueArgs),
Board(BoardArgs),
Sprint(SprintArgs),
Myself,
}
#[derive(Debug, Args)]
struct ProjectArgs {
#[command(subcommand)]
command: ProjectCommands,
}
#[derive(Debug, Args)]
struct IssueArgs {
#[command(subcommand)]
command: IssueCommands,
}
#[derive(Debug, Args)]
struct BoardArgs {
#[command(subcommand)]
command: BoardCommands,
}
#[derive(Debug, Args)]
struct SprintArgs {
#[command(subcommand)]
command: SprintCommands,
}
#[derive(Debug, Subcommand)]
enum ProjectCommands {
Create {
key: String,
#[arg(short, long)]
name: String,
#[arg(short, long, default_value_t = String::from("software"))]
r#type: String,
#[arg(short, long)]
lead: String,
},
Delete {
key: String,
},
Update {
key: String,
#[arg(short, long)]
expand: Option<String>,
#[arg(short, long)]
update: String,
},
List {
#[arg(short, long)]
include_archive: Option<bool>,
#[arg(short, long)]
browse_archive: Option<bool>,
#[arg(short, long)]
expand: Option<String>,
#[arg(short, long)]
recent: Option<u8>,
},
}
#[derive(Debug, Subcommand)]
enum IssueCommands {
Create {
project: String,
#[arg(short, long)]
summary: String,
#[arg(short, long)]
description: String,
#[arg(short, long, default_value_t = String::from("Task"))]
r#type: String,
},
Edit {
key: String,
#[arg(short, long)]
sprint: String,
},
Get {
key: String,
},
Delete {
key: String,
},
}
#[derive(Debug, Subcommand)]
enum BoardCommands {
Get { key: String },
List {},
}
#[derive(Debug, Subcommand)]
enum SprintCommands {
List { board: String },
Get { key: String },
Issue { key: String, task: String },
}
#[tokio::main]
async fn main() {
dotenv().ok();
fmt()
.with_env_filter(EnvFilter::from_default_env())
.compact()
.init();
let bot = Rujira::new().from_env_handler();
let args = Cli::parse();
match args.command {
Commands::Myself => {
let me = match crate::api::myself::get(bot).apply().await {
Ok(rs) => rs,
Err(e) => {
eprintln!("{e}");
panic!();
}
};
println!("{me:#?}");
}
Commands::Issue(s) => match s.command {
IssueCommands::Create {
project,
summary,
description,
r#type,
} => {
let fields = json!({
"project": { "key": &project },
"summary": &summary,
"description": &description,
"issuetype": { "name": &r#type },
});
let issue = crate::api::issue::create(bot.clone(), fields, false)
.apply()
.await
.unwrap();
println!("{issue:#?}");
}
IssueCommands::Edit { key, sprint } => {
let payload = json!({
"sprint": { "name": sprint }
});
let issue = crate::api::issue::edit(bot.clone(), &key, None, Some(payload), None)
.apply()
.await
.unwrap();
println!("{issue:#?}");
}
IssueCommands::Get { key } => {
let issue = crate::api::issue::get(bot.clone(), &key, None, None, None, None)
.apply()
.await
.unwrap();
println!("{issue:#?}");
}
_ => todo!(),
},
Commands::Project(s) => match s.command {
ProjectCommands::Update {
key,
update,
expand,
} => {
let update = serde_json::from_str(&update).unwrap();
let project = api::project::update(bot.clone(), &key, update, expand.as_deref())
.apply()
.await
.unwrap();
println!("{project:#?}");
}
ProjectCommands::List {
include_archive,
browse_archive,
expand,
recent,
} => {
let projects = api::project::list(
bot.clone(),
include_archive,
browse_archive,
expand.as_deref(),
recent,
)
.apply()
.await
.unwrap();
println!("{projects:#?}");
}
ProjectCommands::Create {
key,
name,
r#type,
lead,
} => {
api::project::create(bot.clone(), &key, &name, &r#type, &lead)
.apply()
.await
.unwrap();
}
ProjectCommands::Delete { key } => {
api::project::delete(bot.clone(), &key)
.apply()
.await
.unwrap();
}
},
Commands::Board(s) => match s.command {
BoardCommands::List {} => {
let boards = agile::board::list(bot.clone(), None, None, None, None, None)
.apply()
.await
.unwrap();
println!("{boards:#?}");
}
BoardCommands::Get { key } => {
let board = agile::board::get(bot.clone(), &key).apply().await.unwrap();
println!("{board:#?}");
}
},
Commands::Sprint(s) => match s.command {
SprintCommands::List { board } => {
let sprints = agile::sprint::list(bot.clone(), &board, None, None, None)
.apply()
.await
.unwrap();
println!("{sprints:#?}");
}
SprintCommands::Get { key } => {
let sprint = agile::sprint::get(bot.clone(), &key).apply().await.unwrap();
println!("{sprint:#?}");
}
SprintCommands::Issue { key, task } => {
let payload = json!([task]);
let sprint = agile::sprint::issue(bot.clone(), &key, payload)
.apply()
.await
.unwrap();
println!("{sprint:#?}");
}
},
}
}