1use clap::{Arg, Command};
2
3pub mod otel;
4pub mod pact_broker;
5pub mod pact_broker_client;
6pub mod pactflow;
7pub mod pactflow_client;
8pub mod utils;
9pub fn build_cli() -> Command {
10 let app = pact_broker_client::add_pact_broker_client_command()
11 .arg_required_else_help(true)
12 .version(env!("CARGO_PKG_VERSION"))
13 .about("A pact cli tool")
14 .args(add_otel_options_args())
15 .args(add_logging_arguments())
16 .subcommand(
17 pactflow_client::add_pactflow_client_command().version(env!("CARGO_PKG_VERSION")),
18 )
19 .subcommand(add_completions_subcommand());
20 app
21}
22
23fn add_otel_options_args() -> Vec<Arg> {
24 vec![
25 Arg::new("enable-otel")
26 .long("enable-otel")
27 .help("Enable OpenTelemetry tracing")
28 .global(true)
29 .action(clap::ArgAction::SetTrue),
31 Arg::new("enable-otel-logs")
32 .long("enable-otel-logs")
33 .help("Enable OpenTelemetry logging")
34 .global(true)
35 .action(clap::ArgAction::SetTrue),
37 Arg::new("enable-otel-traces")
38 .long("enable-otel-traces")
39 .help("Enable OpenTelemetry traces")
40 .global(true)
41 .action(clap::ArgAction::SetTrue),
43 Arg::new("otel-exporter")
44 .long("otel-exporter")
45 .help("The OpenTelemetry exporter(s) to use, comma separated (stdout, otlp)")
46 .num_args(1)
47 .global(true)
48 .env("OTEL_TRACES_EXPORTER")
50 .value_delimiter(',')
51 .value_parser(clap::builder::NonEmptyStringValueParser::new()),
52 Arg::new("otel-exporter-endpoint")
53 .long("otel-exporter-endpoint")
54 .help("The endpoint to use for the OTLP exporter (required if --otel-exporter=otlp)")
55 .num_args(1)
56 .global(true)
57 .requires_if("otlp", "otel-exporter")
59 .env("OTEL_EXPORTER_OTLP_ENDPOINT")
60 .value_parser(clap::builder::NonEmptyStringValueParser::new()),
61 Arg::new("otel-exporter-protocol")
62 .long("otel-exporter-protocol")
63 .help("The protocol to use for the OTLP exporter (http/protobuf, http)")
64 .num_args(1)
65 .global(true)
66 .default_value("http")
68 .requires_if("otlp", "otel-exporter")
69 .env("OTEL_EXPORTER_OTLP_PROTOCOL")
70 .value_parser(clap::builder::PossibleValuesParser::new(&[
71 "http",
72 "http/protobuf",
73 ])),
74 ]
75}
76
77pub fn add_logging_arguments() -> Vec<Arg> {
78 vec![
79 Arg::new("log-level")
80 .long("log-level")
81 .global(true)
82 .value_name("LEVEL")
83 .help("Set the log level (none, off, error, warn, info, debug, trace)")
84 .value_parser(clap::builder::PossibleValuesParser::new([
85 "off", "none", "error", "warn", "info", "debug", "trace",
86 ]))
87 .default_value("off")
88 .default_value_if("verbose", "true", Some("info")),
89 Arg::new("verbose")
90 .long("verbose")
91 .global(true)
92 .action(clap::ArgAction::SetTrue)
93 .help("DEPRECATED: Compatibility layer for pact_broker-client. Sets log level to info.")
94 .hide(true),
95 ]
96}
97pub fn add_output_arguments(
98 value_parser_args: Vec<&'static str>,
99 default_value: &'static str,
100) -> Vec<Arg> {
101 vec![
102 Arg::new("output")
103 .short('o')
104 .long("output")
105 .value_name("OUTPUT")
106 .value_parser(clap::builder::PossibleValuesParser::new(&value_parser_args))
107 .default_value(default_value)
108 .value_name("OUTPUT")
109 .help(format!("Value must be one of {:?}", value_parser_args)),
110 ]
111}
112
113pub fn add_ssl_arguments() -> Vec<Arg> {
114 vec![
115 Arg::new("ssl-certificate")
116 .short('c')
117 .long("ssl-certificate")
118 .num_args(1)
119 .help("The path to a valid SSL certificate file")
120 .required(false)
121 .value_name("SSL_CERT_FILE")
122 .env("SSL_CERT_FILE"),
123 Arg::new("skip-ssl-verification")
124 .long("skip-ssl-verification")
125 .num_args(0)
126 .help("Skip SSL certificate verification")
127 .required(false)
128 .value_name("SSL_SKIP_VERIFICATION")
129 .env("SSL_SKIP_VERIFICATION"),
130 Arg::new("ssl-trust-store")
131 .long("ssl-trust-store")
132 .num_args(1)
133 .default_value("true")
134 .value_parser(clap::builder::BoolValueParser::new())
135 .help("Use the system's root trust store for SSL verification")
136 .required(false)
137 .value_name("SSL_TRUST_STORE")
138 .env("SSL_TRUST_STORE"),
139 ]
140}
141
142fn add_completions_subcommand() -> Command {
143 Command::new("completions")
144 .about("Generates completion scripts for your shell")
145 .arg(Arg::new("shell")
146 .value_name("SHELL")
147 .required(true)
148 .value_parser(clap::builder::PossibleValuesParser::new(&["bash", "fish", "zsh", "powershell", "elvish"]))
149 .help("The shell to generate the script for"))
150 .arg(Arg::new("dir")
151 .short('d')
152 .long("dir")
153 .value_name("DIRECTORY")
154 .required(false)
155 .default_value(".")
156 .num_args(1)
157 .value_parser(clap::builder::NonEmptyStringValueParser::new())
158 .help("The directory to write the shell completions to, default is the current directory"))
159}