Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

(WIP) Cocogitto mono #392

Closed
wants to merge 40 commits into from
Closed
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
40 commits
Select commit Hold shift + click to select a range
6a6bf74
refactor: step 1 toward cargo workspace
oknozor May 15, 2024
b78c7b8
refactor: toward cargo workspace
oknozor May 15, 2024
73ea917
refactor: rm settings
oknozor May 16, 2024
088724f
refactor: toward monorepo, extract binary crate
oknozor May 16, 2024
56040d9
test: fix test
oknozor May 16, 2024
a8b78ee
docs: add docs for test helpers
oknozor May 16, 2024
fbcf09b
feat: prepare for tag extraction
oknozor May 16, 2024
a3539ee
refactor: extract tag
oknozor May 16, 2024
e33f2c7
refactor: extract hook
oknozor May 16, 2024
a459dde
refactor: remove cog config dependencies from tag
oknozor May 16, 2024
521e19a
refactor: remove cog config dependencies from hook
oknozor May 16, 2024
6fe4fc5
refactor: rename tag metadata fns
oknozor May 16, 2024
abedc83
refactor: extract ch, commit, oid
oknozor May 16, 2024
83aa0d9
chore: thanks machete
oknozor May 16, 2024
195115d
refactor: extract git
oknozor May 18, 2024
4eab1c0
refactor: remove config deps from commits
oknozor May 18, 2024
33ce450
refactor: extract cocogitto-changelog
oknozor May 19, 2024
0e7146e
refactor: extract cocogitto-bump
oknozor May 19, 2024
cb73c15
chore: remove unused conventional modul
oknozor May 19, 2024
1bc266a
chore: remove config deps from changelog
oknozor May 19, 2024
4ff7295
refactor: extract check command
oknozor May 21, 2024
2ee9f31
refactor: prefix command crate with cog
oknozor May 21, 2024
22c0805
refactor: extract cog commit command
oknozor May 21, 2024
ed303b7
docs: add crate for schema generation
mewhhaha May 20, 2024
5f7f1f3
chore: comment deny missing doc to get CI running
oknozor May 21, 2024
73cf471
chore: thanks clippy
oknozor May 21, 2024
32ff32c
refactor: extract cog get version command
oknozor May 21, 2024
a2ae1c9
chore: thanks machete
oknozor May 21, 2024
d9fa034
refactor: extract cog install hooks command
oknozor May 21, 2024
17593e5
refactor: extract cog init
oknozor May 21, 2024
08394a3
refactor: extract cog log
oknozor May 21, 2024
beeb212
chore: thanks machete
oknozor May 21, 2024
45e01b0
refactor: extract cog edit
oknozor May 21, 2024
a5a4f0b
feat: add changelog command
oknozor Jun 18, 2024
1a32def
refactor: extract changelog step 1
oknozor Jun 18, 2024
6593767
refactor: remove settings from cocogitto-changelog
oknozor Jun 19, 2024
88c860f
refactor: extract verify command
oknozor Jun 19, 2024
88f8ae4
refactor: extract bump command
oknozor Jun 19, 2024
d680593
refactor: finishing extractions
oknozor Jun 19, 2024
471605f
chore: use workspace deps for cog
oknozor Jun 20, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
chore: remove config deps from changelog
  • Loading branch information
oknozor committed May 19, 2024
commit 1bc266ad9a254ee6c87c464dd2d9761b5675ef92
4 changes: 2 additions & 2 deletions crates/cocogitto-changelog/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ version = "0.1.0"
edition = "2021"

[dependencies]
cocogitto-config.workspace = true
cocogitto-commit.workspace = true
cocogitto-git.workspace = true
cocogitto-oid.workspace = true
Expand All @@ -30,4 +29,5 @@ sealed_test.workspace = true
git2.workspace = true
toml.workspace = true
indoc.workspace = true
pretty_assertions.workspace = true
pretty_assertions.workspace = true
cocogitto-config.workspace = true
206 changes: 1 addition & 205 deletions crates/cocogitto-changelog/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -72,208 +72,4 @@ impl Release<'_> {
}

#[cfg(test)]
mod test {
use crate::release::Release;
use cocogitto_git::tag::TagLookUpOptions;
use cocogitto_git::Repository;
use cocogitto_oid::OidOf;
use cocogitto_test_helpers::*;
use git2::Oid;
use sealed_test::prelude::sealed_test;
use sealed_test::prelude::*;
use speculoos::prelude::*;

#[sealed_test]
fn shoud_get_range_for_a_single_release() -> anyhow::Result<()> {
// Arrange
let repo = git_init_no_gpg()?;
let one = commit("chore: first commit")?;
let two = commit("feat: feature 1")?;
let three = commit("feat: feature 2")?;
git_tag("0.1.0")?;

let range = repo.revwalk("0.1.0");

let range = range?;

// Act
let release = Release::try_from(range)?;

// Assert
assert_that!(release.previous).is_none();
assert_that!(release.version.oid()).is_equal_to(&Oid::from_str(&three)?);
assert_that!(release.from).is_equal_to(OidOf::FirstCommit(Oid::from_str(&one)?));

let expected_commits: Vec<String> = release
.commits
.into_iter()
.map(|commit| commit.commit.oid)
.collect();

assert_that!(expected_commits).is_equal_to(vec![three, two, one]);

Ok(())
}

#[sealed_test]
fn shoud_get_range_for_a_multiple_release() -> anyhow::Result<()> {
// Arrange
let repo = git_init_no_gpg()?;
let one = commit("chore: first commit")?;
let two = commit("feat: feature 1")?;
let three = commit("feat: feature 2")?;
git_tag("0.1.0")?;
let four = commit("feat: feature 3")?;
let five = commit("feat: feature 4")?;
git_tag("0.2.0")?;

let range = repo.revwalk("..0.2.0")?;

// Act
let release = Release::try_from(range)?;

// Assert
assert_that!(release.previous).is_some().matches(|_child| {
let commits: Vec<String> = release
.previous
.as_ref()
.unwrap()
.commits
.iter()
.map(|commit| commit.commit.oid.clone())
.collect();

commits == [three.clone(), two.clone(), one.clone()]
});

assert_that!(release.version.to_string()).is_equal_to("0.2.0".to_string());
assert_that!(release.from.to_string()).is_equal_to("0.1.0".to_string());

let expected_commits: Vec<String> = release
.commits
.into_iter()
.map(|commit| commit.commit.oid)
.collect();

assert_that!(expected_commits).is_equal_to(vec![five, four]);

Ok(())
}

#[test]
fn get_release_range_integration_test() -> anyhow::Result<()> {
// Arrange
let repo = open_cocogitto_repo()?;
let range = repo.revwalk("0.32.1..0.32.3")?;

// Act
let release = Release::try_from(range)?;

// Assert
assert_that!(release.version.to_string()).is_equal_to("0.32.3".to_string());

let release = *release.previous.unwrap();
assert_that!(release.version.to_string()).is_equal_to("0.32.2".to_string());

assert_that!(release.previous).is_none();
Ok(())
}

#[test]
fn recursive_from_origin_to_head() -> anyhow::Result<()> {
// Arrange
let repo = Repository::open(&get_workspace_root())?;
let mut tag_count = repo.tag_names(None)?.len();
let head = repo.get_head_commit_oid()?;
let latest = repo.get_latest_tag(TagLookUpOptions::default())?;
let latest = latest.oid();
if latest == Some(&head) {
tag_count -= 1;
};

let range = repo.revwalk("..")?;

// Act
let mut release = Release::try_from(range)?;
let mut count = 0;

while let Some(previous) = release.previous {
release = *previous;
count += 1;
}

// Assert
assert_that!(count).is_equal_to(tag_count);

Ok(())
}

#[sealed_test]
fn from_commit_to_head() -> anyhow::Result<()> {
// Arrange
let repo = git_init_no_gpg()?;

commit("chore: init")?;
commit("feat: a commit")?;
let one = commit("chore: another commit")?;
let two = commit("feat: a feature")?;
let three = commit("chore: 1.0.0")?;
let four = commit("fix: the bug")?;

let range = repo.revwalk(&format!("{}..", &one[0..7]))?;

// Act
let release = Release::try_from(range)?;

// Assert
let actual_oids: Vec<String> = release
.commits
.iter()
.map(|commit| commit.commit.oid.to_string())
.collect();

assert_that!(actual_oids).is_equal_to(vec![four, three, two]);

Ok(())
}

#[sealed_test]
fn from_commit_to_head_with_overlapping_tag() -> anyhow::Result<()> {
// Arrange
let repo = git_init_no_gpg()?;

commit("chore: init")?;
commit("feat: a commit")?;

let from = commit("chore: another commit")?;
let one = commit("feat: a feature")?;
let two = commit("chore: 1.0.0")?;
git_tag("1.0.0")?;
let three = commit("fix: the bug")?;

let range = repo.revwalk(&format!("{}..", &from[0..7]))?;

// Act
let release = Release::try_from(range)?;

// Assert
let head_to_v1: Vec<String> = release
.commits
.iter()
.map(|commit| commit.commit.oid.to_string())
.collect();

let commit_before_v1: Vec<String> = release
.previous
.unwrap()
.commits
.iter()
.map(|commit| commit.commit.oid.to_string())
.collect();

assert_that!(head_to_v1).is_equal_to(vec![three]);
assert_that!(commit_before_v1).is_equal_to(vec![two, one]);

Ok(())
}
}
mod test {}
111 changes: 20 additions & 91 deletions crates/cocogitto-changelog/src/release.rs
Original file line number Diff line number Diff line change
@@ -1,14 +1,8 @@
use chrono::{NaiveDateTime, Utc};
use chrono::NaiveDateTime;
use serde::Serialize;

use cocogitto_commit::{Commit, Footer};
use colored::Colorize;

use crate::error::ChangelogError;
use cocogitto_config::SETTINGS;
use cocogitto_git::rev::CommitIter;
use cocogitto_oid::OidOf;
use log::warn;

#[derive(Debug, Serialize)]
pub struct Release<'a> {
Expand All @@ -19,79 +13,24 @@ pub struct Release<'a> {
pub previous: Option<Box<Release<'a>>>,
}

impl TryFrom<CommitIter<'_>> for Release<'_> {
type Error = ChangelogError;

fn try_from(commits: CommitIter<'_>) -> Result<Self, Self::Error> {
let mut releases = vec![];
let mut commit_iter = commits.into_iter().rev().peekable();

while let Some((_oid, _commit)) = commit_iter.peek() {
let mut release_commits = vec![];

for (oid, commit) in commit_iter.by_ref() {
if matches!(oid, OidOf::Tag(_)) {
release_commits.push((oid, commit));
break;
}
release_commits.push((oid, commit));
}

release_commits.reverse();
releases.push(release_commits);
}

let mut current = None;

for release in releases {
let next = Release {
version: release.first().unwrap().0.clone(),
from: current
.as_ref()
.map(|current: &Release| current.version.clone())
.unwrap_or(release.last().unwrap().0.clone()),
date: Utc::now().naive_local(),
commits: release
.iter()
.filter_map(|(_, commit)| {
match Commit::from_git_commit(commit, &SETTINGS.allowed_commit_types()) {
Ok(commit) => {
let commit_type = &commit.conventional.commit_type;
if !SETTINGS.should_omit_commit(commit_type) {
Some(ChangelogCommit::from(commit))
} else {
None
}
}
Err(err) => {
let err = err.to_string().red();
warn!("{}", err);
None
}
}
})
.collect(),
previous: current.map(Box::new),
};

current = Some(next);
}

current.ok_or(ChangelogError::EmptyRelease)
}
}

#[derive(Debug)]
pub struct ChangelogCommit<'a> {
pub changelog_title: String,
pub author_username: Option<&'a str>,
pub commit: Commit,
}

impl From<Commit> for ChangelogCommit<'_> {
fn from(commit: Commit) -> Self {
let author_username = cocogitto_config::commit_username(&commit.author);

impl<'a, 'b> ChangelogCommit<'a>
where
'b: 'a,
{
pub fn from_commit(
commit: Commit,
author_username: Option<&'a str>,
changelog_title: String,
) -> Self {
ChangelogCommit {
changelog_title,
author_username,
commit,
}
Expand All @@ -117,33 +56,20 @@ impl<'a> From<&'a Footer> for ChangelogFooter<'a> {
mod test {
use anyhow::Result;
use chrono::NaiveDateTime;
use cocogitto_config::SETTINGS;
use cocogitto_oid::OidOf;
use git2::Oid;
use indoc::indoc;
use pretty_assertions::assert_eq;
use speculoos::prelude::*;

use cocogitto_commit::{Commit, CommitType, ConventionalCommit, Footer};
use cocogitto_config::SETTINGS;
use cocogitto_oid::OidOf;
use cocogitto_tag::Tag;

use crate::release::{ChangelogCommit, Release};
use crate::renderer::Renderer;
use crate::template::{
MonoRepoContext, PackageBumpContext, PackageContext, RemoteContext, Template, TemplateKind,
};
use cocogitto_commit::{Commit, CommitType, ConventionalCommit, Footer};

use cocogitto_tag::Tag;
use cocogitto_test_helpers::open_cocogitto_repo;

#[test]
fn should_get_a_release() -> anyhow::Result<()> {
let repo = open_cocogitto_repo()?;
let iter = repo.revwalk("..")?;
let release = Release::try_from(iter);
assert_that!(release)
.is_ok()
.matches(|r| !r.commits.is_empty());
Ok(())
}

#[test]
fn should_render_default_template() -> Result<()> {
Expand Down Expand Up @@ -579,6 +505,7 @@ mod test {
date,
commits: vec![
ChangelogCommit {
changelog_title: "Bug Fixes".to_string(),
author_username: Some("oknozor"),
commit: Commit {
oid: a_commit_hash.to_string(),
Expand All @@ -599,6 +526,7 @@ mod test {
},
},
ChangelogCommit {
changelog_title: "Features".to_string(),
author_username: None,
commit: Commit {
oid: a_commit_hash.to_string(),
Expand All @@ -619,6 +547,7 @@ mod test {
},
},
ChangelogCommit {
changelog_title: "Features".to_string(),
author_username: Some("oknozor"),
commit: Commit {
oid: a_commit_hash.to_string(),
Expand Down
Loading
Loading