diff options
author | Justin Worthe <justin@worthe-it.co.za> | 2017-08-21 23:08:50 +0200 |
---|---|---|
committer | Justin Worthe <justin@worthe-it.co.za> | 2017-08-21 23:08:50 +0200 |
commit | c8a40229dabee642d598a9a8f852e33e6a183780 (patch) | |
tree | 34394dfae6f5ade0f57ea0b1fa114a7448f6da5c /src | |
parent | f3c7ede6af566839918cb884cde5572049962f7f (diff) |
Wrote example hook for prepending branch name to file
Diffstat (limited to 'src')
-rw-r--r-- | src/bin/prepare-commit-msg.rs | 57 | ||||
-rw-r--r-- | src/lib.rs | 31 |
2 files changed, 80 insertions, 8 deletions
diff --git a/src/bin/prepare-commit-msg.rs b/src/bin/prepare-commit-msg.rs index 8118374..63edba0 100644 --- a/src/bin/prepare-commit-msg.rs +++ b/src/bin/prepare-commit-msg.rs @@ -1,14 +1,55 @@ +extern crate rust_git_hooks; + +use rust_git_hooks::*; +use std::fs::File; +use std::io::Write; +use std::io::Read; +use std::process; use std::env; -use std::io::{stdin, BufRead}; fn main() { - let args: Vec<_> = env::args().skip(1).collect(); - println!("prepare-commit-msg called with {:?}", args); + log(); + + let current_branch = get_current_branch(); + let commit_filename = env::args().nth(1); - println!("BEGIN STDIN for prepare-commit-msg"); - let stdin = stdin(); - for line in stdin.lock().lines() { - println!("{:?}", line); + + match (current_branch, commit_filename) { + (Ok(branch), Some(filename)) => { + let write_result = prepend_branch_name(branch, filename); + match write_result { + Ok(_) => {}, + Err(e) => { + eprintln!("Failed to prepend message. {}", e); + process::exit(2); + } + }; + }, + (Err(e), _) => { + eprintln!("Failed to find current branch. {}", e); + process::exit(1); + }, + (_, None) => { + eprintln!("Commit file was not provided"); + process::exit(2); + } } - println!("END STDIN"); +} + +fn prepend_branch_name(branch_name: String, commit_filename: String) -> Result<(), std::io::Error> { + // It turns out that prepending a string to a file is not an + // obvious action. You can only write to the end of a file :( + // + // The solution is to read the existing contents, then write a new + // file starting with the branch name, and then writing the rest + // of the file. + + let mut read_commit_file = File::open(commit_filename.clone())?; + let mut current_message = String::new(); + read_commit_file.read_to_string(&mut current_message)?; + + let mut commit_file = File::create(commit_filename)?; + + writeln!(commit_file, "{}:", branch_name)?; + write!(commit_file, "{}", current_message) } diff --git a/src/lib.rs b/src/lib.rs new file mode 100644 index 0000000..18b3476 --- /dev/null +++ b/src/lib.rs @@ -0,0 +1,31 @@ +extern crate git2; + +use std::env; +use std::io::{stdin, BufRead}; + +use git2::Repository; + + +pub fn log() { + let name_arg = env::args().nth(0).unwrap_or(String::from("unknown")); + let args: Vec<_> = env::args().skip(1).collect(); + println!("{} called with {:?}", name_arg, args); + + println!("BEGIN STDIN"); + let stdin = stdin(); + for line in stdin.lock().lines() { + println!("{:?}", line); + } + println!("END STDIN"); +} + +pub fn get_current_branch() -> Result<String, git2::Error> { + let git_repo = Repository::discover("./")?; + let head = git_repo.head()?; + let head_name = head.shorthand(); + match head_name { + Some(name) => Ok(name.to_string()), + None => Err(git2::Error::from_str("No branch name found")) + } +} + |