use std::{io::Cursor, path::PathBuf};
use structopt::{
clap::{AppSettings, Shell},
StructOpt,
};
use std::error::Error;
use crate::errors::{DevrcError, DevrcResult};
pub fn get_crate_version() -> &'static str {
env!("CARGO_PKG_VERSION")
}
fn parse_key_val<T>(s: &str) -> DevrcResult<(T, T)>
where
T: std::str::FromStr,
T::Err: Error + 'static,
{
let pos = s.find('=').ok_or({
DevrcError::InvalidArgument
})?;
Ok((
s[..pos].parse().map_err(|_| DevrcError::InvalidArgument)?,
s[pos + 1..]
.parse()
.map_err(|_| DevrcError::InvalidArgument)?,
))
}
#[derive(StructOpt, Debug)]
#[structopt(version = get_crate_version())]
#[structopt(name = "devrc")]
#[structopt(about = "⚡ task automation tool on steroids ⚡")]
#[structopt(after_help = "Wish you productive coding!
Visit https://github.com/devrc-hub/devrc to get more info about devrc.")]
#[structopt(setting = AppSettings::ColoredHelp)]
pub struct CommandLine {
#[structopt(
parse(from_os_str),
name = "CONFIG",
short = "f",
long = "f",
verbatim_doc_comment
)]
pub configs: Vec<PathBuf>,
#[structopt(short = "l", long = "list")]
pub list: bool,
#[structopt(short = "d", long = "detailed")]
pub detailed: bool,
#[structopt(long = "stdin")]
pub read_stdin: bool,
#[structopt(long = "variables")]
pub list_vars: bool,
#[structopt(long = "evariables")]
pub list_env_vars: bool,
#[structopt(long, name="SHELL", possible_values = &Shell::variants(), case_insensitive = true)]
pub completions: Option<Shell>,
#[structopt(name = "TASKS OR ARGS")]
pub rest: Vec<String>,
#[structopt(short = "g")]
pub global: bool,
#[structopt(long = "--dry-run")]
pub dry_run: bool,
#[structopt(long = "--describe")]
pub describe: bool,
#[structopt(long = "--dbg-runner", hidden = true)]
pub dbg: bool,
#[structopt(short, long, parse(from_occurrences))]
pub verbose: u8,
#[structopt(short, long)]
pub quiet: bool,
#[structopt(long = "--set", parse(try_from_str = parse_key_val), name="VAR=VALUE")]
pub set: Vec<(String, String)>,
}
impl CommandLine {
pub fn generate_completions(shell: Shell) {
let mut cursor = Cursor::new(Vec::new());
Self::clap().gen_completions_to(env!("CARGO_PKG_NAME"), shell, &mut cursor);
println!(
"{}",
String::from_utf8(cursor.into_inner())
.expect("Clap completion not UTF-8")
.trim()
);
}
}
#[derive(Debug, Eq, PartialEq, StructOpt)]
pub enum Subcommands {
#[structopt(external_subcommand)]
Other(Vec<String>),
}
pub fn parse_args() -> CommandLine {
CommandLine::from_args()
}