Skip to content

Commit

Permalink
feat: add check from latest tag option
Browse files Browse the repository at this point in the history
coucou
  • Loading branch information
oknozor committed Jul 15, 2021
1 parent 80e4887 commit caa6ec3
Show file tree
Hide file tree
Showing 7 changed files with 76 additions and 15 deletions.
9 changes: 9 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ features related to the conventional commit specification. Anything else shall b
- [Pre bump hooks](#pre-bump-hooks)
- [Post bump hooks](#post-bump-hooks)
- [Builtin git hooks](#Builtin-git-hooks)
- [Github action](#Github action)
- [Contributing](#Contributing)
- [Licence](#Licence)

Expand Down Expand Up @@ -233,6 +234,10 @@ ERROR - Your Mother Was A Hamster, And Your Father Smelt Of Elderberries - (c82c
cause: invalid commit format : missing `: ` separator
```

Additionally, you can check your history, starting from the latest tag to HEAD using `from-latest-tag` flag.
This is useful when your git repo started to use conventional commits from a certain point in history, and you
don't care about editing old commits.

### Edit commit history

Once you have spotted invalid commits you can quickly fix your commit history by running `cog edit`.
Expand Down Expand Up @@ -466,6 +471,10 @@ Or one by one, specifying the hook name :
cog install-hook pre-commit
```

## Github action

You can run cog check on github action using [cog-conventional-check](https://github.com/oknozor/cog-conventional-check)

## Contributing

Found a bug, have a suggestion for a new feature ? Please read the contribution guideline and submit an issue.
Expand Down
11 changes: 10 additions & 1 deletion src/bin/cog.rs
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,9 @@ fn main() -> Result<()> {

CHECK => {
let cocogitto = CocoGitto::get()?;
cocogitto.check()?;
let subcommand = matches.subcommand_matches(CHECK).unwrap();
let from_tag = subcommand.is_present("from-latest-tag");
cocogitto.check(from_tag)?;
}
EDIT => {
let cocogitto = CocoGitto::get()?;
Expand Down Expand Up @@ -186,6 +188,13 @@ fn app<'a, 'b>() -> App<'a, 'b> {
let check_command = SubCommand::with_name(CHECK)
.settings(SUBCOMMAND_SETTINGS)
.about("Verify all commit message against the conventional commit specification")
.arg(
Arg::with_name("from-latest-tag")
.help("Check commit history, starting from the latest tag to HEAD")
.short("l")
.takes_value(false)
.long("from-latest-tag"),
)
.display_order(1);

let edit_command = SubCommand::with_name(EDIT)
Expand Down
2 changes: 1 addition & 1 deletion src/conventional/commit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -180,11 +180,11 @@ impl Commit {
);

Ok(CommitMessage {
description,
commit_type,
scope,
body,
footer,
description,
is_breaking_change,
})
}
Expand Down
4 changes: 2 additions & 2 deletions src/git/hook.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
use crate::CocoGitto;
use anyhow::Result;
use std::path::PathBuf;

use std::fs::Permissions;
#[cfg(target_family = "unix")]
use std::os::unix::fs::PermissionsExt;

use std::fs;
use std::path::Path;

pub static PRE_PUSH_HOOK: &[u8] = include_bytes!("assets/pre-push");
pub static PREPARE_COMMIT_HOOK: &[u8] = include_bytes!("assets/prepare-commit-msg");
Expand Down Expand Up @@ -40,7 +40,7 @@ impl CocoGitto {
}
}

fn create_hook(path: &PathBuf, kind: HookKind) -> Result<()> {
fn create_hook(path: &Path, kind: HookKind) -> Result<()> {
let (hook_path, hook_content) = match kind {
HookKind::PrepareCommit => (path.join(PRE_COMMIT_HOOK_PATH), PREPARE_COMMIT_HOOK),
HookKind::PrePush => (path.join(PRE_PUSH_HOOK_PATH), PRE_PUSH_HOOK),
Expand Down
9 changes: 3 additions & 6 deletions src/hook/parser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -60,12 +60,9 @@ impl HookExpr {

fn scan_hook_entry(hook_entry: &str) -> Option<HookExpr> {
match hook_entry.find(DELIMITER_START) {
Some(start) => match hook_entry.find(DELIMITER_END) {
Some(end) => Some(HookExpr::from_str(
&hook_entry[start + DELIMITER_START.len()..end],
)),
None => None,
},
Some(start) => hook_entry
.find(DELIMITER_END)
.map(|end| HookExpr::from_str(&hook_entry[start + DELIMITER_START.len()..end])),
None => None,
}
}
Expand Down
16 changes: 13 additions & 3 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,6 @@ use conventional::version::{parse_pre_release, VersionIncrement};
use git::repository::Repository;
use git2::{Oid, RebaseOptions};
use hook::Hook;
use itertools::Itertools;
use log::filter::CommitFilters;
use semver::Version;
use settings::AuthorSetting;
Expand Down Expand Up @@ -269,8 +268,17 @@ impl CocoGitto {
Ok(())
}

pub fn check(&self) -> Result<()> {
let from = self.repository.get_first_commit()?;
#[allow(unstable_name_collisions)]
pub fn check(&self, check_from_latest_tag: bool) -> Result<()> {
let from = if check_from_latest_tag {
self.repository.get_latest_tag_oid().unwrap_or_else(|_err| {
println!("No previous tag found, falling back to first commit");
self.repository.get_first_commit().unwrap()
})
} else {
self.repository.get_first_commit()?
};

let to = self.repository.get_head_commit_oid()?;
let commits = self.repository.get_commit_range(from, to)?;
let errors: Vec<anyhow::Error> = commits
Expand All @@ -281,6 +289,8 @@ impl CocoGitto {
.map(|err| err.unwrap_err())
.collect();

use itertools::Itertools;

if errors.is_empty() {
let msg = "No errored commits".green();
println!("{}", msg);
Expand Down
40 changes: 38 additions & 2 deletions tests/git_test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ fn check_commit_history_ok() -> Result<()> {

let gitto = CocoGitto::get()?;

assert!(gitto.check().is_ok());
assert!(gitto.check(false).is_ok());
Ok(())
}

Expand All @@ -61,6 +61,42 @@ fn check_commit_history_err() -> Result<()> {

let gitto = CocoGitto::get()?;

assert!(gitto.check().is_err());
assert!(gitto.check(false).is_err());
Ok(())
}

#[test]
fn check_commit_ok_from_latest_tag() -> Result<()> {
let tmp = TempDir::new()?;
std::env::set_current_dir(&tmp)?;
git_init("commit_ok_from_tag")?;
std::env::set_current_dir(&tmp.path().join("commit_ok_from_tag"))?;

create_empty_config()?;
git_commit("this one should not be picked")?;
git_tag("0.1.0")?;
git_commit("feat: another commit")?;

let gitto = CocoGitto::get()?;

assert!(gitto.check(true).is_ok());
Ok(())
}

#[test]
fn check_commit_err_from_latest_tag() -> Result<()> {
let tmp = TempDir::new()?;
std::env::set_current_dir(&tmp)?;
git_init("commit_err_from_tag")?;
std::env::set_current_dir(&tmp.path().join("commit_err_from_tag"))?;

create_empty_config()?;
git_commit("this one should not be picked")?;
git_tag("0.1.0")?;
git_commit("Oh no!")?;

let gitto = CocoGitto::get()?;

assert!(gitto.check(true).is_err());
Ok(())
}

0 comments on commit caa6ec3

Please sign in to comment.