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