Skip to main content

pact_broker_cli/
main.rs

1pub mod cli;
2pub use cli::build_cli;
3
4use clap::ArgMatches;
5use clap::error::ErrorKind;
6use clap_complete::{Shell, generate_to};
7use tracing::span;
8
9use std::process::ExitCode;
10use std::str::FromStr;
11
12use crate::cli::otel::OtelConfig;
13use crate::cli::otel::init_logging;
14pub fn handle_matches(
15    matches: &Result<ArgMatches, clap::Error>,
16    raw_args: Option<Vec<String>>,
17) -> Result<(), ExitCode> {
18    let raw_args = if let Some(args) = raw_args {
19        args
20    } else {
21        std::env::args().skip(1).collect()
22    };
23    match matches {
24        Ok(results) => {
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 = 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,
55                endpoint: otel_exporter_endpoint.cloned(),
56                protocol: otel_exporter_protocol.cloned(),
57                log_level,
58            };
59            let tracer_provider = init_logging(otel_config);
60            let _tracer_provider_dropper;
61            if let Some(tp) = tracer_provider {
62                _tracer_provider_dropper = crate::cli::otel::TracerProviderDropper(tp);
63            }
64
65            let span = if tracing::Span::current().is_none() {
66                span!(tracing::Level::INFO, "pact-broker-cli")
67            } else {
68                tracing::Span::current()
69            };
70            let _enter = span.enter();
71
72            match results.subcommand() {
73                Some(("pactflow", args)) => match cli::pactflow_client::run(args) {
74                    Ok(_) => Ok(()),
75                    Err(error) => Err(ExitCode::from(error as u8)),
76                },
77                Some(("completions", args)) => {
78                    generate_completions(args);
79                    Ok(())
80                }
81                _ => match cli::pact_broker_client::run(results, raw_args) {
82                    Ok(_) => Ok(()),
83                    Err(error) => Err(ExitCode::from(error as u8)),
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}