From c8a40229dabee642d598a9a8f852e33e6a183780 Mon Sep 17 00:00:00 2001 From: Justin Worthe Date: Mon, 21 Aug 2017 23:08:50 +0200 Subject: Wrote example hook for prepending branch name to file --- Cargo.lock | 186 ++++++++++++++++++++++++++++++++++++++++++ Cargo.toml | 1 + src/bin/prepare-commit-msg.rs | 57 +++++++++++-- src/lib.rs | 31 +++++++ 4 files changed, 267 insertions(+), 8 deletions(-) create mode 100644 src/lib.rs diff --git a/Cargo.lock b/Cargo.lock index 1804eaf..ef6e4fe 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1,4 +1,190 @@ [root] name = "rust_git_hooks" version = "0.1.0" +dependencies = [ + "git2 0.6.6 (registry+https://github.com/rust-lang/crates.io-index)", +] +[[package]] +name = "bitflags" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "cmake" +version = "0.1.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "gcc 0.3.53 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "curl-sys" +version = "0.3.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "gcc 0.3.53 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.29 (registry+https://github.com/rust-lang/crates.io-index)", + "libz-sys 1.0.16 (registry+https://github.com/rust-lang/crates.io-index)", + "openssl-sys 0.9.17 (registry+https://github.com/rust-lang/crates.io-index)", + "pkg-config 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", + "vcpkg 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "gcc" +version = "0.3.53" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "git2" +version = "0.6.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "bitflags 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.29 (registry+https://github.com/rust-lang/crates.io-index)", + "libgit2-sys 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)", + "openssl-probe 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", + "openssl-sys 0.9.17 (registry+https://github.com/rust-lang/crates.io-index)", + "url 1.5.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "idna" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "matches 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", + "unicode-bidi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", + "unicode-normalization 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "libc" +version = "0.2.29" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "libgit2-sys" +version = "0.6.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "cmake 0.1.24 (registry+https://github.com/rust-lang/crates.io-index)", + "curl-sys 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)", + "gcc 0.3.53 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.29 (registry+https://github.com/rust-lang/crates.io-index)", + "libssh2-sys 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)", + "libz-sys 1.0.16 (registry+https://github.com/rust-lang/crates.io-index)", + "openssl-sys 0.9.17 (registry+https://github.com/rust-lang/crates.io-index)", + "pkg-config 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "libssh2-sys" +version = "0.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "cmake 0.1.24 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.29 (registry+https://github.com/rust-lang/crates.io-index)", + "libz-sys 1.0.16 (registry+https://github.com/rust-lang/crates.io-index)", + "openssl-sys 0.9.17 (registry+https://github.com/rust-lang/crates.io-index)", + "pkg-config 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "libz-sys" +version = "1.0.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "gcc 0.3.53 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.29 (registry+https://github.com/rust-lang/crates.io-index)", + "pkg-config 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", + "vcpkg 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "matches" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "openssl-probe" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "openssl-sys" +version = "0.9.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "gcc 0.3.53 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.29 (registry+https://github.com/rust-lang/crates.io-index)", + "pkg-config 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", + "vcpkg 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "percent-encoding" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "pkg-config" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "unicode-bidi" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "matches 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "unicode-normalization" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "url" +version = "1.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "idna 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", + "matches 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", + "percent-encoding 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "vcpkg" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "winapi" +version = "0.2.8" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[metadata] +"checksum bitflags 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)" = "4efd02e230a02e18f92fc2735f44597385ed02ad8f831e7c1c1156ee5e1ab3a5" +"checksum cmake 0.1.24 (registry+https://github.com/rust-lang/crates.io-index)" = "b8ebbb35d3dc9cd09497168f33de1acb79b265d350ab0ac34133b98f8509af1f" +"checksum curl-sys 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)" = "d5481162dc4f424d088581db2f979fa7d4c238fe9794595de61d8d7522e277de" +"checksum gcc 0.3.53 (registry+https://github.com/rust-lang/crates.io-index)" = "e8310f7e9c890398b0e80e301c4f474e9918d2b27fca8f48486ca775fa9ffc5a" +"checksum git2 0.6.6 (registry+https://github.com/rust-lang/crates.io-index)" = "aa01936ac96555c083c0e8553f672616274408d9d3fc5b8696603fbf63ff43ee" +"checksum idna 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "014b298351066f1512874135335d62a789ffe78a9974f94b43ed5621951eaf7d" +"checksum libc 0.2.29 (registry+https://github.com/rust-lang/crates.io-index)" = "8a014d9226c2cc402676fbe9ea2e15dd5222cd1dd57f576b5b283178c944a264" +"checksum libgit2-sys 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)" = "0f1641ccb55181967a3e5ee4ae2911c0563492f016383ea67a27886181de088c" +"checksum libssh2-sys 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "0db4ec23611747ef772db1c4d650f8bd762f07b461727ec998f953c614024b75" +"checksum libz-sys 1.0.16 (registry+https://github.com/rust-lang/crates.io-index)" = "3fdd64ef8ee652185674455c1d450b83cbc8ad895625d543b5324d923f82e4d8" +"checksum matches 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "100aabe6b8ff4e4a7e32c1c13523379802df0772b82466207ac25b013f193376" +"checksum openssl-probe 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "d98df0270d404ccd3c050a41d579c52d1db15375168bb3471e04ec0f5f378daf" +"checksum openssl-sys 0.9.17 (registry+https://github.com/rust-lang/crates.io-index)" = "7e3a9845a4c9fdb321931868aae5549e96bb7b979bf9af7de03603d74691b5f3" +"checksum percent-encoding 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "de154f638187706bde41d9b4738748933d64e6b37bdbffc0b47a97d16a6ae356" +"checksum pkg-config 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)" = "3a8b4c6b8165cd1a1cd4b9b120978131389f64bdaf456435caa41e630edba903" +"checksum unicode-bidi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "49f2bd0c6468a8230e1db229cff8029217cf623c767ea5d60bfbd42729ea54d5" +"checksum unicode-normalization 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "51ccda9ef9efa3f7ef5d91e8f9b83bbe6955f9bf86aec89d5cce2c874625920f" +"checksum url 1.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "eeb819346883532a271eb626deb43c4a1bb4c4dd47c519bd78137c3e72a4fe27" +"checksum vcpkg 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "9e0a7d8bed3178a8fb112199d466eeca9ed09a14ba8ad67718179b4fd5487d0b" +"checksum winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "167dc9d6949a9b857f3451275e911c3f44255842c1f7a76f33c55103a909087a" diff --git a/Cargo.toml b/Cargo.toml index 0d70e26..b81c43d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -4,3 +4,4 @@ version = "0.1.0" authors = ["Justin Worthe "] [dependencies] +git2 = "0.6" \ No newline at end of file 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 { + 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")) + } +} + -- cgit v1.2.3