use crate::cli::args::*;
use clap::{CommandFactory, Parser};
use clap_complete::generate;
use pinto::i18n::{Message, current};
use pinto::service::BoardQuery;
use std::process::ExitCode;
use super::{
build_search_filter, dispatch, format_anyhow_error, resolve_label_filter, resolve_label_match,
};
pub(super) async fn cmd_shell() -> anyhow::Result<ExitCode> {
use rustyline::error::ReadlineError;
let localizer = current();
let mut editor = crate::cli::shell::build_editor()?;
loop {
let readline = tokio::task::block_in_place(|| editor.readline("pinto> "));
let line = match readline {
Ok(line) => line,
Err(ReadlineError::Interrupted) => continue,
Err(ReadlineError::Eof) => break,
Err(e) => {
eprintln!("{} {e}", localizer.text(Message::ErrorPrefix));
break;
}
};
let trimmed = line.trim();
if trimmed.is_empty() {
continue;
}
let _ = editor.add_history_entry(trimmed);
if trimmed == "exit" || trimmed == "quit" || trimmed == "q" {
break;
}
let argv = match crate::cli::shell::split_args(trimmed) {
Ok(argv) => argv,
Err(e) => {
eprintln!(
"{}",
localizer.format(
Message::ShellParseError,
[("error", e.to_string().as_str())]
)
);
continue;
}
};
if argv.is_empty() {
continue;
}
let parsed = Cli::try_parse_from(std::iter::once("pinto".to_string()).chain(argv));
match parsed {
Err(e) => {
let _ = e.print();
}
Ok(cli) if matches!(cli.command, Command::Shell) => {
eprintln!("{}", current().text(Message::AlreadyInInteractiveShell));
}
Ok(cli) => {
if let Err(e) = Box::pin(dispatch(cli, true)).await {
eprintln!(
"{} {}",
localizer.text(Message::ErrorPrefix),
format_anyhow_error(&e, localizer)
);
}
}
}
}
Ok(ExitCode::SUCCESS)
}
pub(super) async fn cmd_kanban(args: KanbanArgs, in_shell: bool) -> anyhow::Result<ExitCode> {
let labels = resolve_label_filter("--label", args.label, false)?;
let label_match = resolve_label_match(args.all_labels, &labels)?;
let query = BoardQuery {
sprint: args.sprint,
labels,
label_match,
search: build_search_filter(args.search, args.regex)?,
..BoardQuery::default()
};
let mode = crate::cli::kanban::run(args.column.as_deref(), args.maximize, query).await?;
if mode == crate::cli::kanban::ExitMode::Shell && !in_shell {
return cmd_shell().await;
}
Ok(ExitCode::SUCCESS)
}
pub(super) fn cmd_completion(args: CompletionArgs) -> anyhow::Result<ExitCode> {
let mut cmd = Cli::command();
let bin_name = cmd.get_name().to_string();
generate(args.shell, &mut cmd, bin_name, &mut std::io::stdout());
Ok(ExitCode::SUCCESS)
}