nedots 0.1.3

A tool to manage configuration files/(ne)dots.
use std::path::PathBuf;

pub(crate) const DEFAULT_ROOT: &str = ".nedots";
pub(crate) const DEFAULT_CFG_FILE: &str = ".nedots.yml";

#[derive(Debug, clap::Parser)]
#[command(author, about, version, arg_required_else_help(true))]
pub(crate) struct RootCmd {
    #[arg(short, long, default_value = DEFAULT_ROOT)]
    /// Root directory.
    pub(crate) root: String,

    /// Custom config file.
    #[arg(short, long = "config", default_value = DEFAULT_CFG_FILE)]
    pub(crate) cfg_file: String,

    #[arg(short = 'C', long = "configpath")]
    /// Path to config file, if provided then root & cfg_file are discarded.
    pub(crate) cfg_path: Option<PathBuf>,

    #[arg(short, long)]
    /// Where to store config files/(ne)dots.
    pub(crate) dots: Option<PathBuf>,

    #[arg(short, long)]
    /// Where to store backups of config files/(ne)dots.
    pub(crate) backups: Option<PathBuf>,

    #[command(flatten)]
    pub(crate) verbose: clap_verbosity_flag::Verbosity,

    #[command(subcommand)]
    cmd: Option<Command>,
}

#[derive(Debug, clap::Subcommand)]
pub(crate) enum Command {
    Gather(super::gather::GatherCmd),
    Backup(super::backup::BackupCmd),
    Clean(super::clean::CleanCmd),
    Install(super::install::InstallCmd),
    Restore(super::restore::RestoreCmd),
    Sync(super::sync::SyncCmd),
}

impl super::Command for RootCmd {
    fn init(&self, _: &self::RootCmd) -> anyhow::Result<crate::config::Config> {
        Ok(crate::config::Config::default())
    }

    fn run(&self, args: &RootCmd, _: &crate::config::Config) -> anyhow::Result<()> {
        if let Some(cmd) = &self.cmd {
            match cmd {
                Command::Backup(backup_cmd) => backup_cmd.exec(args),
                Command::Clean(clean_cmd) => clean_cmd.exec(args),
                Command::Gather(gather_cmd) => gather_cmd.exec(args),
                Command::Install(install_cmd) => install_cmd.exec(args),
                Command::Restore(restore_cmd) => restore_cmd.exec(args),
                Command::Sync(sync_cmd) => sync_cmd.exec(args),
            }
        } else {
            Ok(())
        }
    }
}

#[cfg(test)]
mod test {
    #[test]
    fn verify() {
        <super::RootCmd as clap::CommandFactory>::command().debug_assert()
    }
}