Skip to content

Commit

Permalink
feat(changelog): display multiple release changelog on changelog range
Browse files Browse the repository at this point in the history
  • Loading branch information
oknozor committed Nov 30, 2021
1 parent ce24789 commit c6940c5
Show file tree
Hide file tree
Showing 14 changed files with 497 additions and 141 deletions.
49 changes: 48 additions & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ predicates = "1"
rand = "0.7.3"
indoc = "1.0.3"
speculoos = "0.8.0"
pretty_assertions = "1.0.0"

[features]
default = ["cli"]
Expand Down
4 changes: 2 additions & 2 deletions src/bin/cog.rs
Original file line number Diff line number Diff line change
Expand Up @@ -306,8 +306,8 @@ fn main() -> Result<()> {
let result = match at {
Some(at) => cocogitto.get_changelog_at_tag(&at, template)?,
None => {
let changelog = cocogitto.get_changelog(pattern.unwrap_or_default())?;
changelog.to_markdown(template)?
let changelog = cocogitto.get_changelog(pattern.unwrap_or_default(), true)?;
changelog.into_markdown(template)?
}
};
println!("{}", result);
Expand Down
4 changes: 2 additions & 2 deletions src/conventional/changelog/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,12 @@ const DEFAULT_FOOTER: &str =
"Changelog generated by [cocogitto](https://github.com/oknozor/cocogitto).";

impl Release<'_> {
pub fn to_markdown(&self, template: Template) -> Result<String, tera::Error> {
pub fn into_markdown(self, template: Template) -> Result<String, tera::Error> {
let renderer = Renderer::try_new(template)?;
renderer.render(self)
}

pub fn write_to_file<S: AsRef<Path>>(&self, path: S, template: Template) -> anyhow::Result<()> {
pub fn write_to_file<S: AsRef<Path>>(self, path: S, template: Template) -> anyhow::Result<()> {
let renderer = Renderer::try_new(template)?;
let changelog = renderer.render(self)?;

Expand Down
50 changes: 43 additions & 7 deletions src/conventional/changelog/release.rs
Original file line number Diff line number Diff line change
@@ -1,19 +1,54 @@
use chrono::NaiveDateTime;
use chrono::{NaiveDateTime, Utc};
use conventional_commit_parser::commit::Footer;
use serde::Serialize;

use crate::conventional::commit::Commit;
use crate::git::oid::OidOf;
use crate::git::revspec::CommitRange;
use crate::settings;
use colored::Colorize;

#[derive(Serialize)]
#[derive(Debug, Serialize)]
pub struct Release<'a> {
pub version: OidOf,
pub from: OidOf,
pub date: NaiveDateTime,
pub commits: Vec<ChangelogCommit<'a>>,
pub previous: Option<Box<Release<'a>>>,
}

impl<'a> From<CommitRange<'a>> for Release<'a> {
fn from(commit_range: CommitRange<'a>) -> Self {
let mut commits = vec![];

for commit in commit_range.commits {
// Ignore merge commits
if let Some(message) = commit.message() {
if message.starts_with("Merge") {
continue;
}
}

match Commit::from_git_commit(&commit) {
Ok(commit) => commits.push(ChangelogCommit::from(commit)),
Err(err) => {
let err = err.to_string().red();
eprintln!("{}", err);
}
};
}

Release {
version: commit_range.to,
from: commit_range.from,
date: Utc::now().naive_utc(),
commits,
previous: None,
}
}
}

#[derive(Debug)]
pub struct ChangelogCommit<'a> {
pub author_username: Option<&'a str>,
pub commit: Commit,
Expand Down Expand Up @@ -47,6 +82,7 @@ impl<'a> From<&'a Footer> for ChangelogFooter<'a> {

#[cfg(test)]
mod test {
use anyhow::Result;
use chrono::NaiveDateTime;
use conventional_commit_parser::commit::{CommitType, ConventionalCommit, Footer};
use git2::Oid;
Expand All @@ -59,7 +95,6 @@ mod test {
use crate::conventional::commit::Commit;
use crate::git::oid::OidOf;
use crate::git::tag::Tag;
use anyhow::Result;

#[test]
fn should_render_default_template() -> Result<()> {
Expand All @@ -68,7 +103,7 @@ mod test {
let renderer = Renderer::default();

// Act
let changelog = renderer.render(&release);
let changelog = renderer.render(release);

// Assert
assert_that!(changelog).is_ok().is_equal_to(
Expand Down Expand Up @@ -96,7 +131,7 @@ mod test {
})?;

// Act
let changelog = renderer.render(&release);
let changelog = renderer.render(release);

// Assert
assert_that!(changelog).is_ok().is_equal_to(
Expand Down Expand Up @@ -127,7 +162,7 @@ mod test {
})?;

// Act
let changelog = renderer.render(&release);
let changelog = renderer.render(release);

// Assert
assert_that!(changelog).is_ok().is_equal_to(
Expand All @@ -139,7 +174,7 @@ mod test {
- **(parser)** implement the changelog generator - ([17f7e23](https://github.com/oknozor/cocogitto/commit/17f7e23081db15e9318aeb37529b1d473cf41cbe)) - [@oknozor](https://github.com/oknozor)
- awesome feature - ([17f7e23](https://github.com/oknozor/cocogitto/commit/17f7e23081db15e9318aeb37529b1d473cf41cbe)) - Paul Delafosse"
}
.to_string(),
.to_string(),
);

Ok(())
Expand Down Expand Up @@ -228,6 +263,7 @@ mod test {
},
},
],
previous: None,
}
}
}
Expand Down
13 changes: 12 additions & 1 deletion src/conventional/changelog/renderer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,18 @@ impl Renderer {
Ok(Renderer { tera, template })
}

pub(crate) fn render(&self, version: &Release) -> Result<String, tera::Error> {
pub(crate) fn render(&self, version: Release) -> Result<String, tera::Error> {
let mut release = self.render_release(&version)?;
let mut version = version;
while let Some(previous) = version.previous.map(|v| *v) {
release.push_str("\n- - -\n");
release.push_str(self.render_release(&previous)?.as_str());
version = previous;
}

Ok(release)
}
fn render_release(&self, version: &Release) -> Result<String, tera::Error> {
let mut template_context = Context::from_serialize(version)?;

let context = self
Expand Down
5 changes: 2 additions & 3 deletions src/conventional/changelog/template/simple
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,15 @@
{% set to = version.id%} \
{% set from_shorthand = from.id | truncate(length=7, end="") %} \
{% set to_shorthand = to | truncate(length=7, end="") %} \
## Unreleased ({{ from_shorthand ~ ".." ~ to_shorthand }}) \
## Unreleased ({{ from_shorthand ~ ".." ~ to_shorthand }})
{% endif %} \
\
{% for type, typed_commits in commits | sort(attribute="type")| group_by(attribute="type")%} \
\
#### {{ type | upper_first }}
\
{% for scope, scoped_commits in typed_commits | group_by(attribute="scope") %} \
{% for commit in scoped_commits | sort(attribute="scope") %} \
{% if commit.author %} \
{% if commit.author %} \
{% set author = "*" ~ commit.author ~ "*" %} \
{% else %} \
{% set author = commit.signature %} \
Expand Down
10 changes: 10 additions & 0 deletions src/git/oid.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,16 @@ pub enum OidOf {
Other(Oid),
}

impl OidOf {
pub fn oid(&self) -> &Oid {
match self {
OidOf::Tag(t) => t.oid(),
OidOf::Head(o) => o,
OidOf::Other(o) => o,
}
}
}

impl Display for OidOf {
/// Print the oid according to it's type
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
Expand Down
Loading

0 comments on commit c6940c5

Please sign in to comment.