#![warn(missing_docs)]
#![warn(unused_extern_crates)]
#![warn(unused_imports)]
pub mod arg_enums;
mod commands;
mod config;
mod error;
mod params;
mod runner;
pub use arg_enums::*;
pub use commands::*;
pub use config::*;
pub use error::*;
pub use params::*;
pub use runner::*;
pub use tc_service::{ChainSpec, Role};
use tc_service::{Configuration, TaskExecutor};
use tc_telemetry::TelemetryHandle;
pub use tc_tracing::logging::LoggerBuilder;
pub use tp_version::RuntimeVersion;
use std::io::Write;
pub use structopt;
use structopt::{
clap::{self, AppSettings},
StructOpt,
};
pub trait TetcoreCli: Sized {
fn impl_name() -> String;
fn impl_version() -> String;
fn executable_name() -> String {
std::env::current_exe()
.ok()
.and_then(|e| e.file_name().map(|s| s.to_os_string()))
.and_then(|w| w.into_string().ok())
.unwrap_or_else(|| env!("CARGO_PKG_NAME").into())
}
fn description() -> String;
fn author() -> String;
fn support_url() -> String;
fn copyright_start_year() -> i32;
fn load_spec(&self, id: &str) -> std::result::Result<Box<dyn ChainSpec>, String>;
fn from_args() -> Self
where
Self: StructOpt + Sized,
{
<Self as TetcoreCli>::from_iter(&mut std::env::args_os())
}
fn from_iter<I>(iter: I) -> Self
where
Self: StructOpt + Sized,
I: IntoIterator,
I::Item: Into<std::ffi::OsString> + Clone,
{
let app = <Self as StructOpt>::clap();
let mut full_version = Self::impl_version();
full_version.push_str("\n");
let name = Self::executable_name();
let author = Self::author();
let about = Self::description();
let app = app
.name(name)
.author(author.as_str())
.about(about.as_str())
.version(full_version.as_str())
.settings(&[
AppSettings::GlobalVersion,
AppSettings::ArgsNegateSubcommands,
AppSettings::SubcommandsNegateReqs,
]);
let matches = match app.get_matches_from_safe(iter) {
Ok(matches) => matches,
Err(mut e) => {
e.message.extend("\n".chars());
if e.use_stderr() {
let _ = std::io::stderr().write_all(e.message.as_bytes());
std::process::exit(1);
} else {
let _ = std::io::stdout().write_all(e.message.as_bytes());
std::process::exit(0);
}
}
};
<Self as StructOpt>::from_clap(&matches)
}
fn try_from_iter<I>(iter: I) -> clap::Result<Self>
where
Self: StructOpt + Sized,
I: IntoIterator,
I::Item: Into<std::ffi::OsString> + Clone,
{
let app = <Self as StructOpt>::clap();
let mut full_version = Self::impl_version();
full_version.push_str("\n");
let name = Self::executable_name();
let author = Self::author();
let about = Self::description();
let app = app
.name(name)
.author(author.as_str())
.about(about.as_str())
.version(full_version.as_str());
let matches = app.get_matches_from_safe(iter)?;
Ok(<Self as StructOpt>::from_clap(&matches))
}
fn client_id() -> String {
format!("{}/v{}", Self::impl_name(), Self::impl_version())
}
fn create_configuration<T: CliConfiguration<DVC>, DVC: DefaultConfigurationValues>(
&self,
command: &T,
task_executor: TaskExecutor,
telemetry_handle: Option<TelemetryHandle>,
) -> error::Result<Configuration> {
command.create_configuration(self, task_executor, telemetry_handle)
}
fn create_runner<T: CliConfiguration>(&self, command: &T) -> error::Result<Runner<Self>> {
let telemetry_worker = command.init::<Self>()?;
Runner::new(self, command, telemetry_worker)
}
fn native_runtime_version(chain_spec: &Box<dyn ChainSpec>) -> &'static RuntimeVersion;
}