use ::std::time::Duration;
use ::clap::Parser;
use ::parse_duration0::parse as parse_dur;
use crate::common::CommandArgs;
#[derive(Parser, Debug, PartialEq)]
#[command(
name = "cached",
about = "Cache the output of a command for a given duration, running it only if there is no cache or it has expired. Stderr is only shown on first run."
)]
pub struct CachedArgs {
#[arg(value_parser = parse_dur, short = 'd', long = "duration", default_value = "15 min")]
pub duration: Duration,
#[clap(flatten)]
pub key: CachedKeyArgs,
#[arg(short = 's', long)]
pub no_cached_output: bool,
#[arg(short = 'x', long)]
pub exit_code: bool,
#[arg(short = 'v', long)]
pub verbose: bool,
#[command(subcommand)]
pub cmd: CommandArgs,
}
#[derive(Parser, Debug, PartialEq, Default)]
#[command()]
pub struct CachedKeyArgs {
#[arg(short = 'g', long)]
pub git_head: bool,
#[arg(short = 'b', long, conflicts_with = "git_head")]
pub git_base: bool,
#[arg(short = 'G', long, conflicts_with = "git_head")]
pub git_head_diff: bool,
#[arg(long)]
pub git_repo_dir: bool,
#[arg(short = 'p', long)]
pub git_pending: bool,
#[arg(short = 'e', long)]
pub env: Vec<String>,
#[arg(short = 't', long)]
pub text: Vec<String>,
#[arg(short = 'D', long)]
pub no_dir: bool,
#[arg(short = 'C', long)]
pub no_command: bool,
#[arg(short = 'E', long)]
pub no_direct_env: bool,
}
impl CachedArgs {
pub fn any_explicit_key(&self) -> bool {
self.key.git_head || self.key.git_head_diff || self.key.git_base || self.key.git_repo_dir ||
self.key.git_pending || !self.key.env.is_empty() || !self.key.text.is_empty()
}
}
impl Default for CachedArgs {
fn default() -> Self {
CachedArgs {
duration: Duration::from_secs(15 * 60),
key: CachedKeyArgs {
git_head: false,
git_base: false,
git_head_diff: false,
git_repo_dir: false,
git_pending: false,
env: vec![],
text: vec![],
no_dir: false,
no_command: false,
no_direct_env: false,
},
no_cached_output: false,
exit_code: false,
verbose: false,
cmd: CommandArgs::Cmd(Vec::new()),
}
}
}
#[test]
fn test_cli_args() {
let mut args = CachedArgs::try_parse_from(&["cmd", "ls"]).unwrap();
assert!(!args.any_explicit_key());
assert_eq!(args, CachedArgs {
cmd: CommandArgs::Cmd(vec!["ls".to_owned()]),
..CachedArgs::default()
});
args = CachedArgs::try_parse_from(&["cmd", "--duration", "1 year", "ls"]).unwrap();
assert!(!args.any_explicit_key());
args = CachedArgs::try_parse_from(&["cmd", "-d1y", "--git-head", "--git-pending", "ls", "-a", "-l", "-s", "-h"]).unwrap();
assert!(args.any_explicit_key());
args = CachedArgs::try_parse_from(&["cmd", "-d1y", "--text", "string", "ls", "-alsh"]).unwrap();
assert!(args.any_explicit_key());
args = CachedArgs::try_parse_from(&["cmd", "-d1y", "-gpe", "ENV_VAR", "-CDEt", "string", "-t", "another string", "--", "ls"]).unwrap();
assert!(args.any_explicit_key());
}