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}