solana_test/
commands.rs

1//! SolanaTest Subcommands
2//!
3//! This is where you specify the subcommands of your application.
4//!
5//! The default application comes with two subcommands:
6//!
7//! - `start`: launches the application
8//! - `--version`: print application version
9//!
10//! See the `impl Configurable` below for how to specify the path to the
11//! application's configuration file.
12
13mod init;
14
15use self::init::InitCmd;
16use crate::config::SolanaTestConfig;
17use abscissa_core::{config::Override, Command, Configurable, FrameworkError, Runnable};
18use clap::Parser;
19use std::path::PathBuf;
20
21/// SolanaTest Configuration Filename
22pub const CONFIG_FILE: &str = "solana-test.toml";
23
24/// SolanaTest Subcommands
25/// Subcommands need to be listed in an enum.
26#[derive(Command, Debug, Parser, Runnable)]
27pub enum SolanaTestCmd {
28    /// The `start` subcommand
29    Init(InitCmd),
30}
31
32/// Entry point for the application. It needs to be a struct to allow using subcommands!
33#[derive(Command, Debug, Parser)]
34#[clap(author, about, version)]
35pub struct EntryPoint {
36    #[clap(subcommand)]
37    cmd: SolanaTestCmd,
38
39    /// Enable verbose logging
40    #[clap(short, long)]
41    pub verbose: bool,
42
43    /// Use the specified config file
44    #[clap(short, long)]
45    pub config: Option<String>,
46}
47
48impl Runnable for EntryPoint {
49    fn run(&self) {
50        self.cmd.run()
51    }
52}
53
54/// This trait allows you to define how application configuration is loaded.
55impl Configurable<SolanaTestConfig> for EntryPoint {
56    /// Location of the configuration file
57    fn config_path(&self) -> Option<PathBuf> {
58        // Check if the config file exists, and if it does not, ignore it.
59        // If you'd like for a missing configuration file to be a hard error
60        // instead, always return `Some(CONFIG_FILE)` here.
61        let filename = self
62            .config
63            .as_ref()
64            .map(PathBuf::from)
65            .unwrap_or_else(|| CONFIG_FILE.into());
66
67        if filename.exists() {
68            Some(filename)
69        } else {
70            None
71        }
72    }
73
74    /// Apply changes to the config after it's been loaded, e.g. overriding
75    /// values in a config file using command-line options.
76    ///
77    /// This can be safely deleted if you don't want to override config
78    /// settings from command-line options.
79    fn process_config(&self, config: SolanaTestConfig) -> Result<SolanaTestConfig, FrameworkError> {
80        match &self.cmd {
81            SolanaTestCmd::Init(cmd) => cmd.override_config(config),
82            //
83            // If you don't need special overrides for some
84            // subcommands, you can just use a catch all
85            // _ => Ok(config),
86        }
87    }
88}