use clap::{ArgGroup, Parser};
use log::LevelFilter;
use redu::restic::Repository;
use rpassword::read_password;
use crate::restic::Password;
#[derive(Debug)]
pub struct Args {
pub repository: Repository,
pub password: Password,
pub parallelism: usize,
pub log_level: LevelFilter,
pub no_cache: bool,
pub non_interactive: bool,
}
impl Args {
pub fn parse() -> Self {
let cli = Cli::parse();
Args {
repository: if let Some(repo) = cli.repo {
Repository::Repo(repo)
} else if let Some(file) = cli.repository_file {
Repository::File(file)
} else {
unreachable!("Error in Config: neither repo nor repository_file found. Please open an issue if you see this.")
},
password: if let Some(command) = cli.password_command {
Password::Command(command)
} else if let Some(file) = cli.password_file {
Password::File(file)
} else if let Some(str) = cli.restic_password {
Password::Plain(str)
} else {
Password::Plain(Self::read_password_from_stdin())
},
parallelism: cli.parallelism,
log_level: match cli.verbose {
0 => LevelFilter::Info,
1 => LevelFilter::Debug,
_ => LevelFilter::Trace,
},
no_cache: cli.no_cache,
non_interactive: cli.non_interactive,
}
}
fn read_password_from_stdin() -> String {
eprint!("enter password for repository: ");
read_password().unwrap()
}
}
#[derive(Parser)]
#[command(version, long_about, verbatim_doc_comment)]
#[command(group(
ArgGroup::new("repository")
.required(true)
.args(["repo", "repository_file"]),
))]
struct Cli {
#[arg(short = 'r', long, env = "RESTIC_REPOSITORY")]
repo: Option<String>,
#[arg(long, env = "RESTIC_REPOSITORY_FILE")]
repository_file: Option<String>,
#[arg(long, value_name = "COMMAND", env = "RESTIC_PASSWORD_COMMAND")]
password_command: Option<String>,
#[arg(long, value_name = "FILE", env = "RESTIC_PASSWORD_FILE")]
password_file: Option<String>,
#[arg(value_name = "RESTIC_PASSWORD", env = "RESTIC_PASSWORD")]
restic_password: Option<String>,
#[arg(short = 'j', value_name = "NUMBER", default_value_t = 4)]
parallelism: usize,
#[arg(
short = 'v',
action = clap::ArgAction::Count,
)]
verbose: u8,
#[arg(long)]
no_cache: bool,
#[arg(long)]
non_interactive: bool,
}