From 6465c4d30ebeecb6648190cf573904ea5604a974 Mon Sep 17 00:00:00 2001 From: Manuel Holtgrewe Date: Fri, 3 Mar 2023 14:33:06 +0100 Subject: [PATCH] chore: bootstrapping mehari CLI (#4) --- Cargo.toml | 6 ++ README.md | 1 + src/common.rs | 12 ++++ src/db/create/mod.rs | 4 ++ src/db/create/seqvar_freqs.rs | 20 +++++++ src/db/create/txs.rs | 13 ++++ src/db/mod.rs | 3 + src/main.rs | 108 +++++++++++++++++++++++++++++++++- 8 files changed, 165 insertions(+), 2 deletions(-) create mode 100644 src/common.rs create mode 100644 src/db/create/mod.rs create mode 100644 src/db/create/seqvar_freqs.rs create mode 100644 src/db/create/txs.rs create mode 100644 src/db/mod.rs diff --git a/Cargo.toml b/Cargo.toml index 46a10dd9..000f3536 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -12,3 +12,9 @@ readme = "README.md" name = "mehari" [dependencies] +anyhow = "1.0.69" +clap = { version = "4.1.8", features = ["derive"] } +clap-verbosity-flag = "2.0.0" +log = "0.4.17" +tracing = { version = "0.1.37", features = ["log"] } +tracing-subscriber = "0.3.16" diff --git a/README.md b/README.md index 74ede4fe..7992ee7d 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,5 @@ [![CI](https://github.com/bihealth/mehari/actions/workflows/rust.yml/badge.svg)](https://github.com/bihealth/mehari/actions/workflows/rust.yml) +[![codecov](https://codecov.io/gh/bihealth/mehari/branch/main/graph/badge.svg?token=B1dfb7N2n8)](https://codecov.io/gh/bihealth/mehari) # Mehari diff --git a/src/common.rs b/src/common.rs new file mode 100644 index 00000000..9c5ffa9c --- /dev/null +++ b/src/common.rs @@ -0,0 +1,12 @@ +//! Commonly used code. + +use clap::Parser; +use clap_verbosity_flag::{InfoLevel, Verbosity}; + +/// Commonly used command line arguments. +#[derive(Parser, Debug)] +pub struct Args { + /// Verbosity of the program + #[clap(flatten)] + pub verbose: Verbosity, +} diff --git a/src/db/create/mod.rs b/src/db/create/mod.rs new file mode 100644 index 00000000..cbd5b448 --- /dev/null +++ b/src/db/create/mod.rs @@ -0,0 +1,4 @@ +//! Creation of mehari internal databases. + +pub mod seqvar_freqs; +pub mod txs; diff --git a/src/db/create/seqvar_freqs.rs b/src/db/create/seqvar_freqs.rs new file mode 100644 index 00000000..4c5cf5db --- /dev/null +++ b/src/db/create/seqvar_freqs.rs @@ -0,0 +1,20 @@ +//! Sequence variant frequency annotation. + +use clap::Parser; + +/// Command line arguments for `db create seqvar-freqs` sub command. +#[derive(Parser, Debug)] +#[command(about = "Construct mehari sequence variant frequencies database", long_about = None)] +pub struct Args {} + +/// Main entry point for `db create seqvar_freqs` sub command. +pub(crate) fn run(common: &crate::common::Args, args: &Args) -> Result<(), anyhow::Error> { + tracing::info!( + "Building sequence variant frequencies table\ncommon args: {:#?}\nargs: {:#?}", + common, + args + ); + + tracing::info!("Done building sequence variant frequency table"); + Ok(()) +} diff --git a/src/db/create/txs.rs b/src/db/create/txs.rs new file mode 100644 index 00000000..69a8d570 --- /dev/null +++ b/src/db/create/txs.rs @@ -0,0 +1,13 @@ +//! Transcript database. + +use clap::Parser; + +/// Command line arguments for `db create txs` sub command. +#[derive(Parser, Debug)] +#[command(about = "Construct mehari transcripts database", long_about = None)] +pub struct Args {} + +/// Main entry point for `db create txs` sub command. +pub fn run(_common: &crate::common::Args, _args: &Args) -> Result<(), anyhow::Error> { + todo!() +} diff --git a/src/db/mod.rs b/src/db/mod.rs new file mode 100644 index 00000000..6d6b4192 --- /dev/null +++ b/src/db/mod.rs @@ -0,0 +1,3 @@ +//! Database construction and introspection tools. + +pub mod create; diff --git a/src/main.rs b/src/main.rs index e7a11a96..b43d802f 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,3 +1,107 @@ -fn main() { - println!("Hello, world!"); +//! Main entry point for the Mehari CLI. + +pub mod common; +pub mod db; + +use clap::{command, Args, Parser, Subcommand}; + +#[derive(Debug, Parser)] +#[command( + author, + version, + about = "VCF variant effect prediction and annotation" +)] +struct Cli { + /// Commonly used arguments + #[command(flatten)] + common: common::Args, + + /// The sub command to run + #[command(subcommand)] + command: Commands, +} + +/// Enum supporting the parsing of top-level commands. +#[allow(clippy::large_enum_variant)] +#[derive(Debug, Subcommand)] +enum Commands { + /// Database-related commands. + Db(Db), + // /// SV related commands. + // Sv(Sv), + // /// Server related commands. + // Server(Server), +} + +/// Parsing of "db *" sub commands. +#[derive(Debug, Args)] +#[command(args_conflicts_with_subcommands = true)] +struct Db { + /// The sub command to run + #[command(subcommand)] + command: DbCommands, +} + +/// Enum supporting the parsing of "db *" sub commands. +#[derive(Debug, Subcommand)] +enum DbCommands { + Create(DbCreate), +} + +/// Parsing of "db create *" sub commands. +#[derive(Debug, Args)] +#[command(args_conflicts_with_subcommands = true)] +struct DbCreate { + /// The sub command to run + #[command(subcommand)] + command: DbCreateCommands, +} + +/// Enum supporting the parsing of "db create *" sub commands. +#[derive(Debug, Subcommand)] +enum DbCreateCommands { + Txs(db::create::txs::Args), + SeqvarFreqs(db::create::seqvar_freqs::Args), +} + +fn main() -> Result<(), anyhow::Error> { + let cli = Cli::parse(); + + // Build a tracing subscriber according to the configuration in `cli.common`. + let collector = tracing_subscriber::fmt() + .with_target(false) + .with_max_level(match cli.common.verbose.log_level() { + Some(level) => match level { + log::Level::Error => tracing::Level::ERROR, + log::Level::Warn => tracing::Level::WARN, + log::Level::Info => tracing::Level::INFO, + log::Level::Debug => tracing::Level::DEBUG, + log::Level::Trace => tracing::Level::TRACE, + }, + None => tracing::Level::INFO, + }) + .compact() + .finish(); + + // Install collector and go into sub commands. + tracing::subscriber::with_default(collector, || { + tracing::info!("Mehari startup -- letting the camel from the leash..."); + + match &cli.command { + Commands::Db(db) => match &db.command { + DbCommands::Create(db_create) => match &db_create.command { + DbCreateCommands::Txs(args) => db::create::txs::run(&cli.common, args)?, + DbCreateCommands::SeqvarFreqs(args) => { + db::create::seqvar_freqs::run(&cli.common, args)? + } + }, + }, + } + + tracing::info!("All done. Have a nice day!"); + + Ok::<(), anyhow::Error>(()) + })?; + + Ok(()) }