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

Hermes: replace default JSON with human-readable output #796

Merged
merged 19 commits into from
Apr 8, 2021
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions ci/simple_config.toml
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
timeout = '10s'
strategy = 'naive'
log_level = 'info'
log_json = false

[[chains]]
id = 'ibc-0'
Expand Down
1 change: 1 addition & 0 deletions config.toml
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
timeout = '10s'
strategy = 'naive'
log_level = 'error'
log_json = false

[[chains]]
id = 'ibc-0'
Expand Down
1 change: 1 addition & 0 deletions config_example.toml
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
timeout = '10s'
strategy = 'naive'
log_level = 'error'
log_json = false

[[chains]]
id = 'ibc-0'
Expand Down
1 change: 0 additions & 1 deletion relayer-cli/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ authors = [

description = """
Implementation of `hermes`, an IBC Relayer developed in Rust.
This crate is a CLI wrapper over the `ibc-relayer` library.
Copy link
Member

Choose a reason for hiding this comment

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

👍

"""

[[bin]]
Expand Down
7 changes: 0 additions & 7 deletions relayer-cli/build.rs

This file was deleted.

29 changes: 11 additions & 18 deletions relayer-cli/src/application.rs
Original file line number Diff line number Diff line change
@@ -1,15 +1,16 @@
//! Cli Abscissa Application

use crate::components::Tracing;
use crate::{commands::CliCmd, config::Config};

use abscissa_core::terminal::component::Terminal;
use abscissa_core::{
application::{self, AppCell},
component::Component,
config, trace, Application, Configurable, EntryPoint, FrameworkError, StandardPaths,
config, trace, Application, Configurable, FrameworkError, StandardPaths,
};

use crate::components::Tracing;
use crate::entry::EntryPoint;
use crate::{commands::CliCmd, config::Config};

/// Application state
pub static APPLICATION: AppCell<CliApp> = AppCell::new();

Expand Down Expand Up @@ -116,17 +117,12 @@ impl Application for CliApp {
.transpose()?
.unwrap_or_default();

// For `start` and `start-multi` commands exclusively we disable JSON; otherwise output is JSON-only
let json_on = if let Some(c) = &command.command {
!matches!(c, CliCmd::Start(_) | CliCmd::StartMulti(_))
} else {
true
};

if json_on {
if command.json {
// Enable JSON by using the crate-level `Tracing`
let tracing = Tracing::new(config.global)?;
Ok(vec![Box::new(terminal), Box::new(tracing)])
} else {
// Use abscissa's tracing, which pretty-prints to the terminal obeying log levels
let alt_tracing = abscissa_core::trace::Tracing::new(
abscissa_core::trace::Config::from(config.global.log_level),
abscissa_core::terminal::ColorChoice::Auto,
Expand All @@ -136,12 +132,9 @@ impl Application for CliApp {
}
}

/// Get tracing configuration from command-line options
// This method used to be called from `framework_components`, no longer relevant since we
// customized the framework.
fn tracing_config(&self, command: &EntryPoint<CliCmd>) -> trace::Config {
if command.verbose {
trace::Config::verbose()
} else {
trace::Config::default()
}
unimplemented!()
}
}
2 changes: 2 additions & 0 deletions relayer-cli/src/commands.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
use std::path::PathBuf;

use abscissa_core::{Command, Configurable, FrameworkError, Help, Options, Runnable};
use tracing::info;

use crate::config::Config;

Expand All @@ -31,6 +32,7 @@ mod version;

/// Default configuration file path
pub fn default_config_file() -> Option<PathBuf> {
info!("Using default configuration from: '.hermes/config.toml'");
dirs_next::home_dir().map(|home| home.join(".hermes/config.toml"))
}

Expand Down
3 changes: 2 additions & 1 deletion relayer-cli/src/components.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
use abscissa_core::{Component, FrameworkError};
use ibc_relayer::config::GlobalConfig;
use tracing_subscriber::fmt::{
format::{Format, Json, JsonFields},
time::SystemTime,
Expand All @@ -8,6 +7,8 @@ use tracing_subscriber::fmt::{
use tracing_subscriber::util::SubscriberInitExt;
use tracing_subscriber::{reload::Handle, EnvFilter, FmtSubscriber};

use ibc_relayer::config::GlobalConfig;

/// Abscissa component for initializing the `tracing` subsystem
#[derive(Component, Debug)]
pub struct Tracing {
Expand Down
14 changes: 11 additions & 3 deletions relayer-cli/src/conclude.rs
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@
//! Output::success(h).with_result(end).exit();
//! ```

use std::fmt::Display;
use std::fmt;

use serde::Serialize;
use tracing::error;
Expand All @@ -65,7 +65,6 @@ use tracing::error;
/// ## Note: See `Output::exit()` for the preferred method of exiting a relayer command.
pub fn exit_with(out: Output) {
// Handle the output message
// TODO: To unify all relayer output, consider replacing `println` with a `tracing` macro below.
println!("{}", serde_json::to_string(&out).unwrap());

// The return code
Expand Down Expand Up @@ -93,7 +92,7 @@ pub fn exit_with(out: Output) {
/// let client_a = ForeignClient::new(chains.src.clone(), chains.dst.clone())
/// .unwrap_or_else(exit_with_unrecoverable_error);
/// ```
pub fn exit_with_unrecoverable_error<T, E: Display>(err: E) -> T {
pub fn exit_with_unrecoverable_error<T, E: fmt::Display>(err: E) -> T {
// TODO(@romac): Once never (!) stabilizes, adapt `Output::exit` to return !
// https://github.com/informalsystems/ibc-rs/pull/688#discussion_r583758439
Output::error(format!("{}", err)).exit();
Expand Down Expand Up @@ -183,3 +182,12 @@ pub enum Status {
#[serde(rename(serialize = "error"))]
Error,
}

impl fmt::Display for Status {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Status::Success => write!(f, "Success"),
Status::Error => write!(f, "Error"),
}
}
}
109 changes: 109 additions & 0 deletions relayer-cli/src/entry.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
use std::path::PathBuf;

use abscissa_core::command::Usage;
use abscissa_core::{Command, Config, Configurable, FrameworkError, Options, Runnable};

/// Custom entry point for Hermes.
///
/// Replaces `abscissa_core::EntryPoint` with custom-made flag (for JSON output).
#[derive(Debug, Options)]
pub struct EntryPoint<Cmd>
where
Cmd: Command + Runnable,
{
/// Path to the configuration file
#[options(short = "c", help = "path to configuration file")]
pub config: Option<PathBuf>,

/// Obtain help about the current command
#[options(short = "h", help = "print help message")]
pub help: bool,

/// Toggle JSON output mode one verbosity setting
#[options(short = "j", help = "enable JSON output")]
pub json: bool,

/// Subcommand to execute.
///
/// The `command` option will delegate option parsing to the command type,
/// starting at the first free argument.
#[options(command)]
pub command: Option<Cmd>,
}

impl<Cmd> EntryPoint<Cmd>
where
Cmd: Command + Runnable,
{
/// Borrow the underlying command type or print usage info and exit
fn command(&self) -> &Cmd {
self.command
.as_ref()
.unwrap_or_else(|| Cmd::print_usage_and_exit(&[]))
}
}

impl<Cmd> Runnable for EntryPoint<Cmd>
where
Cmd: Command + Runnable,
{
fn run(&self) {
self.command().run()
}
}

impl<Cmd> Command for EntryPoint<Cmd>
where
Cmd: Command + Runnable,
{
/// Name of this program as a string
fn name() -> &'static str {
"hermes"
}

/// Description of this program
fn description() -> &'static str {
Cmd::description()
}

/// Version of this program
fn version() -> &'static str {
Cmd::version()
}

/// Authors of this program
fn authors() -> &'static str {
Cmd::authors()
}

/// Get usage information for a particular subcommand (if available)
fn subcommand_usage(command: &str) -> Option<Usage> {
Cmd::subcommand_usage(command)
}
}

impl<Cfg, Cmd> Configurable<Cfg> for EntryPoint<Cmd>
where
Cmd: Command + Configurable<Cfg> + Runnable,
Cfg: Config,
{
/// Path to the command's configuration file
fn config_path(&self) -> Option<PathBuf> {
match &self.config {
// Use explicit `-c`/`--config` argument if passed
Some(cfg) => Some(cfg.clone()),

// Otherwise defer to the toplevel command's config path logic
None => self.command.as_ref().and_then(|cmd| cmd.config_path()),
}
}

/// Process the configuration after it has been loaded, potentially
/// modifying it or returning an error if options are incompatible
fn process_config(&self, config: Cfg) -> Result<Cfg, FrameworkError> {
match &self.command {
Some(cmd) => cmd.process_config(config),
None => Ok(config),
}
}
}
1 change: 1 addition & 0 deletions relayer-cli/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,3 +26,4 @@ pub mod registry;
pub(crate) mod cli_utils;
pub(crate) mod components;
pub(crate) mod conclude;
pub(crate) mod entry;
1 change: 1 addition & 0 deletions relayer/tests/config/fixtures/relayer_conf_example.toml
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
timeout = '10s'
strategy = 'naive'
log_level = 'error'
log_json = false

[[chains]]
id = 'chain_A'
Expand Down