pact_broker_cli/
main.rs

1pub mod cli;
2
3use clap::ArgMatches;
4use clap::error::ErrorKind;
5use clap_complete::{Shell, generate_to};
6use tracing::span;
7
8use std::process::ExitCode;
9use std::str::FromStr;
10
11use crate::cli::otel::OtelConfig;
12use crate::cli::otel::init_logging;
13pub fn handle_matches(
14    matches: &Result<ArgMatches, clap::Error>,
15    raw_args: Option<Vec<String>>,
16) -> Result<(), ExitCode> {
17    let raw_args = if let Some(args) = raw_args {
18        args
19    } else {
20        std::env::args().skip(1).collect()
21    };
22    match matches {
23        Ok(results) => match results.subcommand() {
24            _ => {
25                let (
26                    enable_otel,
27                    enable_otel_logs,
28                    enable_otel_traces,
29                    otel_exporter,
30                    otel_exporter_endpoint,
31                    otel_exporter_protocol,
32                    log_level,
33                ) = match &matches {
34                    Ok(m) => (
35                        m.get_flag("enable-otel"),
36                        m.get_flag("enable-otel-logs"),
37                        m.get_flag("enable-otel-traces"),
38                        m.get_one::<String>("otel-exporter").map(|s| {
39                            s.split(',')
40                                .map(|v| v.trim().to_string())
41                                .collect::<Vec<String>>()
42                        }),
43                        m.get_one::<String>("otel-exporter-endpoint"),
44                        m.get_one::<String>("otel-exporter-protocol"),
45                        m.get_one::<String>("log-level")
46                            .and_then(|lvl| lvl.parse::<tracing::Level>().ok()),
47                    ),
48                    Err(_) => (false, false, false, None, None, None, None),
49                };
50                let otel_config = Some(OtelConfig {
51                    enable_otel: Some(enable_otel),
52                    enable_logs: Some(enable_otel_logs),
53                    enable_traces: Some(enable_otel_traces),
54                    exporter: otel_exporter.map(|v| v.clone()),
55                    endpoint: otel_exporter_endpoint.cloned(),
56                    protocol: otel_exporter_protocol.cloned(),
57                    log_level,
58                });
59                let tracer_provider = init_logging(otel_config.unwrap());
60                let _tracer_provider_dropper;
61                if tracer_provider.is_some() {
62                    let tracer_provider = tracer_provider.unwrap().clone();
63                    _tracer_provider_dropper =
64                        crate::cli::otel::TracerProviderDropper(tracer_provider);
65                }
66
67                let span = if tracing::Span::current().is_none() {
68                    span!(tracing::Level::INFO, "pact-broker-cli")
69                } else {
70                    tracing::Span::current()
71                };
72                let _enter = span.enter();
73
74                match results.subcommand() {
75                    Some(("pactflow", args)) => match cli::pactflow_client::run(args, raw_args) {
76                        Ok(_) => Ok(()),
77                        Err(error) => Err(ExitCode::from(error as u8)),
78                    },
79                    Some(("completions", args)) => Ok(generate_completions(args)),
80                    _ => match cli::pact_broker_client::run(results, raw_args) {
81                        Ok(_) => Ok(()),
82                        Err(error) => Err(ExitCode::from(error as u8)),
83                    },
84                }
85            }
86        },
87        Err(err) => match err.kind() {
88            ErrorKind::DisplayHelp => {
89                let _ = err.print();
90                Ok(())
91            }
92            ErrorKind::DisplayVersion => {
93                let _ = err.print();
94                Ok(())
95            }
96            ErrorKind::DisplayHelpOnMissingArgumentOrSubcommand => {
97                let _ = err.print();
98                Ok(())
99            }
100            _ => err.exit(),
101        },
102    }
103}
104
105fn generate_completions(args: &ArgMatches) {
106    let shell = args
107        .get_one::<String>("shell")
108        .expect("a shell is required");
109    let out_dir = args
110        .get_one::<String>("dir")
111        .expect("a directory is expected")
112        .to_string();
113    let mut cmd = cli::build_cli();
114    let shell_enum = Shell::from_str(&shell).unwrap();
115    let _ = generate_to(
116        shell_enum,
117        &mut cmd,
118        "pact-broker-cli".to_string(),
119        &out_dir,
120    );
121    println!(
122        "ℹ️  {} shell completions for pact-broker-cli written to {}",
123        &shell_enum, &out_dir
124    );
125}