115 lines
2.9 KiB
Rust
115 lines
2.9 KiB
Rust
use crate::subcommands::{self, BuildArgs, CleanArgs, InitArgs};
|
|
|
|
use clap::{Parser, Subcommand, ValueEnum};
|
|
use color_eyre::eyre::Result;
|
|
use tracing::Level;
|
|
use tracing_subscriber::FmtSubscriber;
|
|
|
|
#[derive(Debug, Clone, Parser)]
|
|
#[command(version, about, long_about = None)]
|
|
pub struct Args {
|
|
#[command(subcommand)]
|
|
cmd: Command,
|
|
/// Enable tracing output
|
|
///
|
|
/// When specified without a value, defaults to `info`.
|
|
#[arg(
|
|
long,
|
|
global = true,
|
|
default_missing_value = "info",
|
|
require_equals = true,
|
|
num_args = 0..=1,
|
|
value_name = "LEVEL"
|
|
)]
|
|
trace: Option<TracingLevel>,
|
|
}
|
|
|
|
#[derive(Debug, Clone, Subcommand)]
|
|
pub enum Command {
|
|
/// Initialize a new project.
|
|
Init(InitArgs),
|
|
/// Build the project.
|
|
Build(BuildArgs),
|
|
/// Clean build artifacts.
|
|
/// This will remove the `dist` directory.
|
|
Clean(CleanArgs),
|
|
#[cfg(feature = "watch")]
|
|
/// Watch for changes and execute commands.
|
|
Watch(subcommands::WatchArgs),
|
|
#[cfg(feature = "lang-debug")]
|
|
/// Build the project and dump the intermediate state.
|
|
LangDebug(subcommands::LangDebugArgs),
|
|
}
|
|
|
|
#[derive(Debug, Clone, Copy, PartialEq, Eq, Default, ValueEnum)]
|
|
pub enum TracingLevel {
|
|
Trace,
|
|
Debug,
|
|
#[default]
|
|
Info,
|
|
Warn,
|
|
Error,
|
|
}
|
|
|
|
impl Args {
|
|
pub fn run(&self) -> Result<()> {
|
|
if let Some(level) = self.trace {
|
|
setup_tracing(level);
|
|
}
|
|
|
|
self.cmd.run()
|
|
}
|
|
}
|
|
|
|
impl Command {
|
|
pub fn run(&self) -> Result<()> {
|
|
match self {
|
|
Command::Init(args) => subcommands::init(args)?,
|
|
Command::Build(args) => subcommands::build(args)?,
|
|
Command::Clean(args) => subcommands::clean(args)?,
|
|
#[cfg(feature = "watch")]
|
|
Command::Watch(args) => subcommands::watch(args)?,
|
|
#[cfg(feature = "lang-debug")]
|
|
Command::LangDebug(args) => subcommands::lang_debug(args)?,
|
|
}
|
|
|
|
Ok(())
|
|
}
|
|
}
|
|
|
|
impl From<TracingLevel> for Level {
|
|
fn from(value: TracingLevel) -> Self {
|
|
match value {
|
|
TracingLevel::Trace => Level::TRACE,
|
|
TracingLevel::Debug => Level::DEBUG,
|
|
TracingLevel::Info => Level::INFO,
|
|
TracingLevel::Warn => Level::WARN,
|
|
TracingLevel::Error => Level::ERROR,
|
|
}
|
|
}
|
|
}
|
|
|
|
fn setup_tracing(level: TracingLevel) {
|
|
// a builder for `FmtSubscriber`.
|
|
let subscriber = FmtSubscriber::builder()
|
|
// all spans/events with a level higher than TRACE (e.g, debug, info, warn, etc.)
|
|
// will be written to stdout.
|
|
.with_max_level(Level::from(level))
|
|
// completes the builder.
|
|
.finish();
|
|
|
|
tracing::subscriber::set_global_default(subscriber).expect("setting default subscriber failed");
|
|
}
|
|
|
|
#[cfg(test)]
|
|
mod tests {
|
|
use clap::CommandFactory;
|
|
|
|
use super::*;
|
|
|
|
#[test]
|
|
fn verify_cli() {
|
|
Args::command().debug_assert();
|
|
}
|
|
}
|