1pub mod cli;
2pub mod client;
3pub mod commands;
4pub mod config;
5pub mod error;
6pub mod output;
7
8use clap::Parser;
9use cli::Cli;
10use error::AppError;
11
12pub struct CommandContext {
13 pub config: config::Config,
14 pub client: client::LinearClient,
15 pub output: output::Output,
16}
17
18impl CommandContext {
19 pub fn from_cli(cli: &Cli) -> Result<Self, AppError> {
20 let config = config::Config::load(cli.endpoint.clone(), cli.workspace.clone())?;
21 let token = config::api_key()?;
22 Ok(Self {
23 client: client::LinearClient::new(config.endpoint.clone(), token)?,
24 config,
25 output: output::Output::new(cli.format.clone(), cli.full),
26 })
27 }
28}
29
30pub fn run() -> Result<(), AppError> {
31 let cli = Cli::try_parse().map_err(|e| AppError::usage(e.to_string()))?;
32 cli.execute()
33}
34
35pub fn run_with(cli: Cli) -> Result<(), AppError> {
36 cli.execute()
37}
38
39pub fn main_exit() -> std::process::ExitCode {
40 match Cli::try_parse() {
41 Ok(cli) => {
42 let format = cli.format.clone();
43 match cli.execute() {
44 Ok(()) => std::process::ExitCode::SUCCESS,
45 Err(error) => {
46 error::print(&error, &format);
47 std::process::ExitCode::from(error.exit_code())
48 }
49 }
50 }
51 Err(error)
52 if matches!(
53 error.kind(),
54 clap::error::ErrorKind::DisplayHelp | clap::error::ErrorKind::DisplayVersion
55 ) =>
56 {
57 print!("{error}");
58 std::process::ExitCode::SUCCESS
59 }
60 Err(error) => {
61 let error = AppError::usage(error.to_string());
62 error::print(&error, "toon");
63 std::process::ExitCode::from(2)
64 }
65 }
66}