use std::path::PathBuf;
use structopt::StructOpt;
use log::{debug, info, trace};
use crate::errors::*;
use crate::gitignore::Gitignore;
use crate::helpers;
use crate::helpers::{git_dir, BoilerplateOpts, HELP_TEMPLATE};
use crate::template::*;
pub const DEFAULT_VERBOSITY: u64 = 1;
#[derive(StructOpt, Debug)]
#[structopt(template = HELP_TEMPLATE,
about = "TODO: Replace me with the description text for the command",
global_setting = structopt::clap::AppSettings::ColoredHelp)]
pub struct CliOpts {
#[allow(clippy::missing_docs_in_private_items)] #[structopt(flatten)]
pub boilerplate: BoilerplateOpts,
#[structopt(subcommand)]
cmd: Command,
}
#[derive(StructOpt, Debug)]
pub enum Command {
Add {
glob: Vec<String>,
#[structopt(short)]
local: bool,
},
Get {
#[structopt(short)]
append: bool,
lang: String,
},
ListTemplates,
DumpCompletions {
shell: Option<structopt::clap::Shell>,
},
Cat,
}
fn run_add(glob: Vec<String>, local: bool) -> Result<()> {
for g in glob {
add(&g, local)?;
}
Ok(())
}
fn add(glob: &str, local: bool) -> Result<()> {
trace!("running command `add` with glob '{}'", &glob);
let root = match git_dir()? {
Some(r) => r,
None => return Err(ErrorKind::NoGitRootFound.into()),
};
info!("Working with git root in {:?}", root);
let mut file_path = PathBuf::from(&root);
if local {
file_path.push(".git/info/exclude")
} else {
file_path.push(".gitignore");
}
let gitig = Gitignore::from_path(&file_path);
gitig.add_line(glob)?;
debug!("Added '{}' to {}", glob, gitig);
Ok(())
}
fn run_get(lang: &str, append: bool) -> Result<()> {
trace!("Run command `get` with lang {}", &lang);
let mut root = match git_dir()? {
Some(r) => r,
None => return Err(ErrorKind::NoGitRootFound.into()),
};
info!("Working with git root in {:?}", root);
let cache = helpers::default_cache()?;
let tmpl: Template = if cache.exists(lang) {
debug!("Found a template for {} in cache", lang);
cache.get(lang)?
} else {
let tmpls = helpers::get_templates()?;
let mut tmpl =
tmpls.get(lang).ok_or_else(|| ErrorKind::TemplateNotFound(lang.to_string()))?.clone();
tmpl.load_content()?;
cache.set(lang, &tmpl)?;
tmpl
};
root.push(".gitignore");
tmpl.write_to(&root, append)?;
trace!("Wrote template to file");
Ok(())
}
#[allow(clippy::print_stdout)]
fn run_list_templates() -> Result<()> {
let tmpl = helpers::get_templates()?;
let names = tmpl.list_names();
println!("{}", names.join("\n"));
Ok(())
}
fn run_dump_completion(shell: Option<structopt::clap::Shell>) -> Result<()> {
let shell = shell.ok_or(ErrorKind::NoShellProvided)?;
debug!("Request to dump completion for {}", shell);
CliOpts::clap().gen_completions_to(
CliOpts::clap().get_bin_name().unwrap_or_else(|| structopt::clap::crate_name!()),
shell,
&mut ::std::io::stdout(),
);
Ok(())
}
fn run_cat() -> Result<()> {
let ignore_file = Gitignore::from_default_path()?;
let mut buf = String::new();
ignore_file.contents(&mut buf)?;
println!("{}", buf);
Ok(())
}
pub fn main(opts: CliOpts) -> Result<()> {
match opts.cmd {
Command::Add { glob, local } => run_add(glob, local)?,
Command::Get { lang, append } => run_get(&lang, append)?,
Command::ListTemplates => run_list_templates()?,
Command::DumpCompletions { shell } => run_dump_completion(shell)?,
Command::Cat => run_cat()?,
};
Ok(())
}
#[cfg(test)]
mod tests {
#[test]
fn test_something() {
}
}