Ecosyste.ms: Awesome

An open API service indexing awesome lists of open source software.

Awesome Lists | Featured Topics | Projects

https://github.com/Colin-b/keepachangelog

Convert keep a changelog markdown file into python dict
https://github.com/Colin-b/keepachangelog

changelog changelog-parser markdown

Last synced: 3 months ago
JSON representation

Convert keep a changelog markdown file into python dict

Awesome Lists containing this project

README

        

Manipulate keep a changelog files


pypi version
Build status
Coverage
Code style: black
Number of tests
Number of downloads

* [Command line utility](#usage-from-command-line)
* [Convert to dict](#convert-changelog-to-dict)
* [Convert from dict](#convert-dict-to-changelog)
* [Release a new version](#release)
* [Add changelog retrieval REST API endpoint](#endpoint)
* [Starlette](#starlette)
* [Flask-RestX](#flask-restx)

## Convert changelog to dict

Convert changelog markdown file following [keep a changelog](https://keepachangelog.com/en/1.1.0/) format into python dict.

```python
import keepachangelog

changes = keepachangelog.to_dict("path/to/CHANGELOG.md")
```

`changes` would look like:

```python
changes = {
"1.1.0": {
"changed": [
"Enhancement 1 (1.1.0)",
"sub enhancement 1",
"sub enhancement 2",
"Enhancement 2 (1.1.0)",
],
"metadata": {
"release_date": "2018-05-31",
"version": "1.1.0",
"semantic_version": {
"major": 1,
"minor": 1,
"patch": 0,
"prerelease": None,
"buildmetadata": None,
},
"url": "https://github.test_url/test_project/compare/v1.0.1...v1.1.0",
},
},
"1.0.1": {
"fixed": [
"Bug fix 1 (1.0.1)",
"sub bug 1",
"sub bug 2",
"Bug fix 2 (1.0.1)",
],
"metadata": {
"release_date": "2018-05-31",
"version": "1.0.1",
"semantic_version": {
"major": 1,
"minor": 0,
"patch": 1,
"prerelease": None,
"buildmetadata": None,
},
"url": "https://github.test_url/test_project/compare/v1.0.0...v1.0.1",
},
},
"1.0.0": {
"deprecated": ["Known issue 1 (1.0.0)", "Known issue 2 (1.0.0)"],
"metadata": {
"release_date": "2017-04-10",
"version": "1.0.0",
"semantic_version": {
"major": 1,
"minor": 0,
"patch": 0,
"prerelease": None,
"buildmetadata": None,
},
"url": "https://github.test_url/test_project/releases/tag/v1.0.0",
},
},
}
```

For a markdown file with the following content:

```markdown
# Changelog
All notable changes to this project will be documented in this file.

The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [Unreleased]
### Changed
- Release note 1.
- Release note 2.

### Added
- Enhancement 1
- sub enhancement 1
- sub enhancement 2
- Enhancement 2

### Fixed
- Bug fix 1
- sub bug 1
- sub bug 2
- Bug fix 2

### Security
- Known issue 1
- Known issue 2

### Deprecated
- Deprecated feature 1
- Future removal 2

### Removed
- Deprecated feature 2
- Future removal 1

## [1.1.0] - 2018-05-31
### Changed
- Enhancement 1 (1.1.0)
- sub enhancement 1
- sub enhancement 2
- Enhancement 2 (1.1.0)

## [1.0.1] - 2018-05-31
### Fixed
- Bug fix 1 (1.0.1)
- sub bug 1
- sub bug 2
- Bug fix 2 (1.0.1)

## [1.0.0] - 2017-04-10
### Deprecated
- Known issue 1 (1.0.0)
- Known issue 2 (1.0.0)

[Unreleased]: https://github.test_url/test_project/compare/v1.1.0...HEAD
[1.1.0]: https://github.test_url/test_project/compare/v1.0.1...v1.1.0
[1.0.1]: https://github.test_url/test_project/compare/v1.0.0...v1.0.1
[1.0.0]: https://github.test_url/test_project/releases/tag/v1.0.0
```

`show_unreleased` parameter can be specified in order to include `Unreleased` section information.
Note that `release_date` metadata will be set to None in such as case.

### Retrieving the raw content

#### Using CLI

```shell
keepachangelog show 1.0.0
```

For details on what is actually performed, refer to the section below as it is what is used underneath the hood.

#### Using python module

If for some reason you would like to retrieve the raw content of a release you can use `to_raw_dict` instead.

```python
import keepachangelog

changes = keepachangelog.to_raw_dict("path/to/CHANGELOG.md")
```

`changes` would look like:

```python
changes = {
"1.1.0": {
"raw": """### Changed
- Enhancement 1 (1.1.0)
- sub enhancement 1
- sub enhancement 2
- Enhancement 2 (1.1.0)""",
"metadata": {
"release_date": "2018-05-31",
"version": "1.1.0",
"semantic_version": {
"major": 1,
"minor": 1,
"patch": 0,
"prerelease": None,
"buildmetadata": None,
},
"url": "https://github.test_url/test_project/compare/v1.0.1...v1.1.0",
},
},
"1.0.1": {
"raw": """### Fixed
- Bug fix 1 (1.0.1)
- sub bug 1
- sub bug 2
- Bug fix 2 (1.0.1)""",
"metadata": {
"release_date": "2018-05-31",
"version": "1.0.1",
"semantic_version": {
"major": 1,
"minor": 0,
"patch": 1,
"prerelease": None,
"buildmetadata": None,
},
"url": "https://github.test_url/test_project/compare/v1.0.0...v1.0.1",
},
},
"1.0.0": {
"raw": """### Deprecated
- Known issue 1 (1.0.0)
- Known issue 2 (1.0.0)""",
"metadata": {
"release_date": "2017-04-10",
"version": "1.0.0",
"semantic_version": {
"major": 1,
"minor": 0,
"patch": 0,
"prerelease": None,
"buildmetadata": None,
},
"url": "https://github.test_url/test_project/releases/tag/v1.0.0",
},
},
}
```

## Convert dict to changelog

Convert a python dict (resulting from [`keepachangelog.to_dict`](#convert-changelog-to-dict)) to a changelog markdown content following [keep a changelog](https://keepachangelog.com/en/1.1.0/) format.

```python
import keepachangelog

changes = keepachangelog.to_dict("path/to/CHANGELOG.md")
content = keepachangelog.from_dict(changes)
```

## Release

### Using CLI

```shell
keepachangelog release
```

For details on what is actually performed, refer to the section below as it is what is used underneath the hood.

### Using python module

You can create a new release by using `keepachangelog.release` function.

```python
import keepachangelog

new_version = keepachangelog.release("path/to/CHANGELOG.md")
```

This will:
* If `new_version` parameter is not provided, guess the new version number and return it:
* `Removed` or `Changed` sections will be considered as breaking changes, thus incrementing the major version.
* If the only section is `Fixed`, only patch will be incremented.
* Otherwise, minor will be incremented.
* Update changelog.
* Unreleased section content will be moved into a new section.
* `[Unreleased]` link will be updated.
* New link will be created corresponding to the new section (based on the format of the Unreleased link).

## Usage from command line

`keepachangelog` can be used directly via command line.

The main usage is within your CI to be able to [Release a new version](#release) and then [Create the appropriate release body](#retrieving-the-raw-content).
As in the following sample:
```shell
NEW_VERSION=$(keepachangelog release)
GITHUB_RELEASE_BODY=$(keepachangelog show ${NEW_VERSION})
```

You can use it as a python module:
```sh
python -m keepachangelog --help
```

Or as a shell command:
```sh
keepachangelog --help
```

```sh
# usage: keepachangelog [-h] [-v] {show,release} ...
#
# Manipulate keep a changelog files
#
# options:
# -h, --help show this help message and exit
# -v, --version show program's version number and exit
#
# commands:
# {show,release}
# show Show the content of a release from the changelog
# release Create a new release in the changelog
#
# Examples:
#
# keepachangelog show 1.0.0
# keepachangelog show 1.0.0 path/to/CHANGELOG.md
#
# keepachangelog release
# keepachangelog release 1.0.1
# keepachangelog release 1.0.1 -f path/to/CHANGELOG.md
```

## Endpoint

### Starlette

A helper function is available to create a [starlette](https://www.starlette.io) endpoint to retrieve changelog as JSON.

```python
from starlette.applications import Starlette
from starlette.routing import Route
from keepachangelog.starlette import changelog_endpoint

# /changelog endpoint will return the dict extracted from the changelog as JSON.
changelog_route = Route("/changelog", endpoint=changelog_endpoint("path/to/CHANGELOG.md"))
app = Starlette(routes=[changelog_route])
```

Note: [starlette](https://pypi.python.org/pypi/starlette) module must be installed.

### Flask-RestX

A helper function is available to create a [Flask-RestX](https://flask-restx.readthedocs.io/en/latest/) endpoint to retrieve changelog as JSON.

```python
import flask
import flask_restx
from keepachangelog.flask_restx import add_changelog_endpoint

app = flask.Flask(__name__)
api = flask_restx.Api(app)
# /changelog endpoint will return the dict extracted from the changelog as JSON.
add_changelog_endpoint(api, "path/to/CHANGELOG.md")
```

Note: [flask-restx](https://pypi.python.org/pypi/flask-restx) module must be installed.

## How to install
1. [python 3.7+](https://www.python.org/downloads/) must be installed
2. Use pip to install module:
```sh
python -m pip install keepachangelog
```