diff --git a/ocular/src/chain/info.rs b/ocular/src/chain/info.rs index 634b5070..b3be7f3f 100644 --- a/ocular/src/chain/info.rs +++ b/ocular/src/chain/info.rs @@ -77,6 +77,7 @@ pub struct Apis { pub rpc: Vec, #[serde(skip_serializing_if = "Vec::is_empty", default = "Vec::new")] pub rest: Vec, + #[serde(skip_serializing_if = "Vec::is_empty", default = "Vec::new")] pub grpc: Vec, } diff --git a/ocular/src/chain/registry.rs b/ocular/src/chain/registry.rs index 240336b0..f7b87775 100644 --- a/ocular/src/chain/registry.rs +++ b/ocular/src/chain/registry.rs @@ -64,11 +64,21 @@ pub async fn get_chain(name: &str) -> Result { } async fn get_content(path: String) -> Result { - octocrab::instance() + let response = octocrab::instance() .repos("cosmos", "chain-registry") .raw_file("88bde7fb534ed6f7c26c2073f57ec5135b470f56".to_string(), path) .await - .map_err(|e| e.into()) + .unwrap_or_else(|err| { + panic!("executor exited with error: {}", err); + }); + + let status = response.status(); + + if status == 404 { + panic!("Chain not found in registry") + } + + Ok(response) } async fn parse_json(data: reqwest::Response) -> Result diff --git a/ocular_cli/src/commands/chains.rs b/ocular_cli/src/commands/chains.rs index 6c3a4bf8..a7721462 100644 --- a/ocular_cli/src/commands/chains.rs +++ b/ocular_cli/src/commands/chains.rs @@ -11,9 +11,7 @@ use crate::config::OcularCliConfig; use abscissa_core::{config, Command, FrameworkError, Runnable}; use clap::Parser; -use self::list::ListCmd; -use self::show::ShowCmd; -use self::show_default::ShowDefaultCmd; +use self::{add::AddCmd, list::ListCmd, show::ShowCmd, show_default::ShowDefaultCmd}; /// `start` subcommand /// @@ -26,6 +24,7 @@ use self::show_default::ShowDefaultCmd; pub enum ChainsCmd { Show(ShowCmd), List(ListCmd), + Add(AddCmd), ShowDefault(ShowDefaultCmd), } diff --git a/ocular_cli/src/commands/chains/add.rs b/ocular_cli/src/commands/chains/add.rs index 8b137891..2d57cd24 100644 --- a/ocular_cli/src/commands/chains/add.rs +++ b/ocular_cli/src/commands/chains/add.rs @@ -1 +1,72 @@ +use super::show::ShowCmd; +use crate::{config, prelude::*}; +use abscissa_core::{Command, Runnable}; +use clap::Parser; +use ocular::chain::{info::ChainInfo, registry}; +use serde::{Deserialize, Serialize}; +use std::{fs, io::Write, path::Path}; +#[derive(Command, Debug, Parser)] +pub struct AddCmd { + name: String, +} + +#[derive(Deserialize, Serialize)] +struct Chains { + chains: Vec, +} + +impl Runnable for AddCmd { + /// Add chain to local config file + fn run(&self) { + // Navigate to file of local config + let path = config::get_config_path(); + let config_file = Path::new(path.to_str().unwrap()); + + // Check if chain already exists + let chain_content = fs::read_to_string(config_file).unwrap_or_else(|err| { + status_err!("Can't read config file: {}", err); + std::process::exit(1); + }); + + let chain_name = self.name.as_str(); + + abscissa_tokio::run(&APP, async { + let chain_info = registry::get_chain(chain_name).await.unwrap_or_else(|err| { + status_err!("Can't fetch chain from chain registry: {}", err); + std::process::exit(1); + }); + + let mut vec = Vec::new(); + vec.push(chain_info); + + if !chain_content.contains(chain_name) { + // write in the file with fs:write + let config_content = Chains { chains: vec }; + let config_content = toml::ser::to_string(&config_content).unwrap_or_else(|err| { + status_err!("{}", err); + std::process::exit(1); + }); + + let mut file = fs::OpenOptions::new() + .append(true) + .open(config_file) + .expect("Could not open file"); + + write!(file, "{}", config_content).unwrap(); + let name = self.name.clone(); + let show_cmd = ShowCmd { name }; + show_cmd.run(); + } else if chain_content.contains(chain_name) { + error!( + "The chain {} already exists in the local registry", + chain_name + ) + } + }) + .unwrap_or_else(|e| { + status_err!("executor exited with error: {}", e); + std::process::exit(1); + }); + } +} diff --git a/ocular_cli/src/commands/chains/show.rs b/ocular_cli/src/commands/chains/show.rs index 33b2c4d1..327ffad1 100644 --- a/ocular_cli/src/commands/chains/show.rs +++ b/ocular_cli/src/commands/chains/show.rs @@ -7,7 +7,7 @@ use std::{collections::HashMap, fs, path::Path, str}; #[derive(Command, Debug, Parser)] pub struct ShowCmd { - name: String, + pub name: String, } #[derive(Deserialize)]