Skip to content

Commit

Permalink
feat(log): add log filters
Browse files Browse the repository at this point in the history
  • Loading branch information
oknozor committed Sep 11, 2020
1 parent 819a04d commit 44bc3f3
Show file tree
Hide file tree
Showing 3 changed files with 81 additions and 5 deletions.
53 changes: 50 additions & 3 deletions src/bin/cog.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
use anyhow::Result;
use clap::{App, AppSettings, Arg, SubCommand};
use cocogitto::{CocoGitto, VersionIncrement};
use cocogitto::commit::CommitType;
use cocogitto::{CocoGitto, CommitFilter, CommitFilters, VersionIncrement};
use moins::Moins;
use std::process::exit;

Expand Down Expand Up @@ -55,16 +56,41 @@ fn main() -> Result<()> {
.long_about("Conventional Commit Git Terminal Overlord is a tool to help you use the conventional commit specification")
.subcommand(
SubCommand::with_name(CHECK)
.settings(SUBCOMMAND_SETTINGS)
.about("Verify all commit message against the conventional commit specification")
.arg(Arg::with_name("edit")
.help("Interactively rename invalid commit message")
.short("e")
.long("edit")
)
)
.subcommand(SubCommand::with_name(LOG).about("Like git log but for conventional commits"))
.subcommand(SubCommand::with_name(LOG)
.settings(SUBCOMMAND_SETTINGS)
.about("Like git log but for conventional commits")
.arg(Arg::with_name("breaking-change")
.help("filter BREAKING CHANGE commit")
.short("B")
.long("breaking-change"))
.arg(Arg::with_name("type")
.help("filter on commit type")
.short("t")
.takes_value(true)
.long("type"))
.arg(Arg::with_name("author")
.help("filter on commit author")
.short("a")
.takes_value(true)
.long("author"))
.arg(Arg::with_name("scope")
.help("filter on commit scope")
.short("s")
.takes_value(true)
.long("scope"))
)

.subcommand(
SubCommand::with_name(VERIFY)
.settings(SUBCOMMAND_SETTINGS)
.about("Verify a single commit message")
.arg(Arg::with_name("message").help("The commit message"))
)
Expand Down Expand Up @@ -164,7 +190,28 @@ fn main() -> Result<()> {
}
}
LOG => {
let mut content = cocogitto.get_log()?;
let subcommand = matches.subcommand_matches(LOG).unwrap();

let mut filters = vec![];
if let Some(commit_type) = subcommand.value_of("type") {
filters.push(CommitFilter::Type(CommitType::from(commit_type)));
}

if let Some(scope) = subcommand.value_of("scope") {
filters.push(CommitFilter::Scope(scope.to_string()));
}

if let Some(author) = subcommand.value_of("author") {
filters.push(CommitFilter::Author(author.to_string()));
}

if subcommand.is_present("breaking-change") {
filters.push(CommitFilter::BreakingChange);
}

let filters = CommitFilters(filters);

let mut content = cocogitto.get_log(filters)?;
Moins::run(&mut content, None);
}
CHANGELOG => {
Expand Down
2 changes: 1 addition & 1 deletion src/commit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -239,7 +239,7 @@ impl fmt::Display for Commit {
}

#[derive(Eq, PartialEq, Debug)]
pub(crate) enum CommitType {
pub enum CommitType {
Feature,
BugFix,
Chore,
Expand Down
31 changes: 30 additions & 1 deletion src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,31 @@ pub enum VersionIncrement {
Manual(String),
}

pub enum CommitFilter {
Type(CommitType),
Scope(String),
Author(String),
BreakingChange,
}

pub struct CommitFilters(pub Vec<CommitFilter>);

impl CommitFilters {
pub fn filters(&self, commit: &Commit) -> bool {
let mut take = true;
for filter in self.0.iter() {
take = take
&& match filter {
CommitFilter::Type(commit_type) => commit_type == &commit.message.commit_type,
CommitFilter::Scope(scope) => Some(scope) == commit.message.scope.as_ref(),
CommitFilter::Author(author) => author == &commit.author,
CommitFilter::BreakingChange => commit.message.is_breaking_change,
}
}
take
}
}

impl CocoGitto {
pub fn get() -> Result<Self> {
let repository = Repository::open()?;
Expand Down Expand Up @@ -167,14 +192,18 @@ impl CocoGitto {
Ok(())
}

pub fn get_log(&self) -> Result<String> {
pub fn get_log(&self, filters: CommitFilters) -> Result<String> {
let from = self.repository.get_first_commit()?;
let to = self.repository.get_head_commit_oid()?;
let commits = self.get_commit_range(from, to)?;
let logs = commits
.iter()
.filter(|commit| !commit.message().unwrap_or("").starts_with("Merge"))
.map(|commit| Commit::from_git_commit(commit))
.filter(|commit| match commit {
Ok(commit) => filters.filters(commit),
Err(err) => true,
})
.map(|commit| match commit {
Ok(commit) => commit.get_log(),
Err(err) => err.to_string(),
Expand Down

0 comments on commit 44bc3f3

Please sign in to comment.