gitig 0.3.0

A cli utility to manage gitignore files easily
//! 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;

/// An abstraction of the gitignore file
#[derive(Debug, Default)]
pub struct Gitignore {
    /// The path to the gitignore
    path: PathBuf,
}
impl Gitignore {
    /// Create a new Gitignore struct from a git root folder path
    ///
    /// The given `path` must be a valid path to an existing git root folder
    pub fn from_path(path: &PathBuf) -> Self {
        trace!("Creating gitignore file object for path {}", path.to_string_lossy());
        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<Self> {
        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::*;
        let mut file = OpenOptions::new()
            .write(true)
            .append(true)
            .create(true)
            .open(&self.path)
            .chain_err(|| "Error while opening gitignore file")?;
        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 {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::result::Result<(), std::fmt::Error> {
        write!(f, "gitignore file {}", self.path.to_string_lossy())
    }
}