use clap::Parser;
use crate::cloner::{clone, BackupGitlabOptions, CloneParams, FetchGitlabOptions, FilterPatterns};
use anyhow::{bail, Result};
#[derive(Parser)]
#[command(author, version, about)]
struct Cli {
#[arg(
long,
value_parser,
env = "GTLBSTR_FETCH_URL",
value_name = "FETCH URL"
)]
fu: String,
#[arg(
long,
value_parser,
env = "GTLBSTR_FETCH_TOKEN",
value_name = "FETCH TOKEN"
)]
ft: String,
#[arg(
long,
value_parser,
env = "GTLBSTR_BACKUP_URL",
value_name = "BACKUP URL"
)]
bu: Option<String>,
#[arg(
long,
value_parser,
env = "GTLBSTR_BACKUP_TOKEN",
value_name = "BACKUP TOKEN"
)]
bt: Option<String>,
#[arg(
long,
value_parser,
env = "GTLBSTR_BACKUP_GROUP",
value_name = "BACKUP GROUP"
)]
bg: Option<String>,
#[arg(short = 'i', long, env = "GTLBSTR_INCLUDE", value_name = "PATTERN")]
include: Option<Vec<String>>,
#[arg(short = 'x', long, env = "GTLBSTR_EXCLUDE", value_name = "PATTERN")]
exclude: Option<Vec<String>>,
#[arg(
long,
short,
value_parser,
env = "GTLBSTR_DST",
value_name = "DIRECTORY"
)]
dst: Option<String>,
#[arg(short, long, action = clap::ArgAction::Count)]
verbose: u8,
#[arg(long)]
dry_run: bool,
#[arg(
long,
value_parser,
env = "GTLBSTR_OBJECTS_PER_PAGE",
value_name = "COUNT"
)]
objects_per_page: Option<u32>,
#[arg(long, value_parser, env = "GTLBSTR_LIMIT", value_name = "COUNT")]
limit: Option<usize>,
#[arg(
long,
value_parser,
env = "GTLBSTR_CONCURRENCY_LIMIT",
default_value_t = 21,
value_name = "LIMIT"
)]
concurrency_limit: usize,
#[arg(long, env = "GTLBSTR_ONLY_OWNED")]
only_owned: bool,
#[arg(long, env = "GTLBSTR_ONLY_MEMBERSHIP")]
only_membership: bool,
#[arg(long, env = "GTLBSTR_DOWNLOAD_SSH")]
download_ssh: bool,
#[arg(long, env = "GTLBSTR_UPLOAD_SSH")]
upload_ssh: bool,
#[arg(long, env = "GTLBSTR_DISABLE_HIERARCHY")]
disable_hierarchy: bool,
#[arg(long, env = "GTLBSTR_CLEAR_DST")]
clear_dst: bool,
#[arg(long, env = "GTLBSTR_ONLY_MASTER")]
only_master: bool,
#[arg(long, env = "GTLBSTR_DISABLE_SYNC_DATE")]
disable_sync_date: bool,
}
pub fn run() -> Result<()> {
let cli = Cli::parse();
let log_level = match cli.verbose {
0 => tracing::Level::ERROR,
1 => tracing::Level::WARN,
2 => tracing::Level::INFO,
3 => tracing::Level::DEBUG,
_ => tracing::Level::TRACE,
};
tracing_subscriber::fmt().with_max_level(log_level).init();
let fetch_gl = FetchGitlabOptions::new(cli.fu, cli.ft)?;
let patterns = if cli.exclude.is_some() && cli.include.is_some() {
bail!("You cannot use the --include and --exclude flag together");
} else if let Some(patterns) = cli.exclude {
Some(FilterPatterns::Exclude(patterns))
} else {
cli.include.map(FilterPatterns::Include)
};
let upl_err = "For upload to another gitlab, you must specify both the --bt and --bu flags";
let backup_gl = if let (Some(url), Some(token)) = (&cli.bu, &cli.bt) {
Some(BackupGitlabOptions::new(
url.clone(),
token.clone(),
cli.bg.clone(),
)?)
} else {
if cli.bu.is_some() || cli.bt.is_some() {
bail!(upl_err);
};
None
};
if backup_gl.is_none() && cli.bg.is_some() {
bail!(upl_err);
}
let clone_params = CloneParams {
fetch: fetch_gl,
dst: cli.dst,
backup: backup_gl,
patterns,
dry_run: cli.dry_run,
objects_per_page: cli.objects_per_page,
limit: cli.limit,
concurrency_limit: cli.concurrency_limit,
only_owned: cli.only_owned,
only_membership: cli.only_membership,
download_ssh: cli.download_ssh,
upload_ssh: cli.upload_ssh,
disable_hierarchy: cli.disable_hierarchy,
clear_dst: cli.clear_dst,
only_master: cli.only_master,
disable_sync_date: cli.disable_sync_date,
};
clone(clone_params)
}