Code Monkey home page Code Monkey logo

git-changelog-lib's Introduction

Git Changelog Lib

Maven Central

This is a library that can:

  • Generate a changelog, or releasenotes, from a GIT repository.
  • Determine next version, based on format of commits since last release.

It is fully configurable with a Mustache (Handlebars) template filled with a context of placeholders and helpers.

The changelog can:

  • Be stored to file, like CHANGELOG.md. There are some templates used for testing available here.
  • Or, just rendered to a String.

It can integrate with Jira, Redmine, GitLab and/or GitHub to retrieve the title of issues.

Usage

This software can be used:

There are examples of different templates in the code that are used for testing.

Template - Simple

Here is an example template.

# Changelog

Changelog for {{ownerName}} {{repoName}}.

{{#tags}}
## {{name}}
 {{#issues}}
  {{#hasIssue}}
   {{#hasLink}}
### {{name}} [{{issue}}]({{link}}) {{title}} {{#hasIssueType}} *{{issueType}}* {{/hasIssueType}} {{#hasLabels}} {{#labels}} *{{.}}* {{/labels}} {{/hasLabels}}
   {{/hasLink}}
   {{^hasLink}}
### {{name}} {{issue}} {{title}} {{#hasIssueType}} *{{issueType}}* {{/hasIssueType}} {{#hasLabels}} {{#labels}} *{{.}}* {{/labels}} {{/hasLabels}}
   {{/hasLink}}
  {{/hasIssue}}
  {{^hasIssue}}
### {{name}}
  {{/hasIssue}}

  {{#commits}}
**{{{messageTitle}}}**

{{#messageBodyItems}}
 * {{.}}
{{/messageBodyItems}}

[{{hash}}](https://github.com/{{ownerName}}/{{repoName}}/commit/{{hash}}) {{authorName}} *{{commitTime}}*

  {{/commits}}

 {{/issues}}
{{/tags}}

Template - Conventional

If you are using conventional commits:

<type>[optional scope]: <description>

[optional body]

[optional footer(s)]

You can use built in helpers to produce a nice changelog. You can add your own helpers (using Javascript or Java) as described here.

{{#tags}}
{{#ifReleaseTag .}}
## [{{name}}](https://gitlab.com/html-validate/html-validate/compare/{{name}}) ({{tagDate .}})

  {{#ifContainsBreaking commits}}
    ### Breaking changes

    {{#commits}}
      {{#ifCommitBreaking .}}
  - {{#eachCommitScope .}} **{{.}}** {{/eachCommitScope}} {{{commitDescription .}}} ([{{hash}}](https://github.com/{{ownerName}}/{{repoName}}/commit/{{hash}}))
      {{/ifCommitBreaking}}
    {{/commits}}
  {{/ifContainsBreaking}}


  {{#ifContainsType commits type='feat'}}
    ### Features

    {{#commits}}
      {{#ifCommitType . type='feat'}}
  - {{#eachCommitScope .}} **{{.}}** {{/eachCommitScope}} {{{commitDescription .}}} ([{{hash}}](https://github.com/{{ownerName}}/{{repoName}}/commit/{{hash}}))
      {{/ifCommitType}}
    {{/commits}}
  {{/ifContainsType}}


  {{#ifContainsType commits type='fix'}}
    ### Bug Fixes

    {{#commits}}
      {{#ifCommitType . type='fix'}}
        - {{#eachCommitScope .}} **{{.}}** {{/eachCommitScope}} {{{commitDescription .}}} ([{{hash}}](https://github.com/{{ownerName}}/{{repoName}}/commit/{{hash}}))
      {{/ifCommitType}}
    {{/commits}}
  {{/ifContainsType}}

{{/ifReleaseTag}}
{{/tags}}

Partials

You can use partials in your templates.

changelog.hbs

{{#commits}}
{{> commit}}
{{/commits}}

commit.partial

## {{authorName}} - {{commitTime}}
[{{hashFull}}](https://server/{{hash}})
{{{message}}}

This is configured like:

gitChangelogApi
  .withTemplateBaseDir("...")
  .withTemplateSuffix(".partial"); //Optional, defaults to ".partial"

Helpers

Some helpers are implemented in this library. And users can also add more helpers as described in Handlebars.

ifReleaseTag <Tag>

Conditional, renders a block if given Tag matches release-tag.

{{#tags}}
 {{#ifReleaseTag .}}
  "{{.}}" is a release tag
 {{/ifReleaseTag}}
{{/tags}}

tagDate <Tag>

Renders date of Tag on format YYYY-MM-DD.

{{#tags}}
 {{tagDate .}}
{{/tags}}

ifContainsIssueType <List<Issue>>

Conditional, renders a block if given List<Issue> contains given type.

{{#ifContainsIssueType issues type="Bug"}}
  issues contains bugs
{{/ifContainsIssueType}}

ifContainsIssueTypeOtherThan <List<Issue>>

Conditional, renders a block if given List<Issue> contains issues that don't match the given type.

{{#ifContainsIssueTypeOtherThan issues type="fix"}}
  commits contains other types than fix
{{/ifContainsIssueTypeOtherThan}}

ifContainsIssueLabel <List<Issue>> label="<value>"

Conditional, renders a block if given List<Issue> contains given label.

{{#ifContainsIssueLabel issues label='enhancement'}}
  content here
{{/ifContainsIssueLabel}}

ifContainsIssueLabelOtherThan <List<Issue>>

Conditional, renders a block if given List<Issue> contains labels that don't match the given label.

{{#ifContainsIssueLabelOtherThan issues label='enhancement'}}
  content here
{{/ifContainsIssueLabel}}

ifIssueLabel <label> label="<value>"

Conditional, renders a block if given label matches the given value.

{{#ifIssueLabel . label='enhancement'}}
  Found a enhancement
{{/ifIssueLabel}}

ifContainsType <List<Commit>>

Conditional, renders a block if given List<Commits> contains given type.

{{#ifContainsType commits type="fix"}}
  commits contains fixes
{{/ifContainsType}}

ifContainsTypeOtherThan <List<Commit>>

Conditional, renders a block if given List<Commits> contains commits that don't match the given type.

{{#ifContainsTypeOtherThan commits type="fix"}}
  commits contains other types than fix
{{/ifContainsTypeOtherThan}}

ifContainsBreaking <List<Commit>>

Conditional, renders a block if given List<Commits> contains breaking changes.

{{#ifContainsBreaking commits}}
  commits contains fixes
{{/ifContainsBreaking}}

commitDate <Commit>

Renders date of Commit on format YYYY-MM-DD.

{{#commits}}
 {{commitDate .}}
{{/commits}}

commitDescription <Commit>

Renders description of Commit.

{{#commits}}
 {{commitDescription .}}
{{/commits}}

revertedCommit <Commit>

Renders reverted commit refered to by Commit.

{{#commits}}
 {{revertedCommit .}}
{{/commits}}

ifIssueType <Issue> type="<type>"

Conditional, renders a block if given Issue is of type.

{{#issues}}
 {{#ifIssueType . type="fix"}} is type fix {{/ifIssueType}}
{{/issues}}

ifIssueTypeOtherThan <Issue> type="<type>"

Conditional, renders a block if given Issue is of type.

{{#issues}}
 {{#ifIssueTypeOtherThan . type="fix"}} is not type fix {{/ifIssueTypeOtherThan}}
{{/issues}}

ifCommitType <Commit> type="<type>"

Conditional, renders a block if given Commit is of type.

{{#commits}}
 {{#ifCommitType . type="fix"}} is type fix {{/ifCommitType}}
{{/commits}}

ifCommitTypeOtherThan <Commit> type="<type>"

Conditional, renders a block if given Commit is of type.

{{#commits}}
 {{#ifCommitTypeOtherThan . type="fix"}} is not type fix {{/ifCommitTypeOtherThan}}
{{/commits}}

ifCommitBreaking <Commit>

Conditional, renders a block if given Commit is breaking.

{{#commits}}
 {{#ifCommitBreaking .}} is breaking {{/ifCommitBreaking}}
{{/commits}}

ifCommitScope <Commit> scope="utils"

Conditional, renders a block if given Commit has scope.

{{#commits}}
 {{#ifCommitScope . scope="utils"}} is scope utils {{/ifCommitScope}}
{{/commits}}

ifCommitHasFooters <Commit>

Conditional, renders a block if given Commit has footers.

{{#commits}}
 {{#ifCommitHasFooters .}} has footers {{/ifCommitHasFooters}}
{{/commits}}

ifCommitHasParagraphs <Commit>

Conditional, renders a block if given Commit has paragraphs.

{{#commits}}
 {{#ifCommitHasParagraphs .}} has paragraphs {{/ifCommitHasParagraphs}}
{{/commits}}

eachCommitScope <Commit>

Renders block for each scope in Commit.

{{#commits}}
 {{#eachCommitScope .}}
  scope: {{.}}
 {{/eachCommitScope}}
{{/commits}}

eachCommitRefs <Commit>

Renders block for each refs in Commit.

{{#commits}}
 {{#eachCommitRefs .}}
  references issue: {{.}}
 {{/eachCommitRefs}}
{{/commits}}

eachCommitFixes <Commit>

Renders block for each fixes in Commit.

{{#commits}}
 {{#eachCommitFixes .}}
  fixes issue: {{.}}
 {{/eachCommitFixes}}
{{/commits}}

eachCommitParagraph <Commit>

Renders block for each paragraph in Commit.

{{#commits}}
 {{#eachCommitParagraph .}}
  {{.}}
 {{/eachCommitParagraph}}
{{/commits}}

eachCommitFooter <Commit>

Renders block for each footer in Commit.

{{#commits}}
 {{#eachCommitFooter .}}
  {{token}}
 {{/eachCommitFooter}}
{{/commits}}

Optional tokenMatching regex parameter filters footer tokens.

ifFooterHasValue <Footer>

Conditional, renders a block if given Footer has value.

{{#commits}}
 {{#eachCommitFooter .}}
   {{#ifFooterHasValue .}}
    {{{value}}}
   {{/ifFooterHasValue}}
 {{/eachCommitFooter}}
{{/commits}}

ifEquals <a> <b>

Conditional, renders a block if a equals b.

{{#tags}}
 {{name}} Unreleased ? {{#ifEquals name "Unreleased"}} ja {{else}} nej {{/ifEquals}}
{{/tags}}

ifMatches <a> <b>

Conditional, renders a block if a matches regexp b.

{{#eachCommitFixes .}}
 {{#ifMatches . "^[A-Z]+-[0-9]+"}}
  fixes : "{{subString . 0 3}}" and number {{subString . 4}}
 {{/ifMatches}}
{{/eachCommitFixes}}

subString <a> <b> <c>

Works just like Java substring.

{{#eachCommitFixes .}}
 {{#ifMatches . "^[A-Z]+-[0-9]+"}}
  fixes : "{{subString . 0 3}}" and number {{subString . 4}}
 {{/ifMatches}}
{{/eachCommitFixes}}

Context

The template is supplied with this context of prepopulated mustache/handlebars variables:

Click here to show context

(ownerName, repoName, urlParts - derived from the clone URL, git remote origin MUST BE SET)
- ownerName (for this repo it would be "tomasbjerre")
- repoName (for this repo it would be "git-changelog-lib")
- urlParts (for this repo it would be [git-changelog-lib, tomasbjerre, [email protected]])
* commits
 - authorName
 - authorEmailAddress
 - commitTime
 - hash
 - hashFull
 - merge (True if this is a merge-commit)
 - message (The full message)
 - messageTitle (Only the first line of the message)
 - messageBody (Everything, except the title)
 * messageBodyItems (List of strings, the lines after the title)
* tags
 - name
 - annotation
 - tagTime
 - hasTagTime
 * commits
  - authorName
  - authorEmailAddress
  - commitTime
  - hash
  - hashFull
  - merge (True if this is a merge-commit)
  - message (The full message)
  - messageTitle (Only the first line of the message)
  - messageBody (Everything, except the title)
  * messageBodyItems (List of strings, the lines after the title)
 * authors
  - authorName
  - authorEmail
  * commits
   - authorName
   - authorEmailAddress
   - commitTime
   - hash
   - hashFull
   - merge (True if this is a merge-commit)
   - message (The full message)
   - messageTitle (Only the first line of the message)
   - messageBody (Everything, except the title)
   * messageBodyItems (List of strings, the lines after the title)
 * issueTypes
  - name (Like GitHub, GitLab, Jira, ...)
  * issues
   - name
   - hasIssue
   - issue
   - hasLink
   - link
   - hasTitle
   - title
   - hasDescription
   - description
   - hasType
   - type
   - isJira
   - isGitHub
   - isGitLab
   - isCustom
   - isNoIssue
   - hasLabels
   - labels
   - hasLinkedIssues
   - linkedIssues
   - hasAdditionalFields
   - additionalFields
   * commits
    - authorName
    - authorEmailAddress
    - commitTime
    - hash
    - hashFull
    - merge (True if this is a merge-commit)
    - message (The full message)
    - messageTitle (Only the first line of the message)
    - messageBody (Everything, except the title)
    * messageBodyItems (List of strings, the lines after the title)
   * authors
    - authorName
    - authorEmail
    * commits
     - authorName
     - authorEmailAddress
     - commitTime
     - hash
     - hashFull
     - merge (True if this is a merge-commit)
     - message (The full message)
     - messageTitle (Only the first line of the message)
     - messageBody (Everything, except the title)
     * messageBodyItems (List of strings, the lines after the title)
 * issues
  - name
  - hasIssue
  - issue
  - hasLink
  - link
  - hasTitle
  - title
  - hasDescription
  - description
  - hasType
  - type
  - isJira
  - isGitHub
  - isGitLab
  - isCustom
  - isNoIssue
  - hasLabels
  - labels
  - hasLinkedIssues
  - linkedIssues
  - hasAdditionalFields
  - additionalFields
  * commits
   - authorName
   - authorEmailAddress
   - commitTime
   - hash
   - hashFull
   - merge (True if this is a merge-commit)
   - message (The full message)
   - messageTitle (Only the first line of the message)
   - messageBody (Everything, except the title)
   * messageBodyItems (List of strings, the lines after the title)
  * authors
   - authorName
   - authorEmail
   * commits
    - authorName
    - authorEmailAddress
    - commitTime
    - hash
    - hashFull
    - merge (True if this is a merge-commit)
    - message (The full message)
    - messageTitle (Only the first line of the message)
    - messageBody (Everything, except the title)
    * messageBodyItems (List of strings, the lines after the title)
* authors
 - authorName
 - authorEmail
 * commits
  - authorName
  - authorEmailAddress
  - commitTime
  - hash
  - hashFull
  - merge (True if this is a merge-commit)
  - message (The full message)
  - messageTitle (Only the first line of the message)
  - messageBody (Everything, except the title)
  * messageBodyItems (List of strings, the lines after the title)
* issues
 - name
 - hasIssue
 - issue
 - hasLink
 - link
 - hasTitle
 - title
 - hasDescription
 - description
 - hasType
 - type
 - isJira
 - isGitHub
 - isGitLab
 - isCustom
 - isNoIssue
 - hasLabels
 - labels
 - hasLinkedIssues
 - linkedIssues
 - hasAdditionalFields
 - additionalFields
 * commits
  - authorName
  - authorEmailAddress
  - commitTime
  - hash
  - hashFull
  - merge (True if this is a merge-commit)
  - message (The full message)
  - messageTitle (Only the first line of the message)
  - messageBody (Everything, except the title)
  * messageBodyItems (List of strings, the lines after the title)
 * authors
  - authorName
  - authorEmail
  * commits
   - authorName
   - authorEmailAddress
   - commitTime
   - hash
   - hashFull
   - merge (True if this is a merge-commit)
   - message (The full message)
   - messageTitle (Only the first line of the message)
   - messageBody (Everything, except the title)
   * messageBodyItems (List of strings, the lines after the title)

Library

It has a builder for creating the changelog.

  gitChangelogApiBuilder()
   .withFromCommit(ZERO_COMMIT)
   .withToRef("refs/heads/master")
   .withTemplatePath("changelog.mustache")
   .render();

It can be used to calculate next version number, based on commits:

def nextVersion = gitChangelogApiBuilder()
  .withSemanticMajorVersionPattern("^[Bb]reaking")
  .withSemanticMinorVersionPattern("[Ff]eature")
  .getNextSemanticVersion();

println "Next version:" + nextVersion.toString();
println " Major:" + nextVersion.getMajor();
println " Minor:" + nextVersion.getMinor();
println " Patch:" + nextVersion.getPatch();

Settings can be supplied with the build or from a JSON config (documented here).

git-changelog-lib's People

Contributors

adechoudens avatar chme avatar clockworkorange avatar dmitrymamchur avatar drhip avatar edeso avatar gab1one avatar gillyobeast avatar grandchild avatar jagedn avatar jcustenborder avatar maartendcrius avatar mattdibi avatar mslipets avatar nurgling avatar polter05 avatar reda-alaoui avatar spacecowboy avatar tomasbjerre avatar tthornton3-chwy avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.