Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Chain add command #51

Open
wants to merge 10 commits into
base: old-main
Choose a base branch
from
1 change: 1 addition & 0 deletions ocular/src/chain/info.rs
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@ pub struct Apis {
pub rpc: Vec<Rpc>,
#[serde(skip_serializing_if = "Vec::is_empty", default = "Vec::new")]
pub rest: Vec<Rest>,
#[serde(skip_serializing_if = "Vec::is_empty", default = "Vec::new")]
pub grpc: Vec<Grpc>,
}

Expand Down
14 changes: 12 additions & 2 deletions ocular/src/chain/registry.rs
Original file line number Diff line number Diff line change
Expand Up @@ -64,11 +64,21 @@ pub async fn get_chain(name: &str) -> Result<ChainInfo, ChainRegistryError> {
}

async fn get_content(path: String) -> Result<reqwest::Response, ChainRegistryError> {
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);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's return an error instead,

ChainRegistryError::Request() takes in an octocrab::Error

});

let status = response.status();

if status == 404 {
panic!("Chain not found in registry")
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same here, ChainRegistryError::UnsupportedChain is made for this

}

Ok(response)
}

async fn parse_json<T>(data: reqwest::Response) -> Result<T, ChainRegistryError>
Expand Down
5 changes: 3 additions & 2 deletions ocular_cli/src/commands/chains.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@ use crate::config::OcularCliConfig;
use abscissa_core::{config, Command, FrameworkError, Runnable};
use clap::Parser;

use self::list::ListCmd;
use self::show::ShowCmd;
use self::{add::AddCmd, list::ListCmd, show::ShowCmd};

/// `start` subcommand
///
/// The `Parser` proc macro generates an option parser based on the struct
Expand All @@ -24,6 +24,7 @@ use self::show::ShowCmd;
pub enum ChainsCmd {
Show(ShowCmd),
List(ListCmd),
Add(AddCmd),
}

impl config::Override<OcularCliConfig> for ChainsCmd {
Expand Down
71 changes: 71 additions & 0 deletions ocular_cli/src/commands/chains/add.rs
Original file line number Diff line number Diff line change
@@ -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<ChainInfo>,
}

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) {
Copy link
Member

@cbrit cbrit Jun 1, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If the chain exists in the config we can avoid a call to github by putting a check for this before the async block.

// 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");
Comment on lines +51 to +54
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it will be a better UX if the list of chains is in alphabetical order like lens has it, which appending can't accomplish.

I'd forgotten but there is actually an OcularCliConfig struct for serializing/deserializing the config file already in config.rs that can replace the Chains struct in this file. You should be able to deserialize the file to it and edit the chains vec (and sort):

/// OcularCli Configuration
#[derive(Clone, Debug, Default, Deserialize, Serialize)]
#[serde(deny_unknown_fields)]
pub struct OcularCliConfig {
/// Chain related config, not read in from file
pub default_chain: String,
/// Locally cached chains
pub chains: Vec<ChainInfo>,
}


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);
});
}
}
2 changes: 1 addition & 1 deletion ocular_cli/src/commands/chains/show.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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)]
Expand Down