diff --git a/src/app.rs b/src/app.rs index 6adfa3b..3e128bd 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, @@ -107,7 +107,10 @@ fn add(glob: &str, local: bool) -> Result<()> { info!("Working with git root in {:?}", root); let mut file_path = PathBuf::from(&root); - if local { + let override_path = std::env::var("GITIG_OVERRIDE_PATH").ok(); + if let Some(override_path) = override_path { + file_path = PathBuf::from(override_path); + } else if local { file_path.push(".git/info/exclude") } else { file_path.push(".gitignore"); @@ -204,4 +207,4 @@ mod tests { fn test_something() { // TODO: Test something } -} +} \ No newline at end of file diff --git a/src/gitignore.rs b/src/gitignore.rs index 89cfcd1..90a679e 100644 --- a/src/gitignore.rs +++ b/src/gitignore.rs @@ -28,7 +28,6 @@ impl Gitignore { /// # 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"); @@ -40,11 +39,30 @@ impl Gitignore { use std::io::prelude::*; let mut file = OpenOptions::new() .write(true) + .read(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")?; + + let file_len = file.stream_len()?; + let newline = if file_len > 0 { + file.seek(std::io::SeekFrom::End(-1))?; + let mut buf: Vec = vec![0; 1]; + file.read_exact(&mut buf)?; + if buf[0] == '\n' as u8 { + // The last line already ends with a newline + "" + } else { + // Add a newline if the last line doesn't end with one + "\n" + } + } else { + // The file is empty, so we don't need a newline + "" + }; + writeln!(file, "{}{}", newline, line) + .chain_err(|| "Error while writing line to gitignore")?; Ok(()) } @@ -64,4 +82,4 @@ 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()) } -} +} \ No newline at end of file diff --git a/src/main.rs b/src/main.rs index 122213b..aba1192 100644 --- a/src/main.rs +++ b/src/main.rs @@ -29,6 +29,7 @@ This project used [rust-cli-boilerplate](https://github.com/ssokolow/rust-cli-bo clippy::wildcard_imports, clippy::integer_arithmetic )] +#![feature(seek_stream_len)] #[macro_use] extern crate error_chain; @@ -94,4 +95,4 @@ fn main() { } } -// vim: set sw=4 sts=4 expandtab : +// vim: set sw=4 sts=4 expandtab : \ No newline at end of file