Examples¶
Using the cmdline¶
Print to screen¶
The default template is author_by_change_type which prints out a list of files commited grouped by auth and change type
Command¶
$ sgc print --start-ref HEAD~3 --end-ref HEAD --var header_text 0.0.1
Outputs¶
# 0.0.1
## Sam Martin's Files
### Added
- tests/fixtures/custom_template.j2 - 2020-09-02 11:26:13
- tests/test_cmdline_arguments.py - 2020-09-02 11:26:13
### Modified
- samsgeneratechangelog/__init__.py - 2020-09-02 11:26:13
- samsgeneratechangelog/__main__.py - 2020-09-02 11:26:13
- samsgeneratechangelog/config.py - 2020-09-02 11:26:13
- samsgeneratechangelog/generatechangelog.py - 2020-09-02 11:26:13
- tests/test_default_templates.py - 2020-09-02 11:26:13
You can see that the file tests/test_default_templates.py
appears twice, once per commit.
Save to file¶
By adding --output-file
and --entry-id
we can write the output to a markdown file.
Command¶
$ sgc save --start-ref HEAD~3 --end-ref HEAD --var header_text 0.0.1 --output-file CHANGELOG.md --entry-id 0.0.1
Outputs to CHANGELOG.md¶
[//]: # (SamsGenerateChangelog-0.0.1)
# 0.0.1
## Sam Martin's Files
### Added
- tests/fixtures/custom_template.j2 - 2020-09-02 11:26:13
- tests/test_cmdline_arguments.py - 2020-09-02 11:26:13
### Modified
- samsgeneratechangelog/__init__.py - 2020-09-02 11:26:13
- samsgeneratechangelog/__main__.py - 2020-09-02 11:26:13
- samsgeneratechangelog/config.py - 2020-09-02 11:26:13
- samsgeneratechangelog/generatechangelog.py - 2020-09-02 11:26:13
- tests/test_default_templates.py - 2020-09-02 11:26:13
[//]: # (SamsGenerateChangelog-0.0.1)
You can see that this adds the Markdown comment syntax with a delimiter at the beginning and end of the changelog entry. This is invisible once rendered and ensures that running the same command repeatedly will replace the changelog entry rather than keep prepending it repeatedly.
Note
Note the repetition of 0.0.1 as the --var header_text
and the --entry-id
.
The entry ID is used as a delimiter to uniquely identify an entry in the file.
Included templates¶
You can specify an alternative template (you can see a full list of templates in the
samsgeneratechangelog/templates/
folder in the GitHub repo).
Command¶
sgc print --start-ref HEAD~3 --end-ref HEAD --var header_text 0.0.1 --template-name author_by_change_type
Outputs¶
# 0.0.1
## Sam Martin's Files
### Added
- tests/fixtures/custom_template.j2 - 2020-09-02 11:26:13
- tests/test_cmdline_arguments.py - 2020-09-02 11:26:13
### Modified
- docs/Makefile - 2020-09-02 10:00:21
- docs/source/class-reference.rst - 2020-09-02 10:00:21
- samsgeneratechangelog/__init__.py - 2020-09-02 11:26:13
- samsgeneratechangelog/__main__.py - 2020-09-02 11:26:13
- samsgeneratechangelog/config.py - 2020-09-02 11:26:13
- samsgeneratechangelog/generatechangelog.py - 2020-09-02 11:26:13
- samsgeneratechangelog/githelper.py - 2020-09-02 10:00:21
- tests/test_default_templates.py - 2020-09-02 11:26:13
By passing the template name author_by_change_type
we can see tests/test_default_templates.py
only appears once per change type,
showing the commit time of the latest commit for that change type.
Custom templates & attributes¶
Using Jinja2 you can create your own custom templates and (optionally) use your own custom attributes.
Custom attributes are values returned from a regex matching group applied to a commit parameter.
In this example we’re going to match a Jira ID at the beginning of the commit message using the following JSON:
{
"jira_id": {
"derived_from": "message",
"pattern": "^\\w+-\\d+"
}
}
This will provide us a custom attribute jira_id
pulled from the commit message using the ^\\w+-\\d+
pattern which will be accessible on each file_commit
object inside
the Jinja2 template.
We will group our commits by that custom attribute, then subgroup them by change type. Finally we will identify the last_commit for each file in that change type and print the author and commit date for it.
Note
Note how we escaped the regex character classes in the pattern JSON with an
extra slash so ^\w+-\d+
became ^\\w+-\\d+
. Without this we will get a JSON parsing error.
Commits for HEAD~9 to HEAD~8¶
ac77514 JIRA-1234 - Cleaned up unused methods
2f4dbc5 JIRA-1234 - Added additional templates
Contents of jira_id_by_change_type.j2¶
# {{header_text}}
{%- for jira_id, jira_id_files in file_commits | groupby('jira_id') | sort(attribute='grouper') %}
## {{jira_id | default('No Jira ID in commit', true)}}
{%- for change_type, change_type_files in jira_id_files | groupby('friendly_change_type') | sort(attribute='grouper') %}
### {{change_type}}
{% for file_path, file_path_files in change_type_files | groupby('file_path') | sort(attribute='grouper') %}
{%- with %}
{%- set last_commit = file_path_files | sort(attribute='committed_date') | last %}
- {{file_path}} - {{last_commit.author.name}} - {{last_commit.committed_date}}
{%- endwith %}
{%- endfor %}
{%- endfor %}
{%- endfor %}
Command¶
sgc print --start-ref HEAD~9 --end-ref HEAD~8 --var header_text 0.0.1 --custom-attribute '{"jira_id": {"derived_from": "message", "pattern": "^\\w+-\\d+"}}' --template-file jira_id_by_change_type.j2
Outputs¶
# 0.0.1
## JIRA-1234
### Added
- samsgeneratechangelog/templates/author.j2 - Sam Martin - 2020-09-01 17:08:02
- samsgeneratechangelog/templates/author_single_file_entry.j2 - Sam Martin - 2020-09-01 17:08:02
- samsgeneratechangelog/templates/change_type.j2 - Sam Martin - 2020-09-01 17:08:02
- tests/fixtures/author_single_file_entry_template.md - Sam Martin - 2020-09-01 17:08:02
- tests/fixtures/author_template.md - Sam Martin - 2020-09-01 17:08:02
- tests/fixtures/change_type_template.md - Sam Martin - 2020-09-01 17:08:02
### Deleted
- samsgeneratechangelog/templates/default.j2 - Sam Martin - 2020-09-01 17:08:02
- tests/fixtures/basic_result.md - Sam Martin - 2020-09-01 17:08:02
### Modified
- samsgeneratechangelog/config.py - Sam Martin - 2020-09-01 17:08:02
- samsgeneratechangelog/generatechangelog.py - Sam Martin - 2020-09-01 17:08:02
- samsgeneratechangelog/githelper.py - Sam Martin - 2020-09-01 17:08:02
- tests/test_generatechangelog.py - Sam Martin - 2020-09-01 17:08:02
Custom template variables¶
All the templates bundled with Sam’s Generate Changelog allow header text to be specified using
--var header_text <value>
. But what if you want to add, say, a CR number to that?
Command¶
$ sgc print --start-ref 0.0.4 --end-ref 1.0.0 --var header_text 0.0.1 --var change_number CR-1234 --template-file test.j2
Contents of template_variables_example.j2¶
This template will output a list of commits, with our header_text followed by our change_number in the H1.
# {{header_text}} - {{change_number}}
{%for sha, file_commit in file_commits | groupby('hexsha') | sort(attribute='list.0.committed_date') | reverse -%}
- {{file_commit[0].hexsha_short}} - {{file_commit[0].committed_date}} - {{file_commit[0].message.split('\n')[0]}}
{%endfor%}
Outputs¶
# 0.0.1 - CR-1234
- 9ec90ba - 2020-09-04 11:14:05 - Fix yaml
- e3734ed - 2020-09-04 11:01:11 - Standardised docstrings with pydocstyle
- fb785a1 - 2020-09-03 15:46:59 - Merge pull request #9 from Sam-Martin/bugfix/typo{%endfor%}
Template Examples¶
Sam’s Generate Changelog uses Jinja2 templates to create the changelog.
The following variables are passed into the Template()
.
start_ref
end_ref
file_commits
any variables passed in to
GenerateChangelog
viatemplate_variables
or the cmdline via--var
The first two are mandatory arguments when running sgc from the cmdline or instantiating GenerateChangelog from within a Python script.
The third one file_commits
however is where the power of SamsGenerateChangelog resides.
The file_commits
template variable¶
The file_commits
variable in each template contains a list of FileCommit
objects.
This object makes it easy for you to group your changes by
author_date
,
author
,
file_path
,
friendly_change_type
,
and more importantly, custom attributes.
At its most simple, you can loop over all file commits and just print out the detail about it.
{%- for file_commit in file_commits %}
- {{file_commit.file_path}} - {{file_commit.hexsha_short}} - {{file_commit.author.name}} {{file_commit.author.email}} - {{file_commit.committed_date}} - {{file_commit.friendly_change_type}}
{%- endfor %}
This will output something like the following:
- samsgeneratechangelog/templates/author.j2 - 2f4dbc5 - Sam Martin here@there.com - 2020-09-01 17:08:02 - Added
- samsgeneratechangelog/templates/author_single_file_entry.j2 - 2f4dbc5 - Sam Martin here@there.com - 2020-09-01 17:08:02 - Added
- samsgeneratechangelog/templates/change_type.j2 - 2f4dbc5 - Sam Martin here@there.com - 2020-09-01 17:08:02 - Added
This shows some of the attributes that are available on the file_commits
objects, but the real power of this objects
comes from how easy it is to group!
Grouping file_commits¶
With Jinja2’s groupby
functionality we can group these file commits any way we like.
{%- for author_name, author_file_commits in file_commits | groupby('author.name') | sort(attribute='grouper') %}
## {{author_name}}
{%- for file_commit in author_file_commits | sort(attribute='file_path') %}
- {{file_commit.file_path}} - {{file_commit.hexsha_short}} - {{file_commit.author.name}} {{file_commit.author.email}} - {{file_commit.committed_date}} - {{file_commit.friendly_change_type}}
{%- endfor %}
{%- endfor %}
Two important things to note:
We’re grouping by
author.name
indicating the attributeauthor
in theFileCommit
has its own attributename
We’re sorting by
attribute='grouper'
. The grouper attribute is the same asauthor_name
at the beginning the for loop
This will output something like:
## Sam Martin
- samsgeneratechangelog/config.py - 2f4dbc5 - Sam Martin here@there.com - 2020-09-01 17:08:02 - Modified
- samsgeneratechangelog/generatechangelog.py - 2f4dbc5 - Sam Martin here@there.com - 2020-09-01 17:08:02 - Modified
- samsgeneratechangelog/githelper.py - 2f4dbc5 - Sam Martin here@there.com - 2020-09-01 17:08:02 - Modified
Custom Attributes Examples¶
With custom attributes you can for example group together:
Commits by Jira ID in the message
All Terraform files
All files by root folder
Argument structure¶
Whether supplying your custom attributes via the cmdline arguments or when
instantiating GenerateChangelog
you need to supply a structure as follows:
{
"attribute_name": {
"derived_from": "commit_attribute",
"pattern": "regex pattern"
}
}
e.g.
{
"jira_id": {
"derived_from": "message",
"pattern": "^\w+-\d+"
}
}
Usage¶
In the example above, the FileCommit
objects (accessible
in the template via the file_commits
variable) will be given a new attribute called jira_id
.
This attribute will be produced by applying the pattern ^\\w+-\\d+
against the
commit
object’s message
attribute.
The pattern ^\\w+-\\d+
will take a commit message like:
JIRA-1234 - Added additional templates
and return
JIRA-1234
Meaning that in your template you can do something like:
{%- for file_commit in file_commits %}
- {{file_commit.jira_id}} - {{file_commit.file_path}} - {{file_commit.hexsha_short}}
{%- endfor %}
and it will render as
- JIRA-1234 - samsgeneratechangelog/templates/change_type.j2 - 2f4dbc5