use chrono::{DateTime, FixedOffset};
use clap::{crate_version, App, AppSettings, Arg, ArgMatches, SubCommand};
pub fn build_cli<'a, 'b>() -> App<'a, 'b> {
let args = [
Arg::with_name("delete")
.short("D")
.long("delete")
.help("Deletes or closes the slate objects under operation. By default, Foxdie will not delete anything without this flag set."),
Arg::with_name("since")
.short("s")
.long("since")
.required(true)
.help("Date in RFC 3339 format")
.takes_value(true)
.validator(validate_date),
Arg::with_name("token")
.short("t")
.long("token")
.required(true)
.help("Personal access token for use with GitHub or Gitlab.")
.env("TOKEN")
.hide_env_values(true),
];
App::new("foxdie")
.setting(AppSettings::ArgRequiredElseHelp)
.subcommand(
SubCommand::with_name("branches")
.about("Destroy remote branches from a given Git repository.")
.long_about("Destroy remote branches from a given Git repository that have not been updated since the specified date.")
.args(&args)
.arg(
Arg::with_name("DIRECTORY")
.help("Sets the Git directory to work from.")
.required(true)
.index(1),
),
)
.subcommand(
SubCommand::with_name("push-requests")
.about("Close push branches filed with a given Git repository URL.")
.long_about("Close push branches filed with a given Git repository URL that have not been updated since the specified date.")
.args(&args)
.arg(
Arg::with_name("URL")
.help("Sets the URL to a Git repository to work from.")
.required(true)
.index(1),
),
)
.subcommand(
SubCommand::with_name("report")
.about("Generate a JSON report of stale branches from a given Git repository.")
.arg(
Arg::with_name("output")
.short("o")
.long("output")
.help("Output path for the report.")
.takes_value(true),
)
.arg(
Arg::with_name("DIRECTORY")
.help("Sets the Git directory to work from.")
.required(true)
.index(1),
),
)
.version(crate_version!())
}
#[allow(clippy::needless_pass_by_value)]
fn validate_date(s: String) -> Result<(), String> {
DateTime::parse_from_rfc3339(&s)
.map(|_| ())
.map_err(|e| e.to_string())
}
pub struct SharedArguments<'a> {
pub should_delete: bool,
pub since: DateTime<FixedOffset>,
pub token: &'a str,
}
pub fn parse_shared_arguments<'a, 'b>(app_m: &'b ArgMatches<'a>) -> SharedArguments<'b> {
let should_delete = app_m.is_present("delete");
let since = app_m
.value_of("since")
.and_then(|date_str| DateTime::parse_from_rfc3339(date_str).ok())
.expect("Should have already validated a date, which is a required argument.");
let token: &'b str = app_m.value_of("token").expect(
"Should have passed a token, which is a required argument or environment variable.",
);
SharedArguments {
should_delete,
since,
token,
}
}