Skip to content

Commit

Permalink
feat(aliases): implement aliases for commit types
Browse files Browse the repository at this point in the history
This is a decent change. Now the CommitType enum is auto-generated via a
macro. This macro also implements two helper methods, and one Trait. The
helper methods return a Vec<'static str> of all "aliases" for specified
variant if called like CommitType::Variant.aliases(). Or if called on
the enum itself there the method returns ALL aliases such as
CommitType::all_aliases(). The macro also implments the
std::str::FromStr trait so you can parse from a string to a known enum
type automatically. Say we defined a "feat" or "ft" alias of variant
"Feature", if we had a string of "ft" or "feature" we could call
some_str.parse::<CommitType>().unwrap() to get a CommitType::Feature, or if it
failed to parse we get a CommitType::Unknown

Closes #3
  • Loading branch information
kbknapp committed Apr 24, 2015
1 parent 8545a68 commit 44f7d49
Show file tree
Hide file tree
Showing 4 changed files with 69 additions and 18 deletions.
16 changes: 11 additions & 5 deletions src/common.rs
@@ -1,11 +1,17 @@
use std::fmt;
use std::collections::HashMap;

#[derive(Debug, PartialEq, Clone)]
pub enum CommitType {
Feature,
Fix,
Unknown
// Creates an enum where the poritions inside the '(' and ')' act as aliases for that
// commit type. The only one you MUST specify is 'Unknown ()'
//
// Later you can call CommitType::Fix.aliases() to get all the aliases as a Vec<'statci str>
commit_type_enum!{
#[derive(Debug, PartialEq, Clone)]
pub enum CommitType {
Feature ( feat, ft ),
Fix ( fix, fx),
Unknown ()
}
}

#[derive(Clone)]
Expand Down
10 changes: 5 additions & 5 deletions src/git.rs
Expand Up @@ -5,6 +5,7 @@ use std::borrow::ToOwned;

use semver;


#[derive(Debug)]
pub struct LogReaderConfig {
pub grep: String,
Expand Down Expand Up @@ -75,11 +76,10 @@ fn parse_raw_commit(commit_str:&str) -> LogEntry {
let (subject, component, commit_type) =
match lines.next().and_then(|s| commit_pattern.captures(s)) {
Some(caps) => {
let commit_type = match caps.at(1) {
Some("feat") => CommitType::Feature,
Some("fix") => CommitType::Fix,
_ => CommitType::Unknown
};
// The macro that made the CommitType automatically implements std::str::FromStr
// with all aliases or falls back to CommitType::Unknown on failure so we can
// call unwrap().
let commit_type = caps.at(1).unwrap_or("").parse::<CommitType>().unwrap();
let component = caps.at(2);
let subject = caps.at(3);
(subject, component, commit_type)
Expand Down
46 changes: 46 additions & 0 deletions src/macros.rs
@@ -0,0 +1,46 @@
// regex cheat thanks to https://github.com/BurntSushi
macro_rules! regex(
($s:expr) => (::regex::Regex::new($s).unwrap());
);

// A macro creating an entry types, and their aliases
//
// This is a little hacky, because it expects an Unknown () variant
//
// TODO: de-dup with recursive calls
macro_rules! commit_type_enum {
(#[derive($($d:ident),+)] pub enum $e:ident { $($v:ident ( $($a:ident),* ) ),+ }) => {
#[derive($($d,)+)]
pub enum $e {
$($v,)+
}

impl $e {
#[allow(dead_code)]
pub fn aliases(&self) -> Vec<&'static str> {
match *self {
$($e::$v => vec![
$( stringify!($a) ),*
],)+
}
}
#[allow(dead_code)]
pub fn all_aliases() -> Vec<&'static str> {
vec![
$( $( stringify!($a),)* )+
]
}
}
impl ::std::str::FromStr for $e {
type Err = $e;

#[allow(dead_code)]
fn from_str(s: &str) -> Result<Self,Self::Err> {
match s {
$(stringify!($v) $( | stringify!($a) )* => Ok($e::$v),)+
_ => Err($e::Unknown)
}
}
}
};
}
15 changes: 7 additions & 8 deletions src/main.rs
Expand Up @@ -7,20 +7,19 @@ extern crate semver;
#[macro_use]
extern crate clap;

use git::LogReaderConfig;
use log_writer::{ LogWriter, LogWriterOptions };
use std::fs::File;
use std::io::Read;
use std::path::Path;
use std::borrow::ToOwned;

use clap::{App, Arg};
use common::CommitType;
use git::LogReaderConfig;
use log_writer::{ LogWriter, LogWriterOptions };

// regex cheat thanks to https://github.com/BurntSushi
macro_rules! regex(
($s:expr) => (::regex::Regex::new($s).unwrap());
);
use clap::{App, Arg};

#[macro_use]
mod macros;
mod common;
mod git;
mod log_writer;
Expand Down Expand Up @@ -50,7 +49,7 @@ fn main () {
let start_nsec = time::get_time().nsec;

let log_reader_config = LogReaderConfig {
grep: "^feat|^fix|BREAKING'".to_owned(),
grep: format!("{}BREAKING'", CommitType::all_aliases().iter().fold(String::new(),|acc, al| acc + &format!("^{}|", al)[..])),
format: "%H%n%s%n%b%n==END==".to_owned(),
from: if matches.is_present("from-latest-tag") { Some(git::get_latest_tag()) } else { matches.value_of("from").map(|v| v.to_owned()) },
to: matches.value_of("to").unwrap_or("").to_owned()
Expand Down

0 comments on commit 44f7d49

Please sign in to comment.