Uses 'start' as the default subcommand

This commit is contained in:
arya2 2023-05-26 16:56:24 -04:00
parent 3f97470d00
commit 87e921a5ad
3 changed files with 48 additions and 15 deletions

View File

@ -1,6 +1,6 @@
//! Zebrad Abscissa Application
use std::{fmt::Write as _, io::Write as _, process, sync::Arc};
use std::{env, fmt::Write as _, io::Write as _, process, sync::Arc};
use abscissa_core::{
application::{self, AppCell},
@ -10,6 +10,7 @@ use abscissa_core::{
Application, Component, Configurable, FrameworkError, Shutdown, StandardPaths, Version,
};
use clap::Parser;
use zebra_network::constants::PORT_IN_USE_ERROR;
use zebra_state::constants::{DATABASE_FORMAT_VERSION, LOCK_FILE_ERROR};
@ -357,8 +358,8 @@ impl Application for ZebradApp {
.expect("unable to initialize rayon thread pool");
let cfg_ref = &config;
let default_filter = command.cmd.default_tracing_filter(command.verbose);
let is_server = command.cmd.is_server();
let default_filter = command.cmd().default_tracing_filter(command.verbose);
let is_server = command.cmd().is_server();
// Ignore the configured tracing filter for short-lived utility commands
let mut tracing_config = cfg_ref.tracing.clone();
@ -465,3 +466,23 @@ impl Application for ZebradApp {
}
}
}
/// Boot the given application, parsing subcommand and options from
/// command-line arguments, and terminating when complete.
pub fn boot(app_cell: &'static AppCell<ZebradApp>) -> ! {
let mut args: Vec<_> = env::args_os().collect();
// Check if the provided arguments include a subcommand
let should_add_default_subcommand = EntryPoint::try_parse_from(&args)
.unwrap_or_else(|err| err.exit())
.cmd
.is_none();
// Append the default subcommand to args if cmd is None
if should_add_default_subcommand {
args.push(EntryPoint::default_cmd_as_str().into());
};
ZebradApp::run(app_cell, args);
process::exit(0);
}

View File

@ -1,8 +1,8 @@
//! Main entry point for Zebrad
use zebrad::application::APPLICATION;
use zebrad::application::{boot, APPLICATION};
/// Process entry point for `zebrad`
fn main() {
abscissa_core::boot(&APPLICATION);
boot(&APPLICATION);
}

View File

@ -42,12 +42,6 @@ pub enum ZebradCmd {
TipHeight(TipHeightCmd),
}
impl Default for ZebradCmd {
fn default() -> Self {
Self::Start(StartCmd::default())
}
}
impl ZebradCmd {
/// Returns true if this command is a server command.
///
@ -139,7 +133,7 @@ pub struct EntryPoint {
/// The `command` option will delegate option parsing to the command type,
/// starting at the first free argument. Defaults to start.
#[clap(subcommand)]
pub cmd: ZebradCmd,
pub cmd: Option<ZebradCmd>,
/// Path to the configuration file
#[clap(long, short, help = "path to configuration file")]
@ -150,9 +144,27 @@ pub struct EntryPoint {
pub verbose: bool,
}
impl EntryPoint {
/// Borrow the command in the option
///
/// # Panics
///
/// If `cmd` is None
pub fn cmd(&self) -> &ZebradCmd {
self.cmd
.as_ref()
.expect("should default to start if not provided")
}
/// Returns a string that parses to the default subcommand
pub fn default_cmd_as_str() -> &'static str {
"start"
}
}
impl Runnable for EntryPoint {
fn run(&self) {
self.cmd.run()
self.cmd().run()
}
}
@ -181,13 +193,13 @@ impl Configurable<ZebradConfig> for EntryPoint {
Some(cfg) => Some(cfg.clone()),
// Otherwise defer to the toplevel command's config path logic
None => self.cmd.config_path(),
None => self.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: ZebradConfig) -> Result<ZebradConfig, FrameworkError> {
self.cmd.process_config(config)
self.cmd().process_config(config)
}
}