From b71db54ee61d93efe823a2739f0e88792d2cb618 Mon Sep 17 00:00:00 2001 From: Kevin K Date: Thu, 23 Apr 2015 19:25:23 -0400 Subject: [PATCH] feat(clog): auto increment version with --major, --minor, or --patch Only compatible with semver at the moment Closes #19 --- Cargo.lock | 18 ++++++++++++------ Cargo.toml | 1 + src/git.rs | 18 +++++++++++++++--- src/main.rs | 41 +++++++++++++++++++++++++++++++++++------ 4 files changed, 63 insertions(+), 15 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 3b22e15..97b2b5b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2,14 +2,15 @@ name = "clog" version = "0.3.2" dependencies = [ - "clap 0.6.6 (registry+https://github.com/rust-lang/crates.io-index)", - "regex 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)", - "time 0.1.24 (registry+https://github.com/rust-lang/crates.io-index)", + "clap 0.6.7 (registry+https://github.com/rust-lang/crates.io-index)", + "regex 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", + "semver 0.1.19 (registry+https://github.com/rust-lang/crates.io-index)", + "time 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "clap" -version = "0.6.6" +version = "0.6.7" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -24,12 +25,17 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "regex" -version = "0.1.28" +version = "0.1.29" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "semver" +version = "0.1.19" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "time" -version = "0.1.24" +version = "0.1.25" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "gcc 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", diff --git a/Cargo.toml b/Cargo.toml index 9e0741e..ac5d740 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -13,3 +13,4 @@ description = "A conventional changelog for the rest of us" regex = "*" time = "*" clap = "*" +semver = "*" diff --git a/src/git.rs b/src/git.rs index ffc8fa7..02b468e 100644 --- a/src/git.rs +++ b/src/git.rs @@ -3,6 +3,8 @@ use common:: { LogEntry }; use common::CommitType; use std::borrow::ToOwned; +use semver; + #[derive(Debug)] pub struct LogReaderConfig { pub grep: String, @@ -16,17 +18,27 @@ pub fn get_latest_tag () -> String { .arg("rev-list") .arg("--tags") .arg("--max-count=1") - .output().unwrap_or_else(|e| panic!("Failed to run git rev-list with error: {}",e)); + .output().unwrap_or_else(|e| panic!("Failed to run 'git rev-list' with error: {}",e)); let buf = String::from_utf8_lossy(&output.stdout); buf.trim_matches('\n').to_owned() } +pub fn get_latest_tag_ver () -> Result { + let output = Command::new("git") + .arg("describe") + .arg("--tags") + .arg("--abbrev=0") + .output().unwrap_or_else(|e| panic!("Failed to run 'git describe' with error: {}",e)); + + semver::Version::parse(&String::from_utf8_lossy(&output.stdout)[..]) +} + pub fn get_last_commit () -> String { let output = Command::new("git") .arg("rev-parse") .arg("HEAD") - .output().unwrap_or_else(|e| panic!("Failed to run git rev-parse with error: {}", e)); + .output().unwrap_or_else(|e| panic!("Failed to run 'git rev-parse' with error: {}", e)); String::from_utf8_lossy(&output.stdout).into_owned() } @@ -44,7 +56,7 @@ pub fn get_log_entries (config:LogReaderConfig) -> Vec{ .arg(&format!("--grep={}",config.grep)) .arg(&format!("--format={}", "%H%n%s%n%b%n==END==")) .arg(&range) - .output().unwrap_or_else(|e| panic!("Failed to run git log with error: {}", e)); + .output().unwrap_or_else(|e| panic!("Failed to run 'git log' with error: {}", e)); String::from_utf8_lossy(&output.stdout) .split("\n==END==\n") diff --git a/src/main.rs b/src/main.rs index 4aad62c..c201f25 100644 --- a/src/main.rs +++ b/src/main.rs @@ -2,6 +2,7 @@ extern crate regex; extern crate time; +extern crate semver; #[macro_use] extern crate clap; @@ -32,14 +33,18 @@ fn main () { .version(&crate_version!()[..]) .about("a conventional changelog for the rest of us") .args_from_usage("-r --repository=[repository] 'e.g. https://github.com/thoughtram/clog' - --setversion=[setversion] 'e.g. 1.0.1' --from=[from] 'e.g. 12a8546' + --major 'Increment major version by one (Sets minor and patch to 0)' + --minor 'Increment minor version by one (Sets patch to 0)' + --patch 'Increment patch version by one' --subtitle=[subtitle] 'e.g. crazy-release-title' --to=[to] 'e.g. 8057684 (Defaults to HEAD when omitted)'") // Because --from-latest-tag can't be used with --from, we add it seperately so we can // specify a .mutually_excludes() .arg(Arg::from_usage("--from-latest-tag 'use latest tag as start (instead of --from)'") .mutually_excludes("from")) + .arg(Arg::from_usage("--setversion=[setversion] 'e.g. 1.0.1'") + .mutually_excludes_all(vec!["major", "minor", "patch"])) .get_matches(); let start_nsec = time::get_time().nsec; @@ -51,6 +56,34 @@ fn main () { to: matches.value_of("to").unwrap_or("").to_owned() }; + // compute version early, so we can exit on error + let version = { + // less typing later... + let (major, minor, patch) = (matches.is_present("major"), matches.is_present("minor"), matches.is_present("patch")); + if matches.is_present("setversion") { + matches.value_of("setversion").unwrap().to_owned() + } else if major || minor || patch { + match git::get_latest_tag_ver() { + Ok(ref mut v) => { + // if-else may be quicker, but it's longer mentally, and this isn't slow + match (major, minor, patch) { + (true,_,_) => { v.major += 1; v.minor = 0; v.patch = 0; }, + (_,true,_) => { v.minor += 1; v.patch = 0; }, + (_,_,true) => { v.patch += 1; }, + _ => unreachable!() + } + format!("{}", v) + }, + Err(e) => { + println!("Error parsing latest version: {}\nTry setting the version manually with --setversion=[version]", e ); + std::process::exit(1); + } + } + } else { + format_util::get_short_hash(&git::get_last_commit()[..]).to_owned() + } + }; + let commits = git::get_log_entries(log_reader_config); let sections = section_builder::build_sections(commits.clone()); @@ -62,11 +95,7 @@ fn main () { let mut file = File::create(&Path::new("changelog.md")).ok().unwrap(); let mut writer = LogWriter::new(&mut file, LogWriterOptions { repository_link: matches.value_of("repository").unwrap_or(""), - version: if matches.is_present("setversion") { - matches.value_of("setversion").unwrap().to_owned() - } else { - format_util::get_short_hash(&git::get_last_commit()[..]).to_owned() - }, + version: version, subtitle: matches.value_of("subtitle").unwrap_or("").to_owned() });