# JMESLog - Changelog Management
[![PyPI](https://img.shields.io/pypi/v/jmeslog?style=flat-square)](https://pypi.python.org/pypi/jmeslog/)
[![PyPI - Python Version](https://img.shields.io/pypi/pyversions/jmeslog?style=flat-square)](https://pypi.python.org/pypi/jmeslog/)
[![PyPI - License](https://img.shields.io/pypi/l/jmeslog?style=flat-square)](https://pypi.python.org/pypi/jmeslog/)
---
**Source Code**: [https://github.com/jamesls/jmeslog](https://github.com/jamesls/jmeslog)
**PyPI**: [https://pypi.org/project/jmeslog/](https://pypi.org/project/jmeslog/)
---
JMESLog is a script for managing changelogs. It helps you associate
changelog entries for new features and bug fixes and also helps you
generate a CHANGELOG file or any other type of release notes page. It
enforces semver by automatically determining the next version number
based on the pending changes for your next release.
# Installation
```sh
pip install jmeslog
```
# Quickstart
Initialize a repo to use JMESLog:
```
$ jmeslog init
```
Before you send a PR, create a changelog entry for your change:
```
$ jmeslog new-change
A change file was created at .changes/next-release/foo-bar.json
```
Commit that file:
```
$ git add .changes/next-release/foo-bar.json
$ git commit -m "Add changelog entry"
```
That\'s it. When it comes time to release, you run these commands:
```
$ jmeslog new-release
$ jmeslog render > CHANGELOG.rst
```
The `new-release` command consolidates all the files in
`.changes/next-release` into a single JSON file representing the new
release. The `render` command regenerates your CHANGELOG file.
The rest of this doc explains this workflow in more detail.
# Concepts
All changes for a repo are stored as structured data in a `.changes/`
directory.
The changes for the next release are stored in `.changes/next-release/`.
All of the changes from previous releases are stored in
`.changes/X.Y.Z.json` where `X.Y.Z` represent the version associated a
given release. These files are generated by running the
`jmeslog new-change` command.
When you're ready to release a new version, all of the change files
from `.changes/next-release/` are gathered and a new
`.changes/X.Y.Z.json` file is created that contain those changes. The
content from `.changes/next-release/` is then removed. This is done with
the `jmeslog new-release` command.
You can then generate a CHANGELOG (or any other file) using the data
from `.changes/`. To do this you run the `jmeslog generate` command.
# Usage
The typical workflow when using `jmeslog`:
- Use the `jmeslog new-change` command to generate a new changelog
file when you\'re working on a new feature. This file is included as
part of the PR you send.
- When you\'re ready to release, you can run the `jmespath generate`
command to generate the CHANGELOG file based on all your change
files. You also run the `jmeslog new-release` command to consolidate
files from the next `.changes/next-release/` directory into a new
single `.changes/X.Y.Z.json` file.
# Rendering Changelogs
By default, the `jmeslog render` command renders a CHANGELOG file in RST
format with this structure:
```
=========
CHANGELOG
=========
X.Y.Z
=====
* type:category:description
```
You can control how your changes are rendered by specifying your own
template. To specify your own templates, first create a
`.changes/templates` directory:
```
mkdir .changes/templates
```
Next create any number of templates you want. For example:
```
touch .changes/templates/MYTEMPLATE
```
This name can be anything you want. Next, you write your template.
Templates are written using
[jinja2](https://jinja.palletsprojects.com/).
The template is provided the following context dictionary when rendering
the changelog:
```
{
"changes": [
("x.y.z": [{"type": "", "category": "", "description": ""}, ...]),
("x.y.z - 1": [{"type": "", "category": "", "description": ""}, ...]),
("x.y.z - 2": [{"type": "", "category": "", "description": ""}, ...]),
]
}
```
The `changes` list is in descender order with the most recent release
being first, and the oldest release being the last item in the `changes`
list.
To use this template, specify the filename (the basename, not the entire
filename) as the `--template` parameter. For example, if your template
file is `.changes/templates/MYTEMPLATE`, you'd specify
`jmeslog render --template MYTEMPLATE`.
Here's the default template that\'s used if no `--template` parameter
is provided:
```
=========
CHANGELOG
=========
{% for release, changes in releases %}
{{ release }}
{{ '=' * release|length }}
{% if changes.summary %}
{{ changes.summary -}}
{% endif %}
{% for change in changes.changes %}
* {{ change.type }}:{{ change.category }}:{{ change.description }}
{% endfor %}
{% endfor %}
```
# Backwards Compatibility
The following things may change in a backwards incompatible manner until
the 1.0.0 GA release:
- The CLI commands and parameters
- The files generates under `.changes/`
- The functionality provided by JMESLog
- The context dictionary provided to custom templates
# FAQ
**What problem is this trying to solve?**
JMESLog helps you automate releases. It\'s the result of iterating on an
automated release process that started from a completely manual process
to eventually releasing every single day. When you think about what\'s
involved in releasing a new version of your library/tool, you have to:
- Figure out the next version number you want for your release. If
you\'re following semver, this will depend on what types of changes
will be in the next release. New features should require a minor
version bump, and bug fixes should result in a new patch version.
- Update your CHANGELOG with all the new changes that will be part of
this next release under a new section corresponding to the next
version number.
This tool helps with manage both of these problems so you can completely
automate your release process. It also solves several other problems
that come up:
- You can have changelog entries tracked with each pull request, and
you don\'t have to worry about merge conflicts to your CHANGELOG
file.
- You can generate more than just a CHANGELOG file if needed. For
example, you can create a \"History\" page in your docs that\'s
rendered differently than your CHANGELOG.
- You can programatically query for a projects changes.
# Development
This project requires at Python 3.9+ and uses
[Poetry](https://python-poetry.org/) to manage dependencies.
Once you've created and activated your virtual environment, run:
```sh
poetry install
```
This will install all necessary dependencies and install this project
in editable mode.
## Testing
[Poe the Poet](https://github.com/nat-n/poethepoet) is the task runner
used for this project, it's automatically installed as part of the
`poetry install` step. To see a list of available tasks, run the
`poe` command with no args.
To run the tests for this project run:
```sh
poe test
```
## Pre-commit
[Pre-commit](https://pre-commit.com/) hooks runs misc. auto-formatters and
quality checks to ensure all changes look good before committing. The same
changes are also run on Pull Requests so this helps provides a quicker feedback
loop before submitting a PR.
You can install the hooks with (runs for each commit):
```sh
pre-commit install
```
Or if you want e.g. want to run all checks manually for all files:
```
poe pre-commit
```
Or if you run to the `pre-commit` executable directly:
```sh
pre-commit run --all-files
```
Raw data
{
"_id": null,
"home_page": "https://jamesls.github.io/jmeslog",
"name": "jmeslog",
"maintainer": null,
"docs_url": null,
"requires_python": "<4.0,>=3.9.0",
"maintainer_email": null,
"keywords": null,
"author": "James Saryerwinnie",
"author_email": "js@jamesls.com",
"download_url": "https://files.pythonhosted.org/packages/27/2b/38adf3f4a2193ba38d02d25e42fddfc70864203c9ca047eddd03d61120e0/jmeslog-0.2.0.tar.gz",
"platform": null,
"description": "# JMESLog - Changelog Management\n\n[![PyPI](https://img.shields.io/pypi/v/jmeslog?style=flat-square)](https://pypi.python.org/pypi/jmeslog/)\n[![PyPI - Python Version](https://img.shields.io/pypi/pyversions/jmeslog?style=flat-square)](https://pypi.python.org/pypi/jmeslog/)\n[![PyPI - License](https://img.shields.io/pypi/l/jmeslog?style=flat-square)](https://pypi.python.org/pypi/jmeslog/)\n\n\n---\n\n**Source Code**: [https://github.com/jamesls/jmeslog](https://github.com/jamesls/jmeslog)\n**PyPI**: [https://pypi.org/project/jmeslog/](https://pypi.org/project/jmeslog/)\n\n---\n\nJMESLog is a script for managing changelogs. It helps you associate\nchangelog entries for new features and bug fixes and also helps you\ngenerate a CHANGELOG file or any other type of release notes page. It\nenforces semver by automatically determining the next version number\nbased on the pending changes for your next release.\n\n# Installation\n\n```sh\npip install jmeslog\n```\n\n# Quickstart\n\nInitialize a repo to use JMESLog:\n\n```\n$ jmeslog init\n```\n\nBefore you send a PR, create a changelog entry for your change:\n\n```\n$ jmeslog new-change\n\nA change file was created at .changes/next-release/foo-bar.json\n```\n\n\nCommit that file:\n\n```\n$ git add .changes/next-release/foo-bar.json\n$ git commit -m \"Add changelog entry\"\n```\n\nThat\\'s it. When it comes time to release, you run these commands:\n\n```\n$ jmeslog new-release\n$ jmeslog render > CHANGELOG.rst\n```\n\nThe `new-release` command consolidates all the files in\n`.changes/next-release` into a single JSON file representing the new\nrelease. The `render` command regenerates your CHANGELOG file.\n\nThe rest of this doc explains this workflow in more detail.\n\n# Concepts\n\nAll changes for a repo are stored as structured data in a `.changes/`\ndirectory.\n\nThe changes for the next release are stored in `.changes/next-release/`.\nAll of the changes from previous releases are stored in\n`.changes/X.Y.Z.json` where `X.Y.Z` represent the version associated a\ngiven release. These files are generated by running the\n`jmeslog new-change` command.\n\nWhen you're ready to release a new version, all of the change files\nfrom `.changes/next-release/` are gathered and a new\n`.changes/X.Y.Z.json` file is created that contain those changes. The\ncontent from `.changes/next-release/` is then removed. This is done with\nthe `jmeslog new-release` command.\n\nYou can then generate a CHANGELOG (or any other file) using the data\nfrom `.changes/`. To do this you run the `jmeslog generate` command.\n\n# Usage\n\nThe typical workflow when using `jmeslog`:\n\n- Use the `jmeslog new-change` command to generate a new changelog\n file when you\\'re working on a new feature. This file is included as\n part of the PR you send.\n- When you\\'re ready to release, you can run the `jmespath generate`\n command to generate the CHANGELOG file based on all your change\n files. You also run the `jmeslog new-release` command to consolidate\n files from the next `.changes/next-release/` directory into a new\n single `.changes/X.Y.Z.json` file.\n\n# Rendering Changelogs\n\nBy default, the `jmeslog render` command renders a CHANGELOG file in RST\nformat with this structure:\n\n```\n=========\nCHANGELOG\n=========\n\nX.Y.Z\n=====\n\n* type:category:description\n```\n\nYou can control how your changes are rendered by specifying your own\ntemplate. To specify your own templates, first create a\n`.changes/templates` directory:\n\n```\nmkdir .changes/templates\n```\n\nNext create any number of templates you want. For example:\n\n```\ntouch .changes/templates/MYTEMPLATE\n```\n\nThis name can be anything you want. Next, you write your template.\nTemplates are written using\n[jinja2](https://jinja.palletsprojects.com/).\n\nThe template is provided the following context dictionary when rendering\nthe changelog:\n\n```\n{\n \"changes\": [\n (\"x.y.z\": [{\"type\": \"\", \"category\": \"\", \"description\": \"\"}, ...]),\n (\"x.y.z - 1\": [{\"type\": \"\", \"category\": \"\", \"description\": \"\"}, ...]),\n (\"x.y.z - 2\": [{\"type\": \"\", \"category\": \"\", \"description\": \"\"}, ...]),\n ]\n}\n```\n\nThe `changes` list is in descender order with the most recent release\nbeing first, and the oldest release being the last item in the `changes`\nlist.\n\nTo use this template, specify the filename (the basename, not the entire\nfilename) as the `--template` parameter. For example, if your template\nfile is `.changes/templates/MYTEMPLATE`, you'd specify\n`jmeslog render --template MYTEMPLATE`.\n\nHere's the default template that\\'s used if no `--template` parameter\nis provided:\n\n```\n=========\nCHANGELOG\n=========\n\n{% for release, changes in releases %}\n{{ release }}\n{{ '=' * release|length }}\n{% if changes.summary %}\n{{ changes.summary -}}\n{% endif %}\n{% for change in changes.changes %}\n* {{ change.type }}:{{ change.category }}:{{ change.description }}\n{% endfor %}\n{% endfor %}\n```\n\n# Backwards Compatibility\n\nThe following things may change in a backwards incompatible manner until\nthe 1.0.0 GA release:\n\n- The CLI commands and parameters\n- The files generates under `.changes/`\n- The functionality provided by JMESLog\n- The context dictionary provided to custom templates\n\n# FAQ\n\n**What problem is this trying to solve?**\n\nJMESLog helps you automate releases. It\\'s the result of iterating on an\nautomated release process that started from a completely manual process\nto eventually releasing every single day. When you think about what\\'s\ninvolved in releasing a new version of your library/tool, you have to:\n\n- Figure out the next version number you want for your release. If\n you\\'re following semver, this will depend on what types of changes\n will be in the next release. New features should require a minor\n version bump, and bug fixes should result in a new patch version.\n- Update your CHANGELOG with all the new changes that will be part of\n this next release under a new section corresponding to the next\n version number.\n\nThis tool helps with manage both of these problems so you can completely\nautomate your release process. It also solves several other problems\nthat come up:\n\n- You can have changelog entries tracked with each pull request, and\n you don\\'t have to worry about merge conflicts to your CHANGELOG\n file.\n- You can generate more than just a CHANGELOG file if needed. For\n example, you can create a \\\"History\\\" page in your docs that\\'s\n rendered differently than your CHANGELOG.\n- You can programatically query for a projects changes.\n\n\n# Development\n\nThis project requires at Python 3.9+ and uses\n[Poetry](https://python-poetry.org/) to manage dependencies.\n\nOnce you've created and activated your virtual environment, run:\n\n```sh\npoetry install\n```\n\nThis will install all necessary dependencies and install this project\nin editable mode.\n\n\n## Testing\n\n[Poe the Poet](https://github.com/nat-n/poethepoet) is the task runner\nused for this project, it's automatically installed as part of the\n`poetry install` step. To see a list of available tasks, run the\n`poe` command with no args.\n\nTo run the tests for this project run:\n\n\n```sh\npoe test\n```\n\n## Pre-commit\n\n[Pre-commit](https://pre-commit.com/) hooks runs misc. auto-formatters and\nquality checks to ensure all changes look good before committing. The same\nchanges are also run on Pull Requests so this helps provides a quicker feedback\nloop before submitting a PR.\n\nYou can install the hooks with (runs for each commit):\n\n```sh\npre-commit install\n```\n\nOr if you want e.g. want to run all checks manually for all files:\n\n```\npoe pre-commit\n```\n\nOr if you run to the `pre-commit` executable directly:\n\n```sh\npre-commit run --all-files\n```\n\n",
"bugtrack_url": null,
"license": "Apache-2.0",
"summary": "Tool for managing changelogs",
"version": "0.2.0",
"project_urls": {
"Documentation": "https://jamesls.github.io/jmeslog",
"Homepage": "https://jamesls.github.io/jmeslog",
"Repository": "https://github.com/jamesls/jmeslog"
},
"split_keywords": [],
"urls": [
{
"comment_text": "",
"digests": {
"blake2b_256": "1423e8da029c40c6288ff06d6404be467286bed9e5b4cd8e93e54d08a5240d93",
"md5": "5b937482551a174cee6dbad4cef649a8",
"sha256": "373569fc0ae86396466ab9b443e6558bf1bc9b6207dff307e79c214ef4727b96"
},
"downloads": -1,
"filename": "jmeslog-0.2.0-py3-none-any.whl",
"has_sig": false,
"md5_digest": "5b937482551a174cee6dbad4cef649a8",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": "<4.0,>=3.9.0",
"size": 15935,
"upload_time": "2024-05-09T21:44:53",
"upload_time_iso_8601": "2024-05-09T21:44:53.845262Z",
"url": "https://files.pythonhosted.org/packages/14/23/e8da029c40c6288ff06d6404be467286bed9e5b4cd8e93e54d08a5240d93/jmeslog-0.2.0-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": "",
"digests": {
"blake2b_256": "272b38adf3f4a2193ba38d02d25e42fddfc70864203c9ca047eddd03d61120e0",
"md5": "84f459df9a0d64abd426adb39997ed97",
"sha256": "4cab43a8ce3469ac878ba58cb8493d5317200c85b92a85189a2554b859d5533f"
},
"downloads": -1,
"filename": "jmeslog-0.2.0.tar.gz",
"has_sig": false,
"md5_digest": "84f459df9a0d64abd426adb39997ed97",
"packagetype": "sdist",
"python_version": "source",
"requires_python": "<4.0,>=3.9.0",
"size": 16549,
"upload_time": "2024-05-09T21:44:55",
"upload_time_iso_8601": "2024-05-09T21:44:55.072019Z",
"url": "https://files.pythonhosted.org/packages/27/2b/38adf3f4a2193ba38d02d25e42fddfc70864203c9ca047eddd03d61120e0/jmeslog-0.2.0.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2024-05-09 21:44:55",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "jamesls",
"github_project": "jmeslog",
"travis_ci": false,
"coveralls": false,
"github_actions": true,
"lcname": "jmeslog"
}