mod config;
mod events;
mod jira;
mod sources;
mod subcommands;
mod tui;
use anyhow::{Context, Result};
use clap::{Parser, Subcommand};
#[derive(Parser)]
#[command(name = "do-next", about = "Pick your next Jira task")]
struct Cli {
#[arg(long, value_name = "FILE")]
log: Option<std::path::PathBuf>,
#[command(subcommand)]
command: Option<Commands>,
}
#[derive(Subcommand)]
enum Commands {
Comment {
issue_key: Option<String>,
#[arg(long)]
no_history: bool,
},
Fields {
issue_key: String,
#[arg(long, value_name = "FIELD_ID")]
field: Option<String>,
#[arg(long, requires = "field")]
raw: bool,
},
Auth,
}
#[tokio::main]
async fn main() -> Result<()> {
let cli = Cli::parse();
if let Some(ref log_path) = cli.log {
use simplelog::{Config, LevelFilter, WriteLogger};
let file = std::fs::File::create(log_path)
.with_context(|| format!("Failed to create log file: {}", log_path.display()))?;
WriteLogger::init(LevelFilter::Debug, Config::default(), file)
.context("Failed to initialise logger")?;
log::info!("do-next starting, logging to {}", log_path.display());
}
let (mut config, project_override) = config::load().context("Failed to load configuration")?;
if matches!(&cli.command, Some(Commands::Auth)) {
tui::onboarding::run_auth_reset(&mut config).context("Auth reset failed")?;
return Ok(());
}
if config.jira.base_url.is_empty() {
config = tui::onboarding::run_onboarding().context("Onboarding failed")?;
}
let credentials = config::credentials::resolve_credentials(&config.jira)
.context("Failed to resolve Jira credentials")?;
let client = jira::JiraClient::new(config.jira.base_url.clone(), credentials)
.context("Failed to create Jira client")?;
match cli.command {
Some(Commands::Comment {
issue_key,
no_history,
}) => {
subcommands::comment::run(&client, issue_key.as_deref(), no_history).await?;
}
Some(Commands::Fields {
issue_key,
field,
raw,
}) => {
subcommands::fields::run(&client, &issue_key, field.as_deref(), raw).await?;
}
Some(Commands::Auth) => unreachable!("handled before credential resolution"),
None => {
tui::run(config, client, project_override).await?;
}
}
Ok(())
}