From 982a52a1675626b87f59df34bad7a8a1afbe7f08 Mon Sep 17 00:00:00 2001 From: Marcel Schneider Date: Mon, 14 Mar 2022 12:14:56 +0100 Subject: [PATCH] Add `cat` command Fixes #5 --- src/app.rs | 16 ++++++++++++++-- src/gitignore.rs | 27 +++++++++++++++++++++++++++ 2 files changed, 41 insertions(+), 2 deletions(-) diff --git a/src/app.rs b/src/app.rs index 703a4d2..6adfa3b 100644 --- a/src/app.rs +++ b/src/app.rs @@ -65,7 +65,7 @@ pub enum Command { /// Add a line to the gitignore Add { /// The glob string that should be added - glob: Vec, + glob: Vec, /// Add the entry to the repo local ignore file #[structopt(short)] local: bool, @@ -78,7 +78,7 @@ pub enum Command { /// 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, + lang: String, }, /// List all available templates that can be downloaded ListTemplates, @@ -87,6 +87,8 @@ pub enum Command { /// Shell to generate completion for shell: Option, }, + /// Print current .gitignore to stdout + Cat, } /// Runs the command `add` @@ -168,6 +170,15 @@ fn run_dump_completion(shell: Option) -> Result<()> { Ok(()) } +/// Runs the `cat` command to print the contents +fn run_cat() -> Result<()> { + let ignore_file = Gitignore::from_default_path()?; + let mut buf = String::new(); + ignore_file.contents(&mut buf)?; + println!("{}", buf); + Ok(()) +} + /// The actual `main()` pub fn main(opts: CliOpts) -> Result<()> { match opts.cmd { @@ -175,6 +186,7 @@ pub fn main(opts: CliOpts) -> Result<()> { 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(()) diff --git a/src/gitignore.rs b/src/gitignore.rs index dd13d8b..89cfcd1 100644 --- a/src/gitignore.rs +++ b/src/gitignore.rs @@ -1,5 +1,6 @@ //! This module contains an abstraction for gitignore files use crate::errors::*; +use crate::helpers::git_dir; use log::trace; use std::fs::OpenOptions; use std::path::PathBuf; @@ -19,6 +20,21 @@ impl Gitignore { Gitignore { path: path.clone() } } + /// Return a new `Gitignore` object from the default location + /// + /// This function gets the default .gitignore in the git root folder for the current working + /// directory + /// + /// # Errors + /// + /// - `ErrorKind::NoGitRootFound` when there was .gitignore file found at the default location + /// + pub fn from_default_path() -> Result { + let mut path = git_dir()?.ok_or(ErrorKind::NoGitRootFound)?; + path.push(".gitignore"); + Ok(Self::from_path(&path)) + } + /// Append a line to the file pub fn add_line(&self, line: &str) -> Result<()> { use std::io::prelude::*; @@ -31,6 +47,17 @@ impl Gitignore { writeln!(file, "{}", line).chain_err(|| "Error while writing line to gitignore")?; Ok(()) } + + /// Reads the contents of the gitignore file and adds them to buf + pub fn contents(&self, buf: &mut String) -> Result<()> { + use std::io::prelude::*; + let mut file = OpenOptions::new() + .read(true) + .open(&self.path) + .chain_err(|| "Error while opening gitignore file")?; + file.read_to_string(buf)?; + Ok(()) + } } impl std::fmt::Display for Gitignore {