mirror of
https://github.com/neondatabase/neon.git
synced 2026-01-04 03:52:56 +00:00
[issue #7] CLI parse subcommands
This commit is contained in:
@@ -31,3 +31,4 @@ tokio-stream = { version = "0.1.4" }
|
||||
tokio-postgres = { git = "https://github.com/kelvich/rust-postgres", branch = "replication_rebase" }
|
||||
postgres-protocol = { git = "https://github.com/kelvich/rust-postgres", branch = "replication_rebase" }
|
||||
postgres = { git = "https://github.com/kelvich/rust-postgres", branch = "replication_rebase" }
|
||||
anyhow = "1.0"
|
||||
|
||||
46
src/bin/cli/main.rs
Normal file
46
src/bin/cli/main.rs
Normal file
@@ -0,0 +1,46 @@
|
||||
use clap::{App, AppSettings};
|
||||
use anyhow::{Result};
|
||||
|
||||
mod subcommand;
|
||||
pub mod pg;
|
||||
pub mod storage;
|
||||
pub mod snapshot;
|
||||
|
||||
fn main() -> Result<()> {
|
||||
|
||||
let cli_commands = subcommand::ClapCommands {
|
||||
commands: vec![
|
||||
Box::new(pg::PgCmd {
|
||||
clap_cmd: clap::SubCommand::with_name("pg"),
|
||||
}),
|
||||
Box::new(storage::StorageCmd {
|
||||
clap_cmd: clap::SubCommand::with_name("storage"),
|
||||
}),
|
||||
Box::new(snapshot::SnapshotCmd {
|
||||
clap_cmd: clap::SubCommand::with_name("snapshot"),
|
||||
}),
|
||||
],
|
||||
};
|
||||
|
||||
|
||||
let matches = App::new("zenith")
|
||||
.about("Zenith CLI")
|
||||
.version("1.0")
|
||||
.setting(AppSettings::SubcommandRequiredElseHelp)
|
||||
.subcommands(cli_commands.generate())
|
||||
.get_matches();
|
||||
|
||||
|
||||
if let Some(subcommand) = matches.subcommand_name() {
|
||||
println!("'git {}' was used", subcommand);
|
||||
}
|
||||
|
||||
match matches.subcommand() {
|
||||
("pg", Some(sub_args)) => cli_commands.commands[0].run(sub_args.clone())?,
|
||||
("storage", Some(sub_args)) => cli_commands.commands[1].run(sub_args.clone())?,
|
||||
("snapshot", Some(sub_args)) => cli_commands.commands[2].run(sub_args.clone())?,
|
||||
("", None) => println!("No subcommand"),
|
||||
_ => unreachable!(),
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
41
src/bin/cli/pg.rs
Normal file
41
src/bin/cli/pg.rs
Normal file
@@ -0,0 +1,41 @@
|
||||
use clap::{App, AppSettings, Arg};
|
||||
use anyhow::{Result};
|
||||
|
||||
use crate::subcommand;
|
||||
|
||||
pub struct PgCmd<'a> {
|
||||
pub clap_cmd: clap::App<'a, 'a>,
|
||||
}
|
||||
|
||||
impl subcommand::SubCommand for PgCmd<'_> {
|
||||
fn gen_clap_command(&self) -> clap::App {
|
||||
let c = self.clap_cmd.clone();
|
||||
c.about("Operations with zenith compute nodes")
|
||||
.setting(AppSettings::SubcommandRequiredElseHelp)
|
||||
.subcommand(
|
||||
App::new("list")
|
||||
)
|
||||
.subcommand(
|
||||
App::new("create")
|
||||
.arg(Arg::with_name("pgdata").required(true)),
|
||||
)
|
||||
.subcommand(
|
||||
App::new("destroy")
|
||||
)
|
||||
.subcommand(
|
||||
App::new("start")
|
||||
)
|
||||
.subcommand(
|
||||
App::new("stop")
|
||||
)
|
||||
.subcommand(
|
||||
App::new("show")
|
||||
)
|
||||
}
|
||||
|
||||
fn run(&self, args: clap::ArgMatches) -> Result<()> {
|
||||
|
||||
println!("Run PgCmd with args {:?}", args);
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
41
src/bin/cli/snapshot.rs
Normal file
41
src/bin/cli/snapshot.rs
Normal file
@@ -0,0 +1,41 @@
|
||||
use clap::{App, AppSettings, Arg};
|
||||
use anyhow::{Result};
|
||||
|
||||
use crate::subcommand;
|
||||
|
||||
pub struct SnapshotCmd<'a> {
|
||||
pub clap_cmd: clap::App<'a, 'a>,
|
||||
}
|
||||
|
||||
impl subcommand::SubCommand for SnapshotCmd<'_> {
|
||||
fn gen_clap_command(&self) -> clap::App {
|
||||
let c = self.clap_cmd.clone();
|
||||
c.about("Operations with zenith snapshots")
|
||||
.setting(AppSettings::SubcommandRequiredElseHelp)
|
||||
.subcommand(
|
||||
App::new("list")
|
||||
)
|
||||
.subcommand(
|
||||
App::new("create")
|
||||
.arg(Arg::with_name("pgdata").required(true)),
|
||||
)
|
||||
.subcommand(
|
||||
App::new("destroy")
|
||||
)
|
||||
.subcommand(
|
||||
App::new("start")
|
||||
)
|
||||
.subcommand(
|
||||
App::new("stop")
|
||||
)
|
||||
.subcommand(
|
||||
App::new("show")
|
||||
)
|
||||
}
|
||||
|
||||
fn run(&self, args: clap::ArgMatches) -> Result<()> {
|
||||
|
||||
println!("Run SnapshotCmd with args {:?}", args);
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
34
src/bin/cli/storage.rs
Normal file
34
src/bin/cli/storage.rs
Normal file
@@ -0,0 +1,34 @@
|
||||
use clap::{App, AppSettings};
|
||||
use anyhow::{Result};
|
||||
|
||||
use crate::subcommand;
|
||||
|
||||
pub struct StorageCmd<'a> {
|
||||
pub clap_cmd: clap::App<'a, 'a>,
|
||||
}
|
||||
|
||||
impl subcommand::SubCommand for StorageCmd<'_> {
|
||||
fn gen_clap_command(&self) -> clap::App {
|
||||
let c = self.clap_cmd.clone();
|
||||
c.about("Operations with zenith storage nodes")
|
||||
.setting(AppSettings::SubcommandRequiredElseHelp)
|
||||
.subcommand(
|
||||
App::new("list")
|
||||
)
|
||||
.subcommand(
|
||||
App::new("attach")
|
||||
)
|
||||
.subcommand(
|
||||
App::new("detach")
|
||||
)
|
||||
.subcommand(
|
||||
App::new("show")
|
||||
)
|
||||
}
|
||||
|
||||
fn run(&self, args: clap::ArgMatches) -> Result<()> {
|
||||
|
||||
println!("Run StorageCmd with args {:?}", args);
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
29
src/bin/cli/subcommand.rs
Normal file
29
src/bin/cli/subcommand.rs
Normal file
@@ -0,0 +1,29 @@
|
||||
use anyhow::Result;
|
||||
|
||||
/// All subcommands need to implement this interface.
|
||||
pub trait SubCommand {
|
||||
/// Generates the cli-config that Clap requires for the subcommand.
|
||||
fn gen_clap_command(&self) -> clap::App;
|
||||
|
||||
/// Runs the body of the subcommand.
|
||||
fn run(&self, args: clap::ArgMatches) -> Result<()>;
|
||||
}
|
||||
|
||||
/// A struct which holds a vector of heap-allocated `Box`es of trait objects all of which must
|
||||
/// implement the `SubCommand` trait, but other than that, can be of any type.
|
||||
pub struct ClapCommands {
|
||||
pub commands: Vec<Box<dyn SubCommand>>,
|
||||
}
|
||||
|
||||
impl ClapCommands {
|
||||
/// Generates a vector of `clap::Apps` that can be passed into clap's `.subcommands()` method in
|
||||
/// order to generate the full CLI.
|
||||
pub fn generate(&self) -> Vec<clap::App> {
|
||||
let mut v: Vec<clap::App> = Vec::new();
|
||||
|
||||
for command in self.commands.iter() {
|
||||
v.push(command.gen_clap_command());
|
||||
}
|
||||
v
|
||||
}
|
||||
}
|
||||
@@ -1,101 +0,0 @@
|
||||
|
||||
use clap::{App, AppSettings, Arg};
|
||||
|
||||
fn main() {
|
||||
|
||||
let matches = App::new("zenith")
|
||||
.about("Zenith CLI")
|
||||
.version("1.0")
|
||||
.setting(AppSettings::SubcommandRequiredElseHelp)
|
||||
.subcommand(
|
||||
App::new("pg")
|
||||
.about("compute node postgres")
|
||||
.setting(AppSettings::SubcommandRequiredElseHelp)
|
||||
.subcommand(
|
||||
App::new("list")
|
||||
)
|
||||
.subcommand(
|
||||
App::new("create")
|
||||
.arg(Arg::with_name("pgdata").required(true)),
|
||||
)
|
||||
.subcommand(
|
||||
App::new("destroy")
|
||||
)
|
||||
.subcommand(
|
||||
App::new("start")
|
||||
)
|
||||
.subcommand(
|
||||
App::new("stop")
|
||||
)
|
||||
.subcommand(
|
||||
App::new("show")
|
||||
),
|
||||
)
|
||||
.subcommand(
|
||||
App::new("storage")
|
||||
.about("storage node postgres")
|
||||
.setting(AppSettings::SubcommandRequiredElseHelp)
|
||||
.subcommand(
|
||||
App::new("list")
|
||||
)
|
||||
.subcommand(
|
||||
App::new("attach")
|
||||
)
|
||||
.subcommand(
|
||||
App::new("detach")
|
||||
)
|
||||
.subcommand(
|
||||
App::new("show")
|
||||
),
|
||||
)
|
||||
.get_matches();
|
||||
|
||||
|
||||
if let Some(subcommand) = matches.subcommand_name() {
|
||||
println!("'git {}' was used", subcommand);
|
||||
}
|
||||
|
||||
match matches.subcommand() {
|
||||
("pg", Some(pg_matches)) => {
|
||||
println!("pg subcommand");
|
||||
match pg_matches.subcommand()
|
||||
{
|
||||
("list", _) => {
|
||||
println!("list subcommand");
|
||||
}
|
||||
("create", _) => {
|
||||
}
|
||||
("destroy", _) => {
|
||||
}
|
||||
("start", _) => {
|
||||
}
|
||||
("stop", _) => {
|
||||
}
|
||||
("show", _) => {
|
||||
}
|
||||
("", None) => println!("No subcommand"),
|
||||
_ => unreachable!(),
|
||||
}
|
||||
}
|
||||
("storage", Some(storage_matches)) => {
|
||||
println!("storage subcommand");
|
||||
match storage_matches.subcommand()
|
||||
{
|
||||
("list", _) => {
|
||||
println!("list subcommand");
|
||||
}
|
||||
("attach", _) => {
|
||||
}
|
||||
("detach", _) => {
|
||||
}
|
||||
("show", _) => {
|
||||
}
|
||||
("", None) => println!("No subcommand"),
|
||||
_ => unreachable!(),
|
||||
}
|
||||
}
|
||||
|
||||
("", None) => println!("No subcommand"),
|
||||
_ => unreachable!(),
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user