Skip to main content

wekan_cli/
lib.rs

1pub mod app;
2pub mod cli;
3pub mod client;
4pub mod command_result;
5pub mod commands;
6pub mod config;
7pub mod credentials;
8pub mod error;
9pub mod exit_code;
10pub mod input;
11pub mod output;
12pub mod redaction;
13
14use std::{
15    env,
16    ffi::OsString,
17    io::{self, Write},
18    process::ExitCode,
19};
20
21use clap::{CommandFactory, Parser, error::ErrorKind};
22
23use crate::{
24    app::App,
25    cli::Cli,
26    config::ServerSelection,
27    error::AppError,
28    output::{OutputFormat, render_error, write_success},
29};
30
31/// Parse the process arguments, execute one command, render its result, and
32/// return the stable process exit code.
33pub async fn run() -> ExitCode {
34    let args: Vec<OsString> = env::args_os().collect();
35    let cli = match Cli::try_parse_from(&args) {
36        Ok(cli) => cli,
37        Err(error)
38            if matches!(
39                error.kind(),
40                ErrorKind::DisplayHelp | ErrorKind::DisplayVersion
41            ) =>
42        {
43            let code = error.exit_code();
44            let _ = error.print();
45            return ExitCode::from(code as u8);
46        }
47        Err(error) => {
48            let requested_output = OutputFormat::detect_from_args(&args);
49            let app_error = AppError::invalid_input(error.to_string());
50            eprintln!("{}", render_error(requested_output, &app_error));
51            return app_error.exit_code().into();
52        }
53    };
54
55    let output_format = cli.output;
56    if let Err(error) = cli.command.validate_output(output_format) {
57        eprintln!("{}", render_error(output_format, &error));
58        return error.exit_code().into();
59    }
60    let app = App::production_with_confirmation_interactivity(
61        ServerSelection::new(cli.server, cli.profile_name, cli.allow_insecure_http),
62        output_format != OutputFormat::Json,
63    );
64
65    match app.execute(cli.command).await {
66        Ok(success) => {
67            let mut stdout = io::stdout().lock();
68            let mut stderr = io::stderr().lock();
69            match write_success(output_format, success, &mut stdout, &mut stderr).await {
70                Ok(exit_code) => exit_code,
71                Err(error) => {
72                    let _ = writeln!(stderr, "{}", render_error(output_format, &error));
73                    error.exit_code().into()
74                }
75            }
76        }
77        Err(error) => {
78            eprintln!("{}", render_error(output_format, &error));
79            error.exit_code().into()
80        }
81    }
82}
83
84/// Return the generated Clap command for completion and contract tests.
85pub fn command() -> clap::Command {
86    Cli::command()
87}