Skip to content

Commit c15d212

Browse files
feat: add clap_compat module for API compatibility
1 parent 80ab1b7 commit c15d212

File tree

3 files changed

+72
-33
lines changed

3 files changed

+72
-33
lines changed

src/main.rs

Lines changed: 38 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
use {
2-
crate::utils::{dashboard, examples, nodes, ssh_deploy, svm_info},
2+
crate::utils::{clap_compat, dashboard, examples, nodes, ssh_deploy, svm_info},
33
clparse::parse_command_line,
44
solana_clap_utils::{
55
input_parsers::pubkey_of, input_validators::normalize_to_url_if_moniker,
@@ -46,32 +46,29 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
4646
let mut wallet_manager = None;
4747

4848
// Check if colors should be disabled (via flag or environment variable)
49-
let no_color = matches.is_present("no_color") || env::var("NO_COLOR").is_ok();
49+
let no_color = clap_compat::is_present(matches, "no_color") || env::var("NO_COLOR").is_ok();
5050
if no_color {
5151
// Disable colored output globally for the colored crate
5252
colored::control::set_override(false);
5353
}
5454

5555
let config = {
56-
let cli_config = if let Some(config_file) = matches.value_of("config_file") {
56+
let cli_config = if let Some(config_file) = clap_compat::value_of(matches, "config_file") {
5757
solana_cli_config::Config::load(config_file).unwrap_or_default()
5858
} else {
5959
solana_cli_config::Config::load("~/.config/osvm/config.yml").unwrap_or_default()
6060
};
6161

6262
let default_signer = DefaultSigner::new(
6363
"keypair",
64-
matches
65-
.value_of("keypair")
64+
clap_compat::value_of(matches, "keypair")
6665
.map(|s| s.to_string())
6766
.unwrap_or_else(|| cli_config.keypair_path.clone()),
6867
);
6968

7069
Config {
7170
json_rpc_url: normalize_to_url_if_moniker(
72-
matches
73-
.value_of("json_rpc_url")
74-
.unwrap_or(&cli_config.json_rpc_url),
71+
clap_compat::value_of(matches, "json_rpc_url").unwrap_or(&cli_config.json_rpc_url),
7572
),
7673
#[cfg(feature = "remote-wallet")]
7774
default_signer: default_signer
@@ -88,7 +85,7 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
8885
exit(1);
8986
}),
9087
// Count occurrences of the verbose flag to determine verbosity level
91-
verbose: matches.occurrences_of("verbose") as u8,
88+
verbose: clap_compat::occurrences_of(matches, "verbose"),
9289
no_color,
9390
commitment_config: CommitmentConfig::confirmed(),
9491
}
@@ -178,7 +175,7 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
178175
// First get SVM info to verify it exists and can be installed
179176
match svm_info::get_svm_info(&rpc_client, svm_name, config.commitment_config) {
180177
Ok(info) => {
181-
if (!info.can_install_validator && !info.can_install_rpc) {
178+
if !info.can_install_validator && !info.can_install_rpc {
182179
eprintln!("SVM '{}' cannot be installed", svm_name);
183180
exit(1);
184181
}
@@ -212,13 +209,15 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
212209
("nodes", Some(nodes_matches)) => {
213210
let (node_sub_command, node_sub_matches) = nodes_matches.subcommand();
214211
match (node_sub_command, node_sub_matches) {
215-
("list", Some(list_matches)) => {
212+
"list" => {
216213
// List all nodes
217-
let network = list_matches.value_of("network").unwrap_or("all");
218-
let node_type = list_matches.value_of("type").unwrap_or("all");
219-
let status = list_matches.value_of("status").unwrap_or("all");
220-
let svm = list_matches.value_of("svm");
221-
let json_output = list_matches.is_present("json");
214+
let network =
215+
clap_compat::value_of(node_sub_matches, "network").unwrap_or("all");
216+
let node_type =
217+
clap_compat::value_of(node_sub_matches, "type").unwrap_or("all");
218+
let status = clap_compat::value_of(node_sub_matches, "status").unwrap_or("all");
219+
let svm = clap_compat::value_of(node_sub_matches, "svm");
220+
let json_output = clap_compat::is_present(node_sub_matches, "json");
222221

223222
match nodes::list_all_nodes(
224223
&rpc_client,
@@ -230,7 +229,7 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
230229
config.verbose,
231230
) {
232231
Ok(node_list) => {
233-
if (json_output) {
232+
if json_output {
234233
println!("{}", serde_json::to_string_pretty(&node_list).unwrap());
235234
} else {
236235
nodes::display_node_list(&node_list, config.verbose);
@@ -263,7 +262,7 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
263262

264263
match nodes::get_node_status(node_id) {
265264
Ok(status) => {
266-
if (json_output) {
265+
if json_output {
267266
println!("{}", serde_json::to_string_pretty(&status).unwrap());
268267
} else {
269268
nodes::display_node_status(node_id, &status, config.verbose);
@@ -282,7 +281,7 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
282281

283282
match nodes::get_node_info(&rpc_client, node_id, config.commitment_config) {
284283
Ok(info) => {
285-
if (json_output) {
284+
if json_output {
286285
println!("{}", serde_json::to_string_pretty(&info).unwrap());
287286
} else {
288287
nodes::display_node_info(&info, config.verbose);
@@ -328,7 +327,7 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
328327

329328
match nodes::get_node_logs(node_id, lines, follow) {
330329
Ok(_) => {
331-
if (follow) {
330+
if follow {
332331
// For follow mode, the function won't return until user interrupts
333332
println!("Log streaming ended");
334333
}
@@ -377,7 +376,7 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
377376
}
378377
("examples", Some(examples_matches)) => {
379378
// Handle the examples command
380-
if (examples_matches.is_present("list_categories")) {
379+
if examples_matches.is_present("list_categories") {
381380
// List all available example categories
382381
println!("Available example categories:");
383382
println!(" basic - Basic Commands");
@@ -432,8 +431,8 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
432431
};
433432

434433
// Create disk configuration if both disk params are provided
435-
let disk_config = if (validator_matches.is_present("ledger-disk")
436-
&& validator_matches.is_present("accounts-disk"))
434+
let disk_config = if validator_matches
435+
.is_present("ledger-disk" && validator_matches.is_present("accounts-disk"))
437436
{
438437
Some(ssh_deploy::DiskConfig {
439438
ledger_disk: validator_matches
@@ -472,7 +471,7 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
472471
if let Some(client) = &deploy_config.client_type {
473472
println!("Client type: {}", client);
474473
}
475-
if (deploy_config.hot_swap_enabled) {
474+
if deploy_config.hot_swap_enabled {
476475
println!("Hot-swap capability: Enabled");
477476
}
478477
if let Some(disks) = &deploy_config.disk_config {
@@ -523,8 +522,8 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
523522
};
524523

525524
// Create disk configuration if both disk params are provided
526-
let disk_config = if (rpc_matches.is_present("ledger-disk")
527-
&& rpc_matches.is_present("accounts-disk"))
525+
let disk_config = if rpc_matches
526+
.is_present("ledger-disk" && rpc_matches.is_present("accounts-disk"))
528527
{
529528
Some(ssh_deploy::DiskConfig {
530529
ledger_disk: rpc_matches.value_of("ledger-disk").unwrap().to_string(),
@@ -539,7 +538,7 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
539538

540539
// Create additional params for RPC-specific options
541540
let mut additional_params = std::collections::HashMap::new();
542-
if (enable_history) {
541+
if enable_history {
543542
additional_params.insert("enable_history".to_string(), "true".to_string());
544543
}
545544

@@ -566,7 +565,7 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
566565
if let Some(client) = &deploy_config.client_type {
567566
println!("Client type: {}", client);
568567
}
569-
if (enable_history) {
568+
if enable_history {
570569
println!("Transaction history: Enabled");
571570
}
572571
if let Some(disks) = &deploy_config.disk_config {
@@ -645,10 +644,16 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
645644

646645
println!("Sonic RPC node deployed successfully!");
647646
}
648-
("solana", Some(solana_matches)) => {
647+
"solana" => {
649648
// Use the enhanced Solana deployment via rpc subcommand
650-
let connection_str = solana_matches.value_of("connection").unwrap();
651-
let network_str = solana_matches.value_of("network").unwrap_or("mainnet");
649+
let connection_str = rpc_sub_matches
650+
.get_one::<String>("connection")
651+
.map(|s| s.as_str())
652+
.unwrap();
653+
let network_str = rpc_sub_matches
654+
.get_one::<String>("network")
655+
.map(|s| s.as_str())
656+
.unwrap_or("mainnet");
652657

653658
// Parse connection string
654659
let connection =
@@ -738,7 +743,7 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
738743
.split(',')
739744
.map(|s| s.trim().to_string())
740745
.collect::<Vec<_>>();
741-
if (svm_types.is_empty()) {
746+
if svm_types.is_empty() {
742747
eprintln!("No SVMs specified");
743748
exit(1);
744749
}
@@ -803,4 +808,4 @@ mod test {
803808
// Assert that the deserialized data matches the original
804809
assert_eq!(faux, in_faux);
805810
}
806-
}
811+
}

src/utils/clap_compat.rs

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
//! Compatibility layer for Clap API changes
2+
//! This module provides functions to bridge the gap between different versions of Clap
3+
4+
use clap::ArgMatches;
5+
6+
/// Get a string value from ArgMatches (compatibility with older Clap API)
7+
pub fn value_of(matches: &ArgMatches, name: &str) -> Option<&str> {
8+
matches.get_one::<String>(name).map(|s| s.as_str())
9+
}
10+
11+
/// Check if an argument is present (compatibility with older Clap API)
12+
pub fn is_present(matches: &ArgMatches, name: &str) -> bool {
13+
matches.contains_id(name)
14+
}
15+
16+
/// Get the number of occurrences of a flag (compatibility with older Clap API)
17+
pub fn occurrences_of(matches: &ArgMatches, name: &str) -> u8 {
18+
matches.get_count(name) as u8
19+
}
20+
21+
/// Get a value from ArgMatches and unwrap it (compatibility with older Clap API)
22+
pub fn value_of_unwrap(matches: &ArgMatches, name: &str) -> &str {
23+
value_of(matches, name).unwrap()
24+
}
25+
26+
/// Get a value from ArgMatches with a default (compatibility with older Clap API)
27+
pub fn value_of_or<'a, 'b>(matches: &'a ArgMatches, name: &str, default: &'b str) -> &'a str
28+
where
29+
'b: 'a,
30+
{
31+
value_of(matches, name).unwrap_or(default)
32+
}

src/utils/mod.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,8 @@ pub mod ssh_deploy;
2626
pub mod svm_info;
2727

2828
// External dependency wrappers
29+
/// Compatibility layer for Clap API changes
30+
pub mod clap_compat;
2931
/// Wrapper for webpki::Error to implement std::error::Error trait
3032
pub mod webpki_error;
3133

0 commit comments

Comments
 (0)