diff --git a/cli-output/src/cli_output.rs b/cli-output/src/cli_output.rs index 14c4ac3088..4fb0275c0a 100644 --- a/cli-output/src/cli_output.rs +++ b/cli-output/src/cli_output.rs @@ -1466,6 +1466,60 @@ impl fmt::Display for CliTokenAccount { } } +#[derive(Serialize, Deserialize)] +#[serde(rename_all = "camelCase")] +pub struct CliProgramId { + pub program_id: String, +} + +impl QuietDisplay for CliProgramId {} +impl VerboseDisplay for CliProgramId {} + +impl fmt::Display for CliProgramId { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + writeln_name_value(f, "Program Id:", &self.program_id) + } +} + +#[derive(Serialize, Deserialize)] +#[serde(rename_all = "camelCase")] +pub struct CliProgramBuffer { + pub buffer: String, +} + +impl QuietDisplay for CliProgramBuffer {} +impl VerboseDisplay for CliProgramBuffer {} + +impl fmt::Display for CliProgramBuffer { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + writeln_name_value(f, "Buffer:", &self.buffer) + } +} + +#[derive(Debug, Serialize, Deserialize)] +#[serde(rename_all = "camelCase")] +pub enum CliProgramAccountType { + Buffer, + Program, +} + +#[derive(Serialize, Deserialize)] +#[serde(rename_all = "camelCase")] +pub struct CliProgramAuthority { + pub authority: String, + pub account_type: CliProgramAccountType, +} + +impl QuietDisplay for CliProgramAuthority {} +impl VerboseDisplay for CliProgramAuthority {} + +impl fmt::Display for CliProgramAuthority { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + writeln_name_value(f, "Account Type:", &format!("{:?}", self.account_type))?; + writeln_name_value(f, "Authority:", &self.authority) + } +} + pub fn return_signers( tx: &Transaction, output_format: &OutputFormat, diff --git a/cli/src/cli.rs b/cli/src/cli.rs index 76cc5a6c54..a5f340a3af 100644 --- a/cli/src/cli.rs +++ b/cli/src/cli.rs @@ -2724,6 +2724,7 @@ mod tests { use_deprecated_loader: false, allow_excessive_balance: false, }; + config.output_format = OutputFormat::JsonCompact; let result = process_command(&config); let json: Value = serde_json::from_str(&result.unwrap()).unwrap(); let program_id = json diff --git a/cli/src/program.rs b/cli/src/program.rs index 2c654f41e3..10dcff1728 100644 --- a/cli/src/program.rs +++ b/cli/src/program.rs @@ -10,10 +10,12 @@ use bincode::serialize; use bip39::{Language, Mnemonic, MnemonicType, Seed}; use clap::{App, AppSettings, Arg, ArgMatches, SubCommand}; use log::*; -use serde_json::{self, json, Value}; use solana_bpf_loader_program::{bpf_verifier, BPFError, ThisInstructionMeter}; use solana_clap_utils::{self, input_parsers::*, input_validators::*, keypair::*}; -use solana_cli_output::display::new_spinner_progress_bar; +use solana_cli_output::{ + display::new_spinner_progress_bar, CliProgramAccountType, CliProgramAuthority, + CliProgramBuffer, CliProgramId, +}; use solana_client::{ rpc_client::RpcClient, rpc_config::RpcSendTransactionConfig, rpc_request::MAX_GET_SIGNATURE_STATUSES_QUERY_ITEMS, rpc_response::RpcLeaderSchedule, @@ -863,7 +865,17 @@ fn process_set_authority( ) .map_err(|e| format!("Setting authority failed: {}", e))?; - Ok(option_pubkey_to_string("authority", new_authority).to_string()) + let authority = CliProgramAuthority { + authority: new_authority + .map(|pubkey| pubkey.to_string()) + .unwrap_or_else(|| "none".to_string()), + account_type: if program_pubkey.is_some() { + CliProgramAccountType::Program + } else { + CliProgramAccountType::Buffer + }, + }; + Ok(config.output_format.formatted_string(&authority)) } fn process_get_authority( @@ -889,11 +901,13 @@ fn process_get_authority( .. }) = account.state() { - let mut value = - option_pubkey_to_string("authority", upgrade_authority_address); - let map = value.as_object_mut().unwrap(); - map.insert("accountType".to_string(), json!("program".to_string())); - Ok(value.to_string()) + let authority = CliProgramAuthority { + authority: upgrade_authority_address + .map(|pubkey| pubkey.to_string()) + .unwrap_or_else(|| "none".to_string()), + account_type: CliProgramAccountType::Program, + }; + Ok(config.output_format.formatted_string(&authority)) } else { Err("Invalid associated ProgramData account found for the program".into()) } @@ -905,10 +919,13 @@ fn process_get_authority( } } else if let Ok(UpgradeableLoaderState::Buffer { authority_address }) = account.state() { - let mut value = option_pubkey_to_string("authority", authority_address); - let map = value.as_object_mut().unwrap(); - map.insert("accountType".to_string(), json!("buffer".to_string())); - Ok(value.to_string()) + let authority = CliProgramAuthority { + authority: authority_address + .map(|pubkey| pubkey.to_string()) + .unwrap_or_else(|| "none".to_string()), + account_type: CliProgramAccountType::Buffer, + }; + Ok(config.output_format.formatted_string(&authority)) } else { Err("Not a buffer or program account".into()) } @@ -1117,15 +1134,15 @@ fn do_process_program_write_and_deploy( )?; if let Some(program_signers) = program_signers { - Ok(json!({ - "programId": format!("{}", program_signers[0].pubkey()), - }) - .to_string()) + let program_id = CliProgramId { + program_id: program_signers[0].pubkey().to_string(), + }; + Ok(config.output_format.formatted_string(&program_id)) } else { - Ok(json!({ - "buffer": format!("{}", buffer_pubkey), - }) - .to_string()) + let buffer = CliProgramBuffer { + buffer: buffer_pubkey.to_string(), + }; + Ok(config.output_format.formatted_string(&buffer)) } } @@ -1238,10 +1255,10 @@ fn do_process_program_upgrade( Some(&[upgrade_authority]), )?; - Ok(json!({ - "programId": format!("{}", program_id), - }) - .to_string()) + let program_id = CliProgramId { + program_id: program_id.to_string(), + }; + Ok(config.output_format.formatted_string(&program_id)) } fn read_and_verify_elf(program_location: &str) -> Result, Box> { @@ -1442,17 +1459,6 @@ fn report_ephemeral_mnemonic(words: usize, mnemonic: bip39::Mnemonic) { ); } -fn option_pubkey_to_string(tag: &str, option: Option) -> Value { - match option { - Some(pubkey) => json!({ - tag: format!("{:?}", pubkey), - }), - None => json!({ - tag: "none", - }), - } -} - fn send_and_confirm_transactions_with_spinner( rpc_client: &RpcClient, mut transactions: Vec, @@ -1623,6 +1629,7 @@ mod tests { use super::*; use crate::cli::{app, parse_command, process_command}; use serde_json::Value; + use solana_cli_output::OutputFormat; use solana_sdk::signature::write_keypair_file; fn make_tmp_path(name: &str) -> String { @@ -2240,6 +2247,7 @@ mod tests { allow_excessive_balance: false, }), signers: vec![&default_keypair], + output_format: OutputFormat::JsonCompact, ..CliConfig::default() }; diff --git a/cli/tests/program.rs b/cli/tests/program.rs index 64c136ffe7..e861396a77 100644 --- a/cli/tests/program.rs +++ b/cli/tests/program.rs @@ -3,6 +3,7 @@ use solana_cli::{ cli::{process_command, CliCommand, CliConfig}, program::ProgramCliCommand, }; +use solana_cli_output::OutputFormat; use solana_client::rpc_client::RpcClient; use solana_core::test_validator::TestValidator; use solana_faucet::faucet::run_local_faucet; @@ -58,6 +59,7 @@ fn test_cli_program_deploy_non_upgradeable() { use_deprecated_loader: false, allow_excessive_balance: false, }; + config.output_format = OutputFormat::JsonCompact; let response = process_command(&config); let json: Value = serde_json::from_str(&response.unwrap()).unwrap(); let program_id_str = json @@ -190,6 +192,7 @@ fn test_cli_program_deploy_no_authority() { is_final: true, max_len: None, }); + config.output_format = OutputFormat::JsonCompact; let response = process_command(&config); let json: Value = serde_json::from_str(&response.unwrap()).unwrap(); let program_id_str = json @@ -274,6 +277,7 @@ fn test_cli_program_deploy_with_authority() { is_final: false, max_len: Some(max_len), }); + config.output_format = OutputFormat::JsonCompact; let response = process_command(&config); let json: Value = serde_json::from_str(&response.unwrap()).unwrap(); let program_pubkey_str = json @@ -592,6 +596,7 @@ fn test_cli_program_write_buffer() { buffer_authority_signer_index: None, max_len: None, }); + config.output_format = OutputFormat::JsonCompact; let response = process_command(&config); let json: Value = serde_json::from_str(&response.unwrap()).unwrap(); let buffer_pubkey_str = json @@ -826,6 +831,7 @@ fn test_cli_program_set_buffer_authority() { buffer_authority_index: Some(0), new_buffer_authority: new_buffer_authority.pubkey(), }); + config.output_format = OutputFormat::JsonCompact; let response = process_command(&config); let json: Value = serde_json::from_str(&response.unwrap()).unwrap(); let new_buffer_authority_str = json