diff --git a/Cargo.lock b/Cargo.lock index 77c5346..3705eb3 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -325,7 +325,7 @@ dependencies = [ [[package]] name = "gitig" -version = "0.1.0" +version = "0.1.1" dependencies = [ "directories", "error-chain", diff --git a/Cargo.toml b/Cargo.toml index 3513fba..ee3bd05 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "gitig" -version = "0.1.0" +version = "0.1.1" authors = ["Marcel Schneider "] edition = "2018" @@ -13,11 +13,11 @@ serde = { version = "1.0", features = ["derive"] } serde_json = "1.0" directories = "2.0" -[target.'cfg(unix)'.dependencies] -libc = "0.2" - [dependencies.error-chain] version = "0.12" + +[target.'cfg(unix)'.dependencies] +libc = "0.2" #default-features = false # disable pulling in backtrace [profile.release] diff --git a/src/app.rs b/src/app.rs index c0dd23e..f5fad60 100644 --- a/src/app.rs +++ b/src/app.rs @@ -10,7 +10,7 @@ use structopt::StructOpt; use log::{debug, info, trace}; // Local Imports -use crate::cache::File as FileCache; + use crate::errors::*; use crate::gitignore::Gitignore; use crate::helpers; @@ -58,7 +58,8 @@ pub struct CliOpts { cmd: Command, } -/// Subcommands +/// gitig lets you easily start with a fresh gitignore from a template and adds new lines as you +/// wish #[derive(StructOpt, Debug)] pub enum Command { /// Add a line to the gitignore @@ -69,6 +70,8 @@ pub enum Command { /// Download a gitignore for a language Get { /// The language for which the gitignore should be downloaded + /// + /// A list with all available languages and projects can be printed with `list-templates`. lang: String, }, /// List all available templates that can be downloaded @@ -102,12 +105,19 @@ fn run_get(lang: &str) -> Result<()> { }; info!("Working with git root in {:?}", root); - let mut tmpls = helpers::get_templates()?; - let tmpl: &mut Template = - tmpls.get(lang).ok_or_else(|| ErrorKind::TemplateNotFound(lang.to_string()))?; - debug!("Found a template for {}", lang); + 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 + }; - tmpl.load_content()?; root.push(".gitignore"); tmpl.write_to(&root)?; trace!("Wrote template to file"); diff --git a/src/cache.rs b/src/cache.rs index 21f3b4a..564c043 100644 --- a/src/cache.rs +++ b/src/cache.rs @@ -69,7 +69,8 @@ impl File { } /// Stores a `data` under the specified `key` - pub fn set(&self, key: &str, data: &GithubTemplates) -> Result<()> { + pub fn set(&self, key: &str, data: &T) -> Result<()> + where T: Serialize { let mut path: PathBuf = self.root.clone(); path.push(key); trace!("Serializing data to cache file {}", path.to_string_lossy()); @@ -83,14 +84,15 @@ impl File { } /// Retrieves data for `key` - pub fn get(&self, key: &str) -> Result { + pub fn get(&self, key: &str) -> Result + where T: serde::de::DeserializeOwned { let mut path = self.root.clone(); path.push(key); debug!("Retrieving {} from file cache", key); let f = FsFile::open(path) .chain_err(|| format!("Error while opening cache file for key {}", key))?; let reader = BufReader::new(f); - let obj: GithubTemplates = serde_json::from_reader(reader) + let obj: T = serde_json::from_reader(reader) .chain_err(|| "Error while reading templates from file cache")?; debug!("Deserialized {} templates from file cache", "some"); Ok(obj) diff --git a/src/main.rs b/src/main.rs index 39f2e06..cd984c5 100644 --- a/src/main.rs +++ b/src/main.rs @@ -39,6 +39,7 @@ use std::io; // 3rd-party imports mod errors; +use log::{debug, trace}; use structopt::{clap, StructOpt}; // Local imports @@ -75,9 +76,11 @@ fn main() { .timestamp(opts.boilerplate.timestamp.unwrap_or(stderrlog::Timestamp::Off)) .init() .expect("initializing logging output"); + trace!("Initialized logging"); // If requested, generate shell completions and then exit with status of "success" if let Some(shell) = opts.boilerplate.dump_completions { + debug!("Request to dump completion for {}", shell); app::CliOpts::clap().gen_completions_to( app::CliOpts::clap().get_bin_name().unwrap_or_else(|| clap::crate_name!()), shell, @@ -86,6 +89,7 @@ fn main() { std::process::exit(0); }; + trace!("Starting with application"); if let Err(ref e) = app::main(opts) { use std::io::prelude::*; let stderr = std::io::stderr(); diff --git a/src/template.rs b/src/template.rs index 34405a6..94eba71 100644 --- a/src/template.rs +++ b/src/template.rs @@ -155,9 +155,9 @@ impl GithubTemplates { } /// Returns the template for the given name, if found - pub fn get(&mut self, name: &str) -> Option<&mut Template> { + pub fn get(&self, name: &str) -> Option<&Template> { // names have all a .gitignore suffix let name = format!("{}.gitignore", name); - self.templates.iter_mut().find(|t| t.name.eq_ignore_ascii_case(&name)) + self.templates.iter().find(|t| t.name.eq_ignore_ascii_case(&name)) } }