use std::path::PathBuf;
use clap::{Parser, Subcommand};
use ulid::Ulid;
pub mod audit;
pub mod cover;
pub mod diff;
pub mod export;
pub mod log;
pub mod profile;
pub mod scan;
pub mod sync;
#[derive(Parser, Debug)]
#[command(
name = "dapctl",
version,
about = "TUI/CLI sync for HiFi Digital Audio Players",
long_about = None,
)]
struct Cli {
#[command(subcommand)]
command: Option<Command>,
#[arg(long, global = true, value_name = "PATH")]
log_file: Option<PathBuf>,
#[arg(short, long, global = true, action = clap::ArgAction::Count)]
verbose: u8,
#[arg(short = 'y', long, global = true)]
yes: bool,
}
#[derive(Subcommand, Debug)]
enum Command {
Sync(sync::Args),
Diff(diff::Args),
Scan(scan::Args),
Profile(profile::Args),
Log(log::Args),
Export(export::Args),
Audit(audit::Args),
Cover(cover::Args),
}
pub fn run() -> anyhow::Result<()> {
let cli = Cli::parse();
let verbosity = match cli.verbose {
0 => tracing::Level::INFO,
1 => tracing::Level::DEBUG,
_ => tracing::Level::TRACE,
};
let run_id = Ulid::new();
let jsonl_dir = crate::logging::default_jsonl_dir()?;
crate::logging::init(crate::logging::InitOpts {
run_id,
human_log_file: cli.log_file,
jsonl_dir,
verbosity,
tui_mode: cli.command.is_none(),
})?;
let result = match cli.command {
None => crate::tui::run(),
Some(Command::Sync(a)) => sync::run(a, cli.yes),
Some(Command::Diff(a)) => diff::run(a),
Some(Command::Scan(a)) => scan::run(a),
Some(Command::Profile(a)) => profile::run(a),
Some(Command::Log(a)) => log::run(a),
Some(Command::Export(a)) => export::run(a),
Some(Command::Audit(a)) => audit::run(a),
Some(Command::Cover(a)) => cover::run(a),
};
crate::logging::finish(result.is_ok());
result
}