diff --git a/CHANGELOG.md b/CHANGELOG.md index 47f5176..205430e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,9 +6,14 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +## [0.1.0] - 2020-02-17 +### Added +- `keepachangelog.starlette.add_changelog_endpoint` function to add a changelog endpoint to a [Starlette](https://www.starlette.io) application. + ## [0.0.1] - 2020-02-17 ### Added - Initial release. -[Unreleased]: https://github.com/Colin-b/keepachangelog/compare/v0.0.1...HEAD +[Unreleased]: https://github.com/Colin-b/keepachangelog/compare/v0.1.0...HEAD +[0.1.0]: https://github.com/Colin-b/keepachangelog/compare/v0.0.1...v0.1.0 [0.0.1]: https://github.com/Colin-b/keepachangelog/releases/tag/v0.0.1 diff --git a/README.md b/README.md index 0a7702f..a74cab6 100644 --- a/README.md +++ b/README.md @@ -5,7 +5,7 @@ Build status Coverage Code style: black -Number of tests +Number of tests Number of downloads

@@ -112,7 +112,23 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 [1.0.0]: https://github.test_url/test_project/releases/tag/v1.0.0 ``` +## Endpoint +### Starlette + +An 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 keepachangelog.starlette import add_changelog_endpoint + + +app = Starlette() +# /changelog endpoint will return the dict extracted from the changelog as JSON. +add_changelog_endpoint(app, "path/to/CHANGELOG.md") +``` + +Note: [starlette](https://pypi.python.org/pypi/starlette) module must be installed. ## How to install 1. [python 3.6+](https://www.python.org/downloads/) must be installed diff --git a/keepachangelog/starlette.py b/keepachangelog/starlette.py new file mode 100644 index 0000000..63850a2 --- /dev/null +++ b/keepachangelog/starlette.py @@ -0,0 +1,31 @@ +from starlette.applications import Starlette +from starlette.responses import JSONResponse + +from keepachangelog._changelog import to_dict + + +def add_changelog_endpoint(app: Starlette, changelog_path: str): + """ + Create /changelog: Changelog endpoint parsing https://keepachangelog.com/en/1.0.0/ + + :param app: The ASGI application. + :param changelog_path: Path to CHANGELOG.md. + """ + + @app.route("/changelog") + async def changelog(request): + """ + responses: + 200: + description: "Service changelog." + schema: + type: object + summary: "Retrieve service changelog" + operationId: get_changelog + tags: + - Monitoring + """ + try: + return JSONResponse(to_dict(changelog_path)) + except FileNotFoundError: + return JSONResponse({}) diff --git a/keepachangelog/version.py b/keepachangelog/version.py index e973d31..43c94ee 100644 --- a/keepachangelog/version.py +++ b/keepachangelog/version.py @@ -3,4 +3,4 @@ # Major should be incremented in case there is a breaking change. (eg: 2.5.8 -> 3.0.0) # Minor should be incremented in case there is an enhancement. (eg: 2.5.8 -> 2.6.0) # Patch should be incremented in case there is a bug fix. (eg: 2.5.8 -> 2.5.9) -__version__ = "0.0.1" +__version__ = "0.1.0" diff --git a/setup.py b/setup.py index 1130c0a..b314b92 100644 --- a/setup.py +++ b/setup.py @@ -37,9 +37,12 @@ install_requires=[], extras_require={ "testing": [ + # Used to check starlette endpoint + "starlette==0.13.*", + "requests==2.*", # Used to check coverage "pytest-cov==2.*", - ], + ] }, python_requires=">=3.6", project_urls={ diff --git a/tests/test_starlette.py b/tests/test_starlette.py new file mode 100644 index 0000000..eb8fb7d --- /dev/null +++ b/tests/test_starlette.py @@ -0,0 +1,114 @@ +import os + +from starlette.applications import Starlette +from starlette.testclient import TestClient + +from keepachangelog.starlette import add_changelog_endpoint + + +def test_changelog_endpoint_with_file(tmpdir): + changelog_file_path = os.path.join(tmpdir, "CHANGELOG.md") + with open(changelog_file_path, "wt") as file: + file.write( + """# 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.0.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 +""" + ) + + app = Starlette() + add_changelog_endpoint(app, changelog_file_path) + with TestClient(app) as client: + response = client.get("/changelog") + assert response.status_code == 200 + assert response.json() == { + "1.1.0": { + "changed": [ + "- Enhancement 1 (1.1.0)", + "- sub enhancement 1", + "- sub enhancement 2", + "- Enhancement 2 (1.1.0)", + ], + "release_date": "2018-05-31", + "version": "1.1.0", + }, + "1.0.1": { + "fixed": [ + "- Bug fix 1 (1.0.1)", + "- sub bug 1", + "- sub bug 2", + "- Bug fix 2 (1.0.1)", + ], + "release_date": "2018-05-31", + "version": "1.0.1", + }, + "1.0.0": { + "deprecated": ["- Known issue 1 (1.0.0)", "- Known issue 2 (1.0.0)"], + "release_date": "2017-04-10", + "version": "1.0.0", + }, + } + + +def test_changelog_endpoint_without_file(): + app = Starlette() + add_changelog_endpoint(app, "non existing") + with TestClient(app) as client: + response = client.get("/changelog") + assert response.status_code == 200 + assert response.json() == {}