fn main() { // Initialize repository let repo = git2::Repository::open(std::env::var("REPOSITORY").unwrap()).unwrap(); let mut revwalk = repo.revwalk().unwrap(); revwalk .set_sorting(git2::Sort::NONE | git2::Sort::TIME) .unwrap(); revwalk.push_head().unwrap(); // Parse commits let mut fixes = Vec::new(); let mut features = Vec::new(); for commit in revwalk .filter_map(|id| id.ok()) .filter_map(|id| repo.find_commit(id).ok()) { let message = commit.message().unwrap(); if message.starts_with("feat") { features.push(commit); } else if message.starts_with("fix") { fixes.push(commit); } } // Generate changelog let generate = |commits: Vec| -> Vec { commits .iter() .map(|commit| { let id = commit.id().to_string(); format!( "* {} ([{}]({}))", commit.message().unwrap().trim(), &id[0..7], &id[0..7], ) }) .collect() }; let mut result = Vec::new(); result.push(String::from("## 0.1.0")); result.push(String::from("\n### Bug Fixes\n")); result.extend(generate(fixes)); result.push(String::from("\n### Features\n")); result.extend(generate(features)); result.push(String::from("\n")); // Print to file or stdout use std::io::Write; write!(std::io::stdout(), "{}", result.join("\n")).unwrap(); }