From 0519583df2fec2861cc5e0d4cd509511338c1cd3 Mon Sep 17 00:00:00 2001
From: Colin-b
Date: Wed, 26 May 2021 16:38:43 +0200
Subject: [PATCH 1/8] Add uncategorized details to releases
---
CHANGELOG.md | 6 ++
keepachangelog/_changelog.py | 38 ++++++++---
tests/test_changelog.py | 15 ++++-
tests/test_changelog_no_category.py | 97 +++++++++++++++++++++++++++++
tests/test_changelog_unreleased.py | 2 +
5 files changed, 146 insertions(+), 12 deletions(-)
create mode 100644 tests/test_changelog_no_category.py
diff --git a/CHANGELOG.md b/CHANGELOG.md
index a33ab6b..23d60df 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -5,6 +5,12 @@ 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]
+### Fixed
+- `keepachangelog.to_dict` now contains releases that have a URL but no section.
+- `keepachangelog.to_raw_dict` now contains releases that have a URL but no section.
+
+### Changed
+- `keepachangelog.to_dict` now contains `uncategorized` key for each item if uncategorized information are available for the version.
## [1.0.0] - 2021-05-21
### Changed
diff --git a/keepachangelog/_changelog.py b/keepachangelog/_changelog.py
index ce729e3..09aae7b 100644
--- a/keepachangelog/_changelog.py
+++ b/keepachangelog/_changelog.py
@@ -14,7 +14,7 @@ def is_release(line: str) -> bool:
return line.startswith("## ")
-def add_release(changes: Dict[str, dict], line: str, show_unreleased: bool) -> dict:
+def add_release(changes: Dict[str, dict], line: str) -> dict:
release_line = line[3:].lower().strip(" ")
# A release is separated by a space between version and release date
# Release pattern should match lines like: "[0.0.1] - 2020-12-31" or [Unreleased]
@@ -23,8 +23,6 @@ def add_release(changes: Dict[str, dict], line: str, show_unreleased: bool) -> d
if " " in release_line
else (release_line, None)
)
- if not show_unreleased and not release_date:
- return {}
version = unlink(version)
release_details = {"version": version, "release_date": extract_date(release_date)}
@@ -79,7 +77,8 @@ def to_dict(changelog_path: str, *, show_unreleased: bool = False) -> Dict[str,
line = line.strip(" \n")
if is_release(line):
- current_release = add_release(changes, line, show_unreleased)
+ current_release = add_release(changes, line)
+ category = current_release.setdefault("uncategorized", [])
elif is_category(line):
category = add_category(current_release, line)
elif is_link(line):
@@ -88,8 +87,22 @@ def to_dict(changelog_path: str, *, show_unreleased: bool = False) -> Dict[str,
elif line:
add_information(category, line)
+ # Add url for each version (create version if not existing)
for version, url in urls.items():
- changes.get(version, {})["url"] = url
+ changes.setdefault(version, {"version": version})["url"] = url
+
+ # Avoid empty uncategorized
+ unreleased_version = None
+ for version, current_release in changes.items():
+ if not current_release.get("uncategorized"):
+ current_release.pop("uncategorized", None)
+
+ # If there is an empty release date, it identify the unreleased section
+ if ("release_date" in current_release) and not current_release["release_date"]:
+ unreleased_version = version
+
+ if not show_unreleased:
+ changes.pop(unreleased_version, None)
return changes
@@ -104,17 +117,24 @@ def to_raw_dict(changelog_path: str) -> Dict[str, dict]:
clean_line = line.strip(" \n")
if is_release(clean_line):
- current_release = add_release(
- changes, clean_line, show_unreleased=False
- )
+ current_release = add_release(changes, clean_line)
elif is_link(clean_line):
link_match = link_pattern.fullmatch(clean_line)
urls[link_match.group(1).lower()] = link_match.group(2)
elif clean_line:
current_release["raw"] = current_release.get("raw", "") + line
+ # Add url for each version (create version if not existing)
for version, url in urls.items():
- changes.get(version, {})["url"] = url
+ changes.setdefault(version, {"version": version})["url"] = url
+
+ unreleased_version = None
+ for version, current_release in changes.items():
+ # If there is an empty release date, it identify the unreleased section
+ if ("release_date" in current_release) and not current_release["release_date"]:
+ unreleased_version = version
+
+ changes.pop(unreleased_version, None)
return changes
diff --git a/tests/test_changelog.py b/tests/test_changelog.py
index 59159fe..65eb340 100644
--- a/tests/test_changelog.py
+++ b/tests/test_changelog.py
@@ -68,7 +68,8 @@ def changelog(tmpdir):
- 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.1.0]: https://github.test_url/test_project/compare/v1.0.2...v1.1.0
+[1.0.2]: https://github.test_url/test_project/compare/v1.0.1...v1.0.2
[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
"""
@@ -116,7 +117,11 @@ def test_changelog_with_versions_and_all_categories(changelog):
"patch": 0,
"prerelease": None,
},
- "url": "https://github.test_url/test_project/compare/v1.0.1...v1.1.0",
+ "url": "https://github.test_url/test_project/compare/v1.0.2...v1.1.0",
+ },
+ "1.0.2": {
+ "version": "1.0.2",
+ "url": "https://github.test_url/test_project/compare/v1.0.1...v1.0.2",
},
"1.0.1": {
"fixed": [
@@ -204,7 +209,11 @@ def test_raw_changelog_with_versions_and_all_categories(changelog):
"patch": 0,
"prerelease": None,
},
- "url": "https://github.test_url/test_project/compare/v1.0.1...v1.1.0",
+ "url": "https://github.test_url/test_project/compare/v1.0.2...v1.1.0",
+ },
+ "1.0.2": {
+ "version": "1.0.2",
+ "url": "https://github.test_url/test_project/compare/v1.0.1...v1.0.2",
},
"1.0.1": {
"raw": """### Fixed
diff --git a/tests/test_changelog_no_category.py b/tests/test_changelog_no_category.py
new file mode 100644
index 0000000..321b7bc
--- /dev/null
+++ b/tests/test_changelog_no_category.py
@@ -0,0 +1,97 @@
+import os
+import os.path
+
+import pytest
+
+import keepachangelog
+
+
+@pytest.fixture
+def changelog(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]
+
+## [1.2.0] - 2018-06-01
+- Release note 1.
+- Release note 2.
+
+### Fixed
+- Bug fix 1
+- sub bug 1
+- sub bug 2
+- Bug fix 2
+
+## [1.1.0] - 2018-05-31
+- Enhancement 1 (1.1.0)
+- sub enhancement 1
+- sub enhancement 2
+- Enhancement 2 (1.1.0)
+
+## [1.0.1] - 2018-05-31
+- Bug fix 1 (1.0.1)
+- sub bug 1
+- sub bug 2
+- Bug fix 2 (1.0.1)
+"""
+ )
+ return changelog_file_path
+
+
+def test_changelog_without_category(changelog):
+ assert keepachangelog.to_dict(changelog) == {
+ "1.2.0": {
+ "uncategorized": ["Release note 1.", "Release note 2."],
+ "fixed": ["Bug fix 1", "sub bug 1", "sub bug 2", "Bug fix 2"],
+ "release_date": "2018-06-01",
+ "version": "1.2.0",
+ "semantic_version": {
+ "buildmetadata": None,
+ "major": 1,
+ "minor": 2,
+ "patch": 0,
+ "prerelease": None,
+ },
+ },
+ "1.1.0": {
+ "uncategorized": [
+ "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",
+ "semantic_version": {
+ "buildmetadata": None,
+ "major": 1,
+ "minor": 1,
+ "patch": 0,
+ "prerelease": None,
+ },
+ },
+ "1.0.1": {
+ "uncategorized": [
+ "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",
+ "semantic_version": {
+ "buildmetadata": None,
+ "major": 1,
+ "minor": 0,
+ "patch": 1,
+ "prerelease": None,
+ },
+ },
+ }
diff --git a/tests/test_changelog_unreleased.py b/tests/test_changelog_unreleased.py
index 11fcdc1..cff6d4d 100644
--- a/tests/test_changelog_unreleased.py
+++ b/tests/test_changelog_unreleased.py
@@ -18,6 +18,7 @@ def changelog(tmpdir):
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
## [Unreleased]
+- Release note 0.
### Changed
- Release note 1.
* Release note 2.
@@ -88,6 +89,7 @@ def test_changelog_with_versions_and_all_categories(changelog):
],
"fixed": ["Bug fix 1", "sub bug 1", "sub bug 2", "Bug fix 2"],
"security": ["Known issue 1", "Known issue 2"],
+ "uncategorized": ["Release note 0."],
"deprecated": ["Deprecated feature 1", "Future removal 2"],
"removed": ["Deprecated feature 2", "Future removal 1"],
"url": "https://github.test_url/test_project/compare/v1.1.0...HEAD",
From aff22cc367c381abdda3a1d63a9f41cddbc03a37 Mon Sep 17 00:00:00 2001
From: Colin-b
Date: Wed, 26 May 2021 18:23:47 +0200
Subject: [PATCH 2/8] Allow to convert from dict
---
CHANGELOG.md | 3 ++
README.md | 14 +++++-
keepachangelog/__init__.py | 2 +-
keepachangelog/_changelog.py | 49 +++++++++++++++++++++
tests/test_changelog_unreleased.py | 69 ++++++++++++++++++++++++++++++
5 files changed, 135 insertions(+), 2 deletions(-)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 23d60df..38fe605 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -12,6 +12,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### Changed
- `keepachangelog.to_dict` now contains `uncategorized` key for each item if uncategorized information are available for the version.
+### Added
+- `keepachangelog.from_dict` to create a changelog content based on a dictionary.
+
## [1.0.0] - 2021-05-21
### Changed
- `keepachangelog.to_dict` now contains `url` key for each item if a link is available for the version.
diff --git a/README.md b/README.md
index 195bb22..4e2f542 100644
--- a/README.md
+++ b/README.md
@@ -5,11 +5,12 @@
-
+
* [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)
@@ -213,6 +214,17 @@ changes = {
}
```
+## 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
You can create a new release by using `keepachangelog.release` function.
diff --git a/keepachangelog/__init__.py b/keepachangelog/__init__.py
index 31e7d59..d40e7a6 100644
--- a/keepachangelog/__init__.py
+++ b/keepachangelog/__init__.py
@@ -1,2 +1,2 @@
from keepachangelog.version import __version__
-from keepachangelog._changelog import to_dict, to_raw_dict, release
+from keepachangelog._changelog import to_dict, to_raw_dict, release, from_dict
diff --git a/keepachangelog/_changelog.py b/keepachangelog/_changelog.py
index 09aae7b..e71a044 100644
--- a/keepachangelog/_changelog.py
+++ b/keepachangelog/_changelog.py
@@ -107,6 +107,55 @@ def to_dict(changelog_path: str, *, show_unreleased: bool = False) -> Dict[str,
return changes
+def from_dict(changes: Dict[str, dict]):
+ content = """# 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).\n"""
+
+ for current_release in changes.values():
+ content += f"\n## [{current_release['version'].capitalize()}]"
+
+ if current_release.get("release_date"):
+ content += f" - {current_release['release_date']}"
+
+ uncategorized = current_release.get("uncategorized", [])
+ for category_content in uncategorized:
+ content += f"\n* {category_content}"
+ if uncategorized:
+ content += "\n"
+
+ for category_name, category_content in current_release.items():
+ if category_name in [
+ "version",
+ "release_date",
+ "uncategorized",
+ "semantic_version",
+ "url",
+ ]:
+ continue
+
+ content += f"\n### {category_name.capitalize()}"
+
+ for categorized in category_content:
+ content += f"\n- {categorized}"
+
+ content += "\n"
+
+ content += "\n"
+
+ for current_release in changes.values():
+ if not current_release.get("url"):
+ continue
+
+ content += (
+ f"[{current_release['version'].capitalize()}]: {current_release['url']}\n"
+ )
+
+ return content
+
+
def to_raw_dict(changelog_path: str) -> Dict[str, dict]:
changes = {}
# As URLs can be defined before actual usage, maintain a separate dict
diff --git a/tests/test_changelog_unreleased.py b/tests/test_changelog_unreleased.py
index cff6d4d..7c7b5f9 100644
--- a/tests/test_changelog_unreleased.py
+++ b/tests/test_changelog_unreleased.py
@@ -144,3 +144,72 @@ def test_changelog_with_versions_and_all_categories(changelog):
"url": "https://github.test_url/test_project/releases/tag/v1.0.0",
},
}
+
+
+def test_changelog_from_dict(changelog):
+ releases = keepachangelog.to_dict(changelog, show_unreleased=True)
+
+ assert (
+ keepachangelog.from_dict(releases)
+ == """# 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]
+* Release note 0.
+
+### 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
+"""
+ )
From 968b38def21155110c6f91c2f4b9d18e5bb44b42 Mon Sep 17 00:00:00 2001
From: Colin-b
Date: Wed, 26 May 2021 18:39:45 +0200
Subject: [PATCH 3/8] Allow to provide changelog as a buffer
---
CHANGELOG.md | 1 +
keepachangelog/_changelog.py | 16 ++++++-
tests/test_changelog.py | 82 ++++++++++++++++++++++++++++++++++++
3 files changed, 98 insertions(+), 1 deletion(-)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 38fe605..8724bfa 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -14,6 +14,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### Added
- `keepachangelog.from_dict` to create a changelog content based on a dictionary.
+- `keepachangelog.to_dict` now allows to provide a context manager allowing to iterate on lines instead of a file path.
## [1.0.0] - 2021-05-21
### Changed
diff --git a/keepachangelog/_changelog.py b/keepachangelog/_changelog.py
index e71a044..ff92480 100644
--- a/keepachangelog/_changelog.py
+++ b/keepachangelog/_changelog.py
@@ -67,10 +67,24 @@ def add_information(category: List[str], line: str):
def to_dict(changelog_path: str, *, show_unreleased: bool = False) -> Dict[str, dict]:
+ """
+ Convert changelog markdown file following keep a changelog format into python dict.
+
+ :param changelog_path: Path to the changelog file, or context manager providing iteration on lines.
+ :param show_unreleased: Add unreleased section (if any) to the resulting dictionary.
+ :return python dict containing version as key and related changes as value.
+ """
changes = {}
# As URLs can be defined before actual usage, maintain a separate dict
urls = {}
- with open(changelog_path) as change_log:
+
+ # Allow for changelog as a file path or as a context manager providing content
+ try:
+ change_log = open(changelog_path)
+ except TypeError:
+ change_log = changelog_path
+
+ with change_log:
current_release = {}
category = []
for line in change_log:
diff --git a/tests/test_changelog.py b/tests/test_changelog.py
index 65eb340..d6a4676 100644
--- a/tests/test_changelog.py
+++ b/tests/test_changelog.py
@@ -1,3 +1,4 @@
+import io
import os
import os.path
@@ -157,6 +158,87 @@ def test_changelog_with_versions_and_all_categories(changelog):
}
+def test_changelog_with_versions_and_all_categories_as_file_reader(changelog):
+ with io.StringIO(open(changelog).read()) as file_reader:
+ assert keepachangelog.to_dict(file_reader) == {
+ "1.2.0": {
+ "added": [
+ "Enhancement 1",
+ "sub enhancement 1",
+ "sub enhancement 2",
+ "Enhancement 2",
+ ],
+ "changed": ["Release note 1.", "Release note 2."],
+ "deprecated": ["Deprecated feature 1", "Future removal 2"],
+ "fixed": ["Bug fix 1", "sub bug 1", "sub bug 2", "Bug fix 2"],
+ "release_date": "2018-06-01",
+ "removed": ["Deprecated feature 2", "Future removal 1"],
+ "security": ["Known issue 1", "Known issue 2"],
+ "version": "1.2.0",
+ "semantic_version": {
+ "buildmetadata": None,
+ "major": 1,
+ "minor": 2,
+ "patch": 0,
+ "prerelease": None,
+ },
+ },
+ "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",
+ "semantic_version": {
+ "buildmetadata": None,
+ "major": 1,
+ "minor": 1,
+ "patch": 0,
+ "prerelease": None,
+ },
+ "url": "https://github.test_url/test_project/compare/v1.0.2...v1.1.0",
+ },
+ "1.0.2": {
+ "version": "1.0.2",
+ "url": "https://github.test_url/test_project/compare/v1.0.1...v1.0.2",
+ },
+ "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",
+ "semantic_version": {
+ "buildmetadata": None,
+ "major": 1,
+ "minor": 0,
+ "patch": 1,
+ "prerelease": 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)"],
+ "release_date": "2017-04-10",
+ "version": "1.0.0",
+ "semantic_version": {
+ "buildmetadata": None,
+ "major": 1,
+ "minor": 0,
+ "patch": 0,
+ "prerelease": None,
+ },
+ "url": "https://github.test_url/test_project/releases/tag/v1.0.0",
+ },
+ }
+
+
def test_raw_changelog_with_versions_and_all_categories(changelog):
assert keepachangelog.to_raw_dict(changelog) == {
"1.2.0": {
From 357a7fe0e72b8e1e76e6d8f2c6caa69d42c9c6ce Mon Sep 17 00:00:00 2001
From: Colin-b
Date: Wed, 26 May 2021 19:00:49 +0200
Subject: [PATCH 4/8] Expect any line iterable instead of a context manager
---
CHANGELOG.md | 2 +-
keepachangelog/_changelog.py | 51 ++++----
tests/test_changelog.py | 233 ++++++++++++-----------------------
3 files changed, 110 insertions(+), 176 deletions(-)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 8724bfa..2b5ac04 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -14,7 +14,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### Added
- `keepachangelog.from_dict` to create a changelog content based on a dictionary.
-- `keepachangelog.to_dict` now allows to provide a context manager allowing to iterate on lines instead of a file path.
+- `keepachangelog.to_dict` now allows to provide any line iterable instead of only a file path.
## [1.0.0] - 2021-05-21
### Changed
diff --git a/keepachangelog/_changelog.py b/keepachangelog/_changelog.py
index ff92480..e029841 100644
--- a/keepachangelog/_changelog.py
+++ b/keepachangelog/_changelog.py
@@ -1,6 +1,6 @@
import datetime
import re
-from typing import Dict, List, Optional
+from typing import Dict, List, Optional, Iterable, Union
from keepachangelog._versioning import (
actual_version,
@@ -66,7 +66,9 @@ def add_information(category: List[str], line: str):
category.append(line.lstrip(" *-").rstrip(" -"))
-def to_dict(changelog_path: str, *, show_unreleased: bool = False) -> Dict[str, dict]:
+def to_dict(
+ changelog_path: Union[str, Iterable[str]], *, show_unreleased: bool = False
+) -> Dict[str, dict]:
"""
Convert changelog markdown file following keep a changelog format into python dict.
@@ -74,32 +76,33 @@ def to_dict(changelog_path: str, *, show_unreleased: bool = False) -> Dict[str,
:param show_unreleased: Add unreleased section (if any) to the resulting dictionary.
:return python dict containing version as key and related changes as value.
"""
- changes = {}
- # As URLs can be defined before actual usage, maintain a separate dict
- urls = {}
-
# Allow for changelog as a file path or as a context manager providing content
try:
- change_log = open(changelog_path)
+ with open(changelog_path) as change_log:
+ return _to_dict(change_log, show_unreleased)
except TypeError:
- change_log = changelog_path
+ return _to_dict(changelog_path, show_unreleased)
- with change_log:
- current_release = {}
- category = []
- for line in change_log:
- line = line.strip(" \n")
-
- if is_release(line):
- current_release = add_release(changes, line)
- category = current_release.setdefault("uncategorized", [])
- elif is_category(line):
- category = add_category(current_release, line)
- elif is_link(line):
- link_match = link_pattern.fullmatch(line)
- urls[link_match.group(1).lower()] = link_match.group(2)
- elif line:
- add_information(category, line)
+
+def _to_dict(change_log: Iterable[str], show_unreleased: bool) -> Dict[str, dict]:
+ changes = {}
+ # As URLs can be defined before actual usage, maintain a separate dict
+ urls = {}
+ current_release = {}
+ category = []
+ for line in change_log:
+ line = line.strip(" \n")
+
+ if is_release(line):
+ current_release = add_release(changes, line)
+ category = current_release.setdefault("uncategorized", [])
+ elif is_category(line):
+ category = add_category(current_release, line)
+ elif is_link(line):
+ link_match = link_pattern.fullmatch(line)
+ urls[link_match.group(1).lower()] = link_match.group(2)
+ elif line:
+ add_information(category, line)
# Add url for each version (create version if not existing)
for version, url in urls.items():
diff --git a/tests/test_changelog.py b/tests/test_changelog.py
index d6a4676..fc9d28d 100644
--- a/tests/test_changelog.py
+++ b/tests/test_changelog.py
@@ -78,165 +78,96 @@ def changelog(tmpdir):
return changelog_file_path
-def test_changelog_with_versions_and_all_categories(changelog):
- assert keepachangelog.to_dict(changelog) == {
- "1.2.0": {
- "added": [
- "Enhancement 1",
- "sub enhancement 1",
- "sub enhancement 2",
- "Enhancement 2",
- ],
- "changed": ["Release note 1.", "Release note 2."],
- "deprecated": ["Deprecated feature 1", "Future removal 2"],
- "fixed": ["Bug fix 1", "sub bug 1", "sub bug 2", "Bug fix 2"],
- "release_date": "2018-06-01",
- "removed": ["Deprecated feature 2", "Future removal 1"],
- "security": ["Known issue 1", "Known issue 2"],
- "version": "1.2.0",
- "semantic_version": {
- "buildmetadata": None,
- "major": 1,
- "minor": 2,
- "patch": 0,
- "prerelease": None,
- },
+changelog_as_dict = {
+ "1.2.0": {
+ "added": [
+ "Enhancement 1",
+ "sub enhancement 1",
+ "sub enhancement 2",
+ "Enhancement 2",
+ ],
+ "changed": ["Release note 1.", "Release note 2."],
+ "deprecated": ["Deprecated feature 1", "Future removal 2"],
+ "fixed": ["Bug fix 1", "sub bug 1", "sub bug 2", "Bug fix 2"],
+ "release_date": "2018-06-01",
+ "removed": ["Deprecated feature 2", "Future removal 1"],
+ "security": ["Known issue 1", "Known issue 2"],
+ "version": "1.2.0",
+ "semantic_version": {
+ "buildmetadata": None,
+ "major": 1,
+ "minor": 2,
+ "patch": 0,
+ "prerelease": None,
},
- "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",
- "semantic_version": {
- "buildmetadata": None,
- "major": 1,
- "minor": 1,
- "patch": 0,
- "prerelease": None,
- },
- "url": "https://github.test_url/test_project/compare/v1.0.2...v1.1.0",
+ },
+ "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",
+ "semantic_version": {
+ "buildmetadata": None,
+ "major": 1,
+ "minor": 1,
+ "patch": 0,
+ "prerelease": None,
},
- "1.0.2": {
- "version": "1.0.2",
- "url": "https://github.test_url/test_project/compare/v1.0.1...v1.0.2",
- },
- "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",
- "semantic_version": {
- "buildmetadata": None,
- "major": 1,
- "minor": 0,
- "patch": 1,
- "prerelease": None,
- },
- "url": "https://github.test_url/test_project/compare/v1.0.0...v1.0.1",
+ "url": "https://github.test_url/test_project/compare/v1.0.2...v1.1.0",
+ },
+ "1.0.2": {
+ "version": "1.0.2",
+ "url": "https://github.test_url/test_project/compare/v1.0.1...v1.0.2",
+ },
+ "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",
+ "semantic_version": {
+ "buildmetadata": None,
+ "major": 1,
+ "minor": 0,
+ "patch": 1,
+ "prerelease": None,
},
- "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",
- "semantic_version": {
- "buildmetadata": None,
- "major": 1,
- "minor": 0,
- "patch": 0,
- "prerelease": None,
- },
- "url": "https://github.test_url/test_project/releases/tag/v1.0.0",
+ "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)"],
+ "release_date": "2017-04-10",
+ "version": "1.0.0",
+ "semantic_version": {
+ "buildmetadata": None,
+ "major": 1,
+ "minor": 0,
+ "patch": 0,
+ "prerelease": None,
},
- }
+ "url": "https://github.test_url/test_project/releases/tag/v1.0.0",
+ },
+}
+
+
+def test_changelog_with_versions_and_all_categories(changelog):
+ assert keepachangelog.to_dict(changelog) == changelog_as_dict
def test_changelog_with_versions_and_all_categories_as_file_reader(changelog):
with io.StringIO(open(changelog).read()) as file_reader:
- assert keepachangelog.to_dict(file_reader) == {
- "1.2.0": {
- "added": [
- "Enhancement 1",
- "sub enhancement 1",
- "sub enhancement 2",
- "Enhancement 2",
- ],
- "changed": ["Release note 1.", "Release note 2."],
- "deprecated": ["Deprecated feature 1", "Future removal 2"],
- "fixed": ["Bug fix 1", "sub bug 1", "sub bug 2", "Bug fix 2"],
- "release_date": "2018-06-01",
- "removed": ["Deprecated feature 2", "Future removal 1"],
- "security": ["Known issue 1", "Known issue 2"],
- "version": "1.2.0",
- "semantic_version": {
- "buildmetadata": None,
- "major": 1,
- "minor": 2,
- "patch": 0,
- "prerelease": None,
- },
- },
- "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",
- "semantic_version": {
- "buildmetadata": None,
- "major": 1,
- "minor": 1,
- "patch": 0,
- "prerelease": None,
- },
- "url": "https://github.test_url/test_project/compare/v1.0.2...v1.1.0",
- },
- "1.0.2": {
- "version": "1.0.2",
- "url": "https://github.test_url/test_project/compare/v1.0.1...v1.0.2",
- },
- "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",
- "semantic_version": {
- "buildmetadata": None,
- "major": 1,
- "minor": 0,
- "patch": 1,
- "prerelease": 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)"],
- "release_date": "2017-04-10",
- "version": "1.0.0",
- "semantic_version": {
- "buildmetadata": None,
- "major": 1,
- "minor": 0,
- "patch": 0,
- "prerelease": None,
- },
- "url": "https://github.test_url/test_project/releases/tag/v1.0.0",
- },
- }
+ assert keepachangelog.to_dict(file_reader) == changelog_as_dict
+
+ # Assert that file reader is not closed
+ file_reader.seek(0)
+ assert keepachangelog.to_dict(file_reader) == changelog_as_dict
def test_raw_changelog_with_versions_and_all_categories(changelog):
From d3a834df6420aaff6827794b43157ec46c08cc35 Mon Sep 17 00:00:00 2001
From: Colin-b
Date: Wed, 26 May 2021 19:01:20 +0200
Subject: [PATCH 5/8] Keep the number of test cases up to date
---
README.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/README.md b/README.md
index 4e2f542..34ef0a6 100644
--- a/README.md
+++ b/README.md
@@ -5,7 +5,7 @@
-
+
From 3a6102b94fd5fee66cc3e98c6b365e9f4fa653c6 Mon Sep 17 00:00:00 2001
From: Colin-b
Date: Thu, 27 May 2021 10:42:42 +0200
Subject: [PATCH 6/8] Ensure behavior of from_dict with unlink sections or non
existing one
---
tests/test_changelog_unreleased.py | 33 +++++++++++++++++++++++++++---
1 file changed, 30 insertions(+), 3 deletions(-)
diff --git a/tests/test_changelog_unreleased.py b/tests/test_changelog_unreleased.py
index 7c7b5f9..a6d6aa4 100644
--- a/tests/test_changelog_unreleased.py
+++ b/tests/test_changelog_unreleased.py
@@ -66,8 +66,13 @@ def changelog(tmpdir):
- Known issue 1 (1.0.0)
- Known issue 2 (1.0.0)
+## [0.0.1] - 2017-01-01
+### Added
+- First release
+
[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.1.0]: https://github.test_url/test_project/compare/v1.0.2...v1.1.0
+[1.0.2]: https://github.test_url/test_project/compare/v1.0.1...v1.0.2
[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
"""
@@ -110,7 +115,11 @@ def test_changelog_with_versions_and_all_categories(changelog):
"sub enhancement 2",
"Enhancement 2 (1.1.0)",
],
- "url": "https://github.test_url/test_project/compare/v1.0.1...v1.1.0",
+ "url": "https://github.test_url/test_project/compare/v1.0.2...v1.1.0",
+ },
+ "1.0.2": {
+ "url": "https://github.test_url/test_project/compare/v1.0.1...v1.0.2",
+ "version": "1.0.2",
},
"1.0.1": {
"version": "1.0.1",
@@ -143,6 +152,18 @@ def test_changelog_with_versions_and_all_categories(changelog):
"deprecated": ["Known issue 1 (1.0.0)", "Known issue 2 (1.0.0)"],
"url": "https://github.test_url/test_project/releases/tag/v1.0.0",
},
+ "0.0.1": {
+ "added": ["First release"],
+ "release_date": "2017-01-01",
+ "semantic_version": {
+ "buildmetadata": None,
+ "major": 0,
+ "minor": 0,
+ "patch": 1,
+ "prerelease": None,
+ },
+ "version": "0.0.1",
+ },
}
@@ -207,9 +228,15 @@ def test_changelog_from_dict(changelog):
- Known issue 1 (1.0.0)
- Known issue 2 (1.0.0)
+## [0.0.1] - 2017-01-01
+### Added
+- First release
+
+## [1.0.2]
[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.1.0]: https://github.test_url/test_project/compare/v1.0.2...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
+[1.0.2]: https://github.test_url/test_project/compare/v1.0.1...v1.0.2
"""
)
From 1488abb4f02810710026737304a511d300437063 Mon Sep 17 00:00:00 2001
From: Colin-b
Date: Thu, 27 May 2021 16:01:41 +0200
Subject: [PATCH 7/8] Add metadata information
---
CHANGELOG.md | 4 +
README.md | 122 +++++++-------
keepachangelog/_changelog.py | 42 ++---
keepachangelog/_versioning.py | 4 +-
keepachangelog/flask_restx.py | 23 +--
setup.py | 5 +-
tests/test_changelog.py | 168 +++++++++++---------
tests/test_changelog_empty_version.py | 18 ++-
tests/test_changelog_no_added.py | 72 +++++----
tests/test_changelog_no_category.py | 54 ++++---
tests/test_changelog_no_changed.py | 72 +++++----
tests/test_changelog_no_deprecated.py | 72 +++++----
tests/test_changelog_no_fixed.py | 72 +++++----
tests/test_changelog_no_removed.py | 72 +++++----
tests/test_changelog_no_security.py | 72 +++++----
tests/test_changelog_unreleased.py | 98 +++++++-----
tests/test_flask_restx.py | 60 +++----
tests/test_non_standard_changelog.py | 220 ++++++++++++++------------
tests/test_starlette.py | 60 +++----
19 files changed, 727 insertions(+), 583 deletions(-)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 2b5ac04..83de539 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -11,6 +11,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### Changed
- `keepachangelog.to_dict` now contains `uncategorized` key for each item if uncategorized information are available for the version.
+- `keepachangelog.to_dict` now contains `metadata` key where `version`, `release_date`, `semantic_version` and `url` have been moved.
+- `keepachangelog.to_raw_dict` now contains `metadata` key where `version`, `release_date`, `semantic_version` and `url` have been moved.
+- As `keepachangelog.starlette.add_changelog_endpoint` is returning data as returned by `keepachangelog.to_dict`, the endpoint output is now modified.
+- As `keepachangelog.flask_restx.add_changelog_endpoint` is returning data as returned by `keepachangelog.to_dict`, the endpoint output is now modified.
### Added
- `keepachangelog.from_dict` to create a changelog content based on a dictionary.
diff --git a/README.md b/README.md
index 34ef0a6..d95175e 100644
--- a/README.md
+++ b/README.md
@@ -37,16 +37,18 @@ changes = {
"sub enhancement 2",
"Enhancement 2 (1.1.0)",
],
- "release_date": "2018-05-31",
- "version": "1.1.0",
- "semantic_version": {
- "major": 1,
- "minor": 1,
- "patch": 0,
- "prerelease": None,
- "buildmetadata": None,
+ "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",
},
- "url": "https://github.test_url/test_project/compare/v1.0.1...v1.1.0",
},
"1.0.1": {
"fixed": [
@@ -55,29 +57,33 @@ changes = {
"sub bug 2",
"Bug fix 2 (1.0.1)",
],
- "release_date": "2018-05-31",
- "version": "1.0.1",
- "semantic_version": {
- "major": 1,
- "minor": 0,
- "patch": 1,
- "prerelease": None,
- "buildmetadata": None,
+ "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",
},
- "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)"],
- "release_date": "2017-04-10",
- "version": "1.0.0",
- "semantic_version": {
- "major": 1,
- "minor": 0,
- "patch": 0,
- "prerelease": None,
- "buildmetadata": None,
+ "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",
},
- "url": "https://github.test_url/test_project/releases/tag/v1.0.0",
},
}
```
@@ -146,7 +152,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
```
`show_unreleased` parameter can be specified in order to include `Unreleased` section information.
-Note that `release_date` will be set to None in such as case.
+Note that `release_date` metadata will be set to None in such as case.
### Retrieving the raw content
@@ -168,16 +174,18 @@ changes = {
- sub enhancement 1
- sub enhancement 2
- Enhancement 2 (1.1.0)""",
- "release_date": "2018-05-31",
- "version": "1.1.0",
- "semantic_version": {
- "major": 1,
- "minor": 1,
- "patch": 0,
- "prerelease": None,
- "buildmetadata": None,
+ "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",
},
- "url": "https://github.test_url/test_project/compare/v1.0.1...v1.1.0",
},
"1.0.1": {
"raw": """### Fixed
@@ -185,31 +193,35 @@ changes = {
- sub bug 1
- sub bug 2
- Bug fix 2 (1.0.1)""",
- "release_date": "2018-05-31",
- "version": "1.0.1",
- "semantic_version": {
- "major": 1,
- "minor": 0,
- "patch": 1,
- "prerelease": None,
- "buildmetadata": None,
+ "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",
},
- "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)""",
- "release_date": "2017-04-10",
- "version": "1.0.0",
- "semantic_version": {
- "major": 1,
- "minor": 0,
- "patch": 0,
- "prerelease": None,
- "buildmetadata": None,
+ "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",
},
- "url": "https://github.test_url/test_project/releases/tag/v1.0.0",
},
}
```
diff --git a/keepachangelog/_changelog.py b/keepachangelog/_changelog.py
index e029841..51a92dd 100644
--- a/keepachangelog/_changelog.py
+++ b/keepachangelog/_changelog.py
@@ -25,13 +25,13 @@ def add_release(changes: Dict[str, dict], line: str) -> dict:
)
version = unlink(version)
- release_details = {"version": version, "release_date": extract_date(release_date)}
+ metadata = {"version": version, "release_date": extract_date(release_date)}
try:
- release_details["semantic_version"] = to_semantic(version)
+ metadata["semantic_version"] = to_semantic(version)
except InvalidSemanticVersion:
pass
- return changes.setdefault(version, release_details)
+ return changes.setdefault(version, {"metadata": metadata})
def unlink(value: str) -> str:
@@ -106,16 +106,19 @@ def _to_dict(change_log: Iterable[str], show_unreleased: bool) -> Dict[str, dict
# Add url for each version (create version if not existing)
for version, url in urls.items():
- changes.setdefault(version, {"version": version})["url"] = url
+ changes.setdefault(version, {"metadata": {"version": version}})["metadata"][
+ "url"
+ ] = url
# Avoid empty uncategorized
unreleased_version = None
for version, current_release in changes.items():
+ metadata = current_release["metadata"]
if not current_release.get("uncategorized"):
current_release.pop("uncategorized", None)
# If there is an empty release date, it identify the unreleased section
- if ("release_date" in current_release) and not current_release["release_date"]:
+ if ("release_date" in metadata) and not metadata["release_date"]:
unreleased_version = version
if not show_unreleased:
@@ -132,10 +135,11 @@ def from_dict(changes: Dict[str, dict]):
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).\n"""
for current_release in changes.values():
- content += f"\n## [{current_release['version'].capitalize()}]"
+ metadata = current_release["metadata"]
+ content += f"\n## [{metadata['version'].capitalize()}]"
- if current_release.get("release_date"):
- content += f" - {current_release['release_date']}"
+ if metadata.get("release_date"):
+ content += f" - {metadata['release_date']}"
uncategorized = current_release.get("uncategorized", [])
for category_content in uncategorized:
@@ -144,13 +148,7 @@ def from_dict(changes: Dict[str, dict]):
content += "\n"
for category_name, category_content in current_release.items():
- if category_name in [
- "version",
- "release_date",
- "uncategorized",
- "semantic_version",
- "url",
- ]:
+ if category_name in ["metadata", "uncategorized"]:
continue
content += f"\n### {category_name.capitalize()}"
@@ -163,12 +161,11 @@ def from_dict(changes: Dict[str, dict]):
content += "\n"
for current_release in changes.values():
- if not current_release.get("url"):
+ metadata = current_release["metadata"]
+ if not metadata.get("url"):
continue
- content += (
- f"[{current_release['version'].capitalize()}]: {current_release['url']}\n"
- )
+ content += f"[{metadata['version'].capitalize()}]: {metadata['url']}\n"
return content
@@ -192,12 +189,15 @@ def to_raw_dict(changelog_path: str) -> Dict[str, dict]:
# Add url for each version (create version if not existing)
for version, url in urls.items():
- changes.setdefault(version, {"version": version})["url"] = url
+ changes.setdefault(version, {"metadata": {"version": version}})["metadata"][
+ "url"
+ ] = url
unreleased_version = None
for version, current_release in changes.items():
+ metadata = current_release["metadata"]
# If there is an empty release date, it identify the unreleased section
- if ("release_date" in current_release) and not current_release["release_date"]:
+ if ("release_date" in metadata) and not metadata["release_date"]:
unreleased_version = version
changes.pop(unreleased_version, None)
diff --git a/keepachangelog/_versioning.py b/keepachangelog/_versioning.py
index 216e426..b01e90f 100644
--- a/keepachangelog/_versioning.py
+++ b/keepachangelog/_versioning.py
@@ -85,9 +85,7 @@ def guess_unreleased_version(changelog: dict, current_semantic_version: dict) ->
unreleased = changelog.get("unreleased", {})
# Only keep user provided entries
unreleased = unreleased.copy()
- unreleased.pop("version", None)
- unreleased.pop("release_date", None)
- unreleased.pop("url", None)
+ unreleased.pop("metadata", None)
if not unreleased:
raise Exception(
"Release content must be provided within changelog Unreleased section."
diff --git a/keepachangelog/flask_restx.py b/keepachangelog/flask_restx.py
index 3e2710c..a718d64 100644
--- a/keepachangelog/flask_restx.py
+++ b/keepachangelog/flask_restx.py
@@ -25,15 +25,20 @@ def add_changelog_endpoint(
namespace.model(
"ChangelogReleaseModel",
{
- "version": flask_restx.fields.String(
- description="Release version following semantic versioning.",
- required=True,
- example="3.12.5",
- ),
- "release_date": flask_restx.fields.Date(
- description="Release date.",
- required=True,
- example="2019-12-31",
+ "metadata": namespace.model(
+ "ChangelogReleaseMetaDataModel",
+ {
+ "version": flask_restx.fields.String(
+ description="Release version following semantic versioning.",
+ required=True,
+ example="3.12.5",
+ ),
+ "release_date": flask_restx.fields.Date(
+ description="Release date.",
+ required=True,
+ example="2019-12-31",
+ ),
+ },
),
"added": flask_restx.fields.List(
flask_restx.fields.String(description="New features.")
diff --git a/setup.py b/setup.py
index 3d7ac26..17deebe 100644
--- a/setup.py
+++ b/setup.py
@@ -39,11 +39,10 @@
extras_require={
"testing": [
# Used to check starlette endpoint
- "requests",
+ "requests==2.*",
"starlette==0.13.*",
# Used to check flask-restx endpoint
- "flask==1.*",
- "flask-restx==0.2.*",
+ "flask-restx==0.4.*",
# Used to check coverage
"pytest-cov==2.*",
]
diff --git a/tests/test_changelog.py b/tests/test_changelog.py
index fc9d28d..961be91 100644
--- a/tests/test_changelog.py
+++ b/tests/test_changelog.py
@@ -89,16 +89,18 @@ def changelog(tmpdir):
"changed": ["Release note 1.", "Release note 2."],
"deprecated": ["Deprecated feature 1", "Future removal 2"],
"fixed": ["Bug fix 1", "sub bug 1", "sub bug 2", "Bug fix 2"],
- "release_date": "2018-06-01",
"removed": ["Deprecated feature 2", "Future removal 1"],
"security": ["Known issue 1", "Known issue 2"],
- "version": "1.2.0",
- "semantic_version": {
- "buildmetadata": None,
- "major": 1,
- "minor": 2,
- "patch": 0,
- "prerelease": None,
+ "metadata": {
+ "release_date": "2018-06-01",
+ "version": "1.2.0",
+ "semantic_version": {
+ "buildmetadata": None,
+ "major": 1,
+ "minor": 2,
+ "patch": 0,
+ "prerelease": None,
+ },
},
},
"1.1.0": {
@@ -108,20 +110,24 @@ def changelog(tmpdir):
"sub enhancement 2",
"Enhancement 2 (1.1.0)",
],
- "release_date": "2018-05-31",
- "version": "1.1.0",
- "semantic_version": {
- "buildmetadata": None,
- "major": 1,
- "minor": 1,
- "patch": 0,
- "prerelease": None,
+ "metadata": {
+ "release_date": "2018-05-31",
+ "version": "1.1.0",
+ "semantic_version": {
+ "buildmetadata": None,
+ "major": 1,
+ "minor": 1,
+ "patch": 0,
+ "prerelease": None,
+ },
+ "url": "https://github.test_url/test_project/compare/v1.0.2...v1.1.0",
},
- "url": "https://github.test_url/test_project/compare/v1.0.2...v1.1.0",
},
"1.0.2": {
- "version": "1.0.2",
- "url": "https://github.test_url/test_project/compare/v1.0.1...v1.0.2",
+ "metadata": {
+ "version": "1.0.2",
+ "url": "https://github.test_url/test_project/compare/v1.0.1...v1.0.2",
+ }
},
"1.0.1": {
"fixed": [
@@ -130,29 +136,33 @@ def changelog(tmpdir):
"sub bug 2",
"Bug fix 2 (1.0.1)",
],
- "release_date": "2018-05-31",
- "version": "1.0.1",
- "semantic_version": {
- "buildmetadata": None,
- "major": 1,
- "minor": 0,
- "patch": 1,
- "prerelease": None,
+ "metadata": {
+ "release_date": "2018-05-31",
+ "version": "1.0.1",
+ "semantic_version": {
+ "buildmetadata": None,
+ "major": 1,
+ "minor": 0,
+ "patch": 1,
+ "prerelease": None,
+ },
+ "url": "https://github.test_url/test_project/compare/v1.0.0...v1.0.1",
},
- "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)"],
- "release_date": "2017-04-10",
- "version": "1.0.0",
- "semantic_version": {
- "buildmetadata": None,
- "major": 1,
- "minor": 0,
- "patch": 0,
- "prerelease": None,
+ "metadata": {
+ "release_date": "2017-04-10",
+ "version": "1.0.0",
+ "semantic_version": {
+ "buildmetadata": None,
+ "major": 1,
+ "minor": 0,
+ "patch": 0,
+ "prerelease": None,
+ },
+ "url": "https://github.test_url/test_project/releases/tag/v1.0.0",
},
- "url": "https://github.test_url/test_project/releases/tag/v1.0.0",
},
}
@@ -196,14 +206,16 @@ def test_raw_changelog_with_versions_and_all_categories(changelog):
- Deprecated feature 2
- Future removal 1
""",
- "release_date": "2018-06-01",
- "version": "1.2.0",
- "semantic_version": {
- "buildmetadata": None,
- "major": 1,
- "minor": 2,
- "patch": 0,
- "prerelease": None,
+ "metadata": {
+ "release_date": "2018-06-01",
+ "version": "1.2.0",
+ "semantic_version": {
+ "buildmetadata": None,
+ "major": 1,
+ "minor": 2,
+ "patch": 0,
+ "prerelease": None,
+ },
},
},
"1.1.0": {
@@ -213,20 +225,24 @@ def test_raw_changelog_with_versions_and_all_categories(changelog):
- sub enhancement 2
- Enhancement 2 (1.1.0)
""",
- "release_date": "2018-05-31",
- "version": "1.1.0",
- "semantic_version": {
- "buildmetadata": None,
- "major": 1,
- "minor": 1,
- "patch": 0,
- "prerelease": None,
+ "metadata": {
+ "release_date": "2018-05-31",
+ "version": "1.1.0",
+ "semantic_version": {
+ "buildmetadata": None,
+ "major": 1,
+ "minor": 1,
+ "patch": 0,
+ "prerelease": None,
+ },
+ "url": "https://github.test_url/test_project/compare/v1.0.2...v1.1.0",
},
- "url": "https://github.test_url/test_project/compare/v1.0.2...v1.1.0",
},
"1.0.2": {
- "version": "1.0.2",
- "url": "https://github.test_url/test_project/compare/v1.0.1...v1.0.2",
+ "metadata": {
+ "version": "1.0.2",
+ "url": "https://github.test_url/test_project/compare/v1.0.1...v1.0.2",
+ },
},
"1.0.1": {
"raw": """### Fixed
@@ -235,31 +251,35 @@ def test_raw_changelog_with_versions_and_all_categories(changelog):
- sub bug 2
- Bug fix 2 (1.0.1)
""",
- "release_date": "2018-05-31",
- "version": "1.0.1",
- "semantic_version": {
- "buildmetadata": None,
- "major": 1,
- "minor": 0,
- "patch": 1,
- "prerelease": None,
+ "metadata": {
+ "release_date": "2018-05-31",
+ "version": "1.0.1",
+ "semantic_version": {
+ "buildmetadata": None,
+ "major": 1,
+ "minor": 0,
+ "patch": 1,
+ "prerelease": None,
+ },
+ "url": "https://github.test_url/test_project/compare/v1.0.0...v1.0.1",
},
- "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)
""",
- "release_date": "2017-04-10",
- "version": "1.0.0",
- "semantic_version": {
- "buildmetadata": None,
- "major": 1,
- "minor": 0,
- "patch": 0,
- "prerelease": None,
+ "metadata": {
+ "release_date": "2017-04-10",
+ "version": "1.0.0",
+ "semantic_version": {
+ "buildmetadata": None,
+ "major": 1,
+ "minor": 0,
+ "patch": 0,
+ "prerelease": None,
+ },
+ "url": "https://github.test_url/test_project/releases/tag/v1.0.0",
},
- "url": "https://github.test_url/test_project/releases/tag/v1.0.0",
},
}
diff --git a/tests/test_changelog_empty_version.py b/tests/test_changelog_empty_version.py
index 43845c8..b2dc644 100644
--- a/tests/test_changelog_empty_version.py
+++ b/tests/test_changelog_empty_version.py
@@ -52,16 +52,18 @@ def test_changelog_with_empty_version(changelog):
"changed": ["Release note 1.", "Release note 2."],
"deprecated": ["Deprecated feature 1", "Future removal 2"],
"fixed": ["Bug fix 1", "sub bug 1", "sub bug 2", "Bug fix 2"],
- "release_date": "2018-06-01",
"removed": ["Deprecated feature 2", "Future removal 1"],
"security": ["Known issue 1", "Known issue 2"],
- "version": "",
- "semantic_version": {
- "buildmetadata": None,
- "major": 0,
- "minor": 0,
- "patch": 0,
- "prerelease": None,
+ "metadata": {
+ "release_date": "2018-06-01",
+ "version": "",
+ "semantic_version": {
+ "buildmetadata": None,
+ "major": 0,
+ "minor": 0,
+ "patch": 0,
+ "prerelease": None,
+ },
},
},
}
diff --git a/tests/test_changelog_no_added.py b/tests/test_changelog_no_added.py
index 32d6d03..271dfcb 100644
--- a/tests/test_changelog_no_added.py
+++ b/tests/test_changelog_no_added.py
@@ -71,16 +71,18 @@ def test_changelog_with_versions_and_no_added(changelog):
"changed": ["Release note 1.", "Release note 2."],
"deprecated": ["Deprecated feature 1", "Future removal 2"],
"fixed": ["Bug fix 1", "sub bug 1", "sub bug 2", "Bug fix 2"],
- "release_date": "2018-06-01",
"removed": ["Deprecated feature 2", "Future removal 1"],
"security": ["Known issue 1", "Known issue 2"],
- "version": "1.2.0",
- "semantic_version": {
- "buildmetadata": None,
- "major": 1,
- "minor": 2,
- "patch": 0,
- "prerelease": None,
+ "metadata": {
+ "release_date": "2018-06-01",
+ "version": "1.2.0",
+ "semantic_version": {
+ "buildmetadata": None,
+ "major": 1,
+ "minor": 2,
+ "patch": 0,
+ "prerelease": None,
+ },
},
},
"1.1.0": {
@@ -90,14 +92,16 @@ def test_changelog_with_versions_and_no_added(changelog):
"sub enhancement 2",
"Enhancement 2 (1.1.0)",
],
- "release_date": "2018-05-31",
- "version": "1.1.0",
- "semantic_version": {
- "buildmetadata": None,
- "major": 1,
- "minor": 1,
- "patch": 0,
- "prerelease": None,
+ "metadata": {
+ "release_date": "2018-05-31",
+ "version": "1.1.0",
+ "semantic_version": {
+ "buildmetadata": None,
+ "major": 1,
+ "minor": 1,
+ "patch": 0,
+ "prerelease": None,
+ },
},
},
"1.0.1": {
@@ -107,26 +111,30 @@ def test_changelog_with_versions_and_no_added(changelog):
"sub bug 2",
"Bug fix 2 (1.0.1)",
],
- "release_date": "2018-05-31",
- "version": "1.0.1",
- "semantic_version": {
- "buildmetadata": None,
- "major": 1,
- "minor": 0,
- "patch": 1,
- "prerelease": None,
+ "metadata": {
+ "release_date": "2018-05-31",
+ "version": "1.0.1",
+ "semantic_version": {
+ "buildmetadata": None,
+ "major": 1,
+ "minor": 0,
+ "patch": 1,
+ "prerelease": None,
+ },
},
},
"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",
- "semantic_version": {
- "buildmetadata": None,
- "major": 1,
- "minor": 0,
- "patch": 0,
- "prerelease": None,
+ "metadata": {
+ "release_date": "2017-04-10",
+ "version": "1.0.0",
+ "semantic_version": {
+ "buildmetadata": None,
+ "major": 1,
+ "minor": 0,
+ "patch": 0,
+ "prerelease": None,
+ },
},
},
}
diff --git a/tests/test_changelog_no_category.py b/tests/test_changelog_no_category.py
index 321b7bc..3ac2667 100644
--- a/tests/test_changelog_no_category.py
+++ b/tests/test_changelog_no_category.py
@@ -50,14 +50,16 @@ def test_changelog_without_category(changelog):
"1.2.0": {
"uncategorized": ["Release note 1.", "Release note 2."],
"fixed": ["Bug fix 1", "sub bug 1", "sub bug 2", "Bug fix 2"],
- "release_date": "2018-06-01",
- "version": "1.2.0",
- "semantic_version": {
- "buildmetadata": None,
- "major": 1,
- "minor": 2,
- "patch": 0,
- "prerelease": None,
+ "metadata": {
+ "release_date": "2018-06-01",
+ "version": "1.2.0",
+ "semantic_version": {
+ "buildmetadata": None,
+ "major": 1,
+ "minor": 2,
+ "patch": 0,
+ "prerelease": None,
+ },
},
},
"1.1.0": {
@@ -67,14 +69,16 @@ def test_changelog_without_category(changelog):
"sub enhancement 2",
"Enhancement 2 (1.1.0)",
],
- "release_date": "2018-05-31",
- "version": "1.1.0",
- "semantic_version": {
- "buildmetadata": None,
- "major": 1,
- "minor": 1,
- "patch": 0,
- "prerelease": None,
+ "metadata": {
+ "release_date": "2018-05-31",
+ "version": "1.1.0",
+ "semantic_version": {
+ "buildmetadata": None,
+ "major": 1,
+ "minor": 1,
+ "patch": 0,
+ "prerelease": None,
+ },
},
},
"1.0.1": {
@@ -84,14 +88,16 @@ def test_changelog_without_category(changelog):
"sub bug 2",
"Bug fix 2 (1.0.1)",
],
- "release_date": "2018-05-31",
- "version": "1.0.1",
- "semantic_version": {
- "buildmetadata": None,
- "major": 1,
- "minor": 0,
- "patch": 1,
- "prerelease": None,
+ "metadata": {
+ "release_date": "2018-05-31",
+ "version": "1.0.1",
+ "semantic_version": {
+ "buildmetadata": None,
+ "major": 1,
+ "minor": 0,
+ "patch": 1,
+ "prerelease": None,
+ },
},
},
}
diff --git a/tests/test_changelog_no_changed.py b/tests/test_changelog_no_changed.py
index 242363f..4bf6550 100644
--- a/tests/test_changelog_no_changed.py
+++ b/tests/test_changelog_no_changed.py
@@ -73,27 +73,31 @@ def test_changelog_with_versions_and_no_changed(changelog):
],
"deprecated": ["Deprecated feature 1", "Future removal 2"],
"fixed": ["Bug fix 1", "sub bug 1", "sub bug 2", "Bug fix 2"],
- "release_date": "2018-06-01",
"removed": ["Deprecated feature 2", "Future removal 1"],
"security": ["Known issue 1", "Known issue 2"],
- "version": "1.2.0",
- "semantic_version": {
- "buildmetadata": None,
- "major": 1,
- "minor": 2,
- "patch": 0,
- "prerelease": None,
+ "metadata": {
+ "release_date": "2018-06-01",
+ "version": "1.2.0",
+ "semantic_version": {
+ "buildmetadata": None,
+ "major": 1,
+ "minor": 2,
+ "patch": 0,
+ "prerelease": None,
+ },
},
},
"1.1.0": {
- "release_date": "2018-05-31",
- "version": "1.1.0",
- "semantic_version": {
- "buildmetadata": None,
- "major": 1,
- "minor": 1,
- "patch": 0,
- "prerelease": None,
+ "metadata": {
+ "release_date": "2018-05-31",
+ "version": "1.1.0",
+ "semantic_version": {
+ "buildmetadata": None,
+ "major": 1,
+ "minor": 1,
+ "patch": 0,
+ "prerelease": None,
+ },
},
},
"1.0.1": {
@@ -103,26 +107,30 @@ def test_changelog_with_versions_and_no_changed(changelog):
"sub bug 2",
"Bug fix 2 (1.0.1)",
],
- "release_date": "2018-05-31",
- "version": "1.0.1",
- "semantic_version": {
- "buildmetadata": None,
- "major": 1,
- "minor": 0,
- "patch": 1,
- "prerelease": None,
+ "metadata": {
+ "release_date": "2018-05-31",
+ "version": "1.0.1",
+ "semantic_version": {
+ "buildmetadata": None,
+ "major": 1,
+ "minor": 0,
+ "patch": 1,
+ "prerelease": None,
+ },
},
},
"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",
- "semantic_version": {
- "buildmetadata": None,
- "major": 1,
- "minor": 0,
- "patch": 0,
- "prerelease": None,
+ "metadata": {
+ "release_date": "2017-04-10",
+ "version": "1.0.0",
+ "semantic_version": {
+ "buildmetadata": None,
+ "major": 1,
+ "minor": 0,
+ "patch": 0,
+ "prerelease": None,
+ },
},
},
}
diff --git a/tests/test_changelog_no_deprecated.py b/tests/test_changelog_no_deprecated.py
index cc70e0a..cfaa9e9 100644
--- a/tests/test_changelog_no_deprecated.py
+++ b/tests/test_changelog_no_deprecated.py
@@ -75,16 +75,18 @@ def test_changelog_with_versions_and_no_deprecated(changelog):
],
"changed": ["Release note 1.", "Release note 2."],
"fixed": ["Bug fix 1", "sub bug 1", "sub bug 2", "Bug fix 2"],
- "release_date": "2018-06-01",
"removed": ["Deprecated feature 2", "Future removal 1"],
"security": ["Known issue 1", "Known issue 2"],
- "version": "1.2.0",
- "semantic_version": {
- "buildmetadata": None,
- "major": 1,
- "minor": 2,
- "patch": 0,
- "prerelease": None,
+ "metadata": {
+ "release_date": "2018-06-01",
+ "version": "1.2.0",
+ "semantic_version": {
+ "buildmetadata": None,
+ "major": 1,
+ "minor": 2,
+ "patch": 0,
+ "prerelease": None,
+ },
},
},
"1.1.0": {
@@ -94,14 +96,16 @@ def test_changelog_with_versions_and_no_deprecated(changelog):
"sub enhancement 2",
"Enhancement 2 (1.1.0)",
],
- "release_date": "2018-05-31",
- "version": "1.1.0",
- "semantic_version": {
- "buildmetadata": None,
- "major": 1,
- "minor": 1,
- "patch": 0,
- "prerelease": None,
+ "metadata": {
+ "release_date": "2018-05-31",
+ "version": "1.1.0",
+ "semantic_version": {
+ "buildmetadata": None,
+ "major": 1,
+ "minor": 1,
+ "patch": 0,
+ "prerelease": None,
+ },
},
},
"1.0.1": {
@@ -111,25 +115,29 @@ def test_changelog_with_versions_and_no_deprecated(changelog):
"sub bug 2",
"Bug fix 2 (1.0.1)",
],
- "release_date": "2018-05-31",
- "version": "1.0.1",
- "semantic_version": {
- "buildmetadata": None,
- "major": 1,
- "minor": 0,
- "patch": 1,
- "prerelease": None,
+ "metadata": {
+ "release_date": "2018-05-31",
+ "version": "1.0.1",
+ "semantic_version": {
+ "buildmetadata": None,
+ "major": 1,
+ "minor": 0,
+ "patch": 1,
+ "prerelease": None,
+ },
},
},
"1.0.0": {
- "release_date": "2017-04-10",
- "version": "1.0.0",
- "semantic_version": {
- "buildmetadata": None,
- "major": 1,
- "minor": 0,
- "patch": 0,
- "prerelease": None,
+ "metadata": {
+ "release_date": "2017-04-10",
+ "version": "1.0.0",
+ "semantic_version": {
+ "buildmetadata": None,
+ "major": 1,
+ "minor": 0,
+ "patch": 0,
+ "prerelease": None,
+ },
},
},
}
diff --git a/tests/test_changelog_no_fixed.py b/tests/test_changelog_no_fixed.py
index ecde986..2f1fa93 100644
--- a/tests/test_changelog_no_fixed.py
+++ b/tests/test_changelog_no_fixed.py
@@ -76,16 +76,18 @@ def test_changelog_with_versions_and_no_fixed(changelog):
],
"changed": ["Release note 1.", "Release note 2."],
"deprecated": ["Deprecated feature 1", "Future removal 2"],
- "release_date": "2018-06-01",
"removed": ["Deprecated feature 2", "Future removal 1"],
"security": ["Known issue 1", "Known issue 2"],
- "version": "1.2.0",
- "semantic_version": {
- "buildmetadata": None,
- "major": 1,
- "minor": 2,
- "patch": 0,
- "prerelease": None,
+ "metadata": {
+ "release_date": "2018-06-01",
+ "version": "1.2.0",
+ "semantic_version": {
+ "buildmetadata": None,
+ "major": 1,
+ "minor": 2,
+ "patch": 0,
+ "prerelease": None,
+ },
},
},
"1.1.0": {
@@ -95,14 +97,16 @@ def test_changelog_with_versions_and_no_fixed(changelog):
"sub enhancement 2",
"Enhancement 2 (1.1.0)",
],
- "release_date": "2018-05-31",
- "version": "1.1.0",
- "semantic_version": {
- "buildmetadata": None,
- "major": 1,
- "minor": 1,
- "patch": 0,
- "prerelease": None,
+ "metadata": {
+ "release_date": "2018-05-31",
+ "version": "1.1.0",
+ "semantic_version": {
+ "buildmetadata": None,
+ "major": 1,
+ "minor": 1,
+ "patch": 0,
+ "prerelease": None,
+ },
},
},
"1.0.1": {
@@ -112,26 +116,30 @@ def test_changelog_with_versions_and_no_fixed(changelog):
"sub bug 2",
"Bug fix 2 (1.0.1)",
],
- "release_date": "2018-05-31",
- "version": "1.0.1",
- "semantic_version": {
- "buildmetadata": None,
- "major": 1,
- "minor": 0,
- "patch": 1,
- "prerelease": None,
+ "metadata": {
+ "release_date": "2018-05-31",
+ "version": "1.0.1",
+ "semantic_version": {
+ "buildmetadata": None,
+ "major": 1,
+ "minor": 0,
+ "patch": 1,
+ "prerelease": None,
+ },
},
},
"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",
- "semantic_version": {
- "buildmetadata": None,
- "major": 1,
- "minor": 0,
- "patch": 0,
- "prerelease": None,
+ "metadata": {
+ "release_date": "2017-04-10",
+ "version": "1.0.0",
+ "semantic_version": {
+ "buildmetadata": None,
+ "major": 1,
+ "minor": 0,
+ "patch": 0,
+ "prerelease": None,
+ },
},
},
}
diff --git a/tests/test_changelog_no_removed.py b/tests/test_changelog_no_removed.py
index 18de621..be1fde1 100644
--- a/tests/test_changelog_no_removed.py
+++ b/tests/test_changelog_no_removed.py
@@ -79,15 +79,17 @@ def test_changelog_with_versions_and_no_removed(changelog):
"changed": ["Release note 1.", "Release note 2."],
"deprecated": ["Deprecated feature 1", "Future removal 2"],
"fixed": ["Bug fix 1", "sub bug 1", "sub bug 2", "Bug fix 2"],
- "release_date": "2018-06-01",
"security": ["Known issue 1", "Known issue 2"],
- "version": "1.2.0",
- "semantic_version": {
- "buildmetadata": None,
- "major": 1,
- "minor": 2,
- "patch": 0,
- "prerelease": None,
+ "metadata": {
+ "release_date": "2018-06-01",
+ "version": "1.2.0",
+ "semantic_version": {
+ "buildmetadata": None,
+ "major": 1,
+ "minor": 2,
+ "patch": 0,
+ "prerelease": None,
+ },
},
},
"1.1.0": {
@@ -97,14 +99,16 @@ def test_changelog_with_versions_and_no_removed(changelog):
"sub enhancement 2",
"Enhancement 2 (1.1.0)",
],
- "release_date": "2018-05-31",
- "version": "1.1.0",
- "semantic_version": {
- "buildmetadata": None,
- "major": 1,
- "minor": 1,
- "patch": 0,
- "prerelease": None,
+ "metadata": {
+ "release_date": "2018-05-31",
+ "version": "1.1.0",
+ "semantic_version": {
+ "buildmetadata": None,
+ "major": 1,
+ "minor": 1,
+ "patch": 0,
+ "prerelease": None,
+ },
},
},
"1.0.1": {
@@ -114,26 +118,30 @@ def test_changelog_with_versions_and_no_removed(changelog):
"sub bug 2",
"Bug fix 2 (1.0.1)",
],
- "release_date": "2018-05-31",
- "version": "1.0.1",
- "semantic_version": {
- "buildmetadata": None,
- "major": 1,
- "minor": 0,
- "patch": 1,
- "prerelease": None,
+ "metadata": {
+ "release_date": "2018-05-31",
+ "version": "1.0.1",
+ "semantic_version": {
+ "buildmetadata": None,
+ "major": 1,
+ "minor": 0,
+ "patch": 1,
+ "prerelease": None,
+ },
},
},
"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",
- "semantic_version": {
- "buildmetadata": None,
- "major": 1,
- "minor": 0,
- "patch": 0,
- "prerelease": None,
+ "metadata": {
+ "release_date": "2017-04-10",
+ "version": "1.0.0",
+ "semantic_version": {
+ "buildmetadata": None,
+ "major": 1,
+ "minor": 0,
+ "patch": 0,
+ "prerelease": None,
+ },
},
},
}
diff --git a/tests/test_changelog_no_security.py b/tests/test_changelog_no_security.py
index 1ddd0e8..1fc21d3 100644
--- a/tests/test_changelog_no_security.py
+++ b/tests/test_changelog_no_security.py
@@ -79,15 +79,17 @@ def test_changelog_with_versions_and_no_security(changelog):
"changed": ["Release note 1.", "Release note 2."],
"deprecated": ["Deprecated feature 1", "Future removal 2"],
"fixed": ["Bug fix 1", "sub bug 1", "sub bug 2", "Bug fix 2"],
- "release_date": "2018-06-01",
"removed": ["Deprecated feature 2", "Future removal 1"],
- "version": "1.2.0",
- "semantic_version": {
- "buildmetadata": None,
- "major": 1,
- "minor": 2,
- "patch": 0,
- "prerelease": None,
+ "metadata": {
+ "release_date": "2018-06-01",
+ "version": "1.2.0",
+ "semantic_version": {
+ "buildmetadata": None,
+ "major": 1,
+ "minor": 2,
+ "patch": 0,
+ "prerelease": None,
+ },
},
},
"1.1.0": {
@@ -97,14 +99,16 @@ def test_changelog_with_versions_and_no_security(changelog):
"sub enhancement 2",
"Enhancement 2 (1.1.0)",
],
- "release_date": "2018-05-31",
- "version": "1.1.0",
- "semantic_version": {
- "buildmetadata": None,
- "major": 1,
- "minor": 1,
- "patch": 0,
- "prerelease": None,
+ "metadata": {
+ "release_date": "2018-05-31",
+ "version": "1.1.0",
+ "semantic_version": {
+ "buildmetadata": None,
+ "major": 1,
+ "minor": 1,
+ "patch": 0,
+ "prerelease": None,
+ },
},
},
"1.0.1": {
@@ -114,26 +118,30 @@ def test_changelog_with_versions_and_no_security(changelog):
"sub bug 2",
"Bug fix 2 (1.0.1)",
],
- "release_date": "2018-05-31",
- "version": "1.0.1",
- "semantic_version": {
- "buildmetadata": None,
- "major": 1,
- "minor": 0,
- "patch": 1,
- "prerelease": None,
+ "metadata": {
+ "release_date": "2018-05-31",
+ "version": "1.0.1",
+ "semantic_version": {
+ "buildmetadata": None,
+ "major": 1,
+ "minor": 0,
+ "patch": 1,
+ "prerelease": None,
+ },
},
},
"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",
- "semantic_version": {
- "buildmetadata": None,
- "major": 1,
- "minor": 0,
- "patch": 0,
- "prerelease": None,
+ "metadata": {
+ "release_date": "2017-04-10",
+ "version": "1.0.0",
+ "semantic_version": {
+ "buildmetadata": None,
+ "major": 1,
+ "minor": 0,
+ "patch": 0,
+ "prerelease": None,
+ },
},
},
}
diff --git a/tests/test_changelog_unreleased.py b/tests/test_changelog_unreleased.py
index a6d6aa4..4f2044c 100644
--- a/tests/test_changelog_unreleased.py
+++ b/tests/test_changelog_unreleased.py
@@ -83,8 +83,6 @@ def changelog(tmpdir):
def test_changelog_with_versions_and_all_categories(changelog):
assert keepachangelog.to_dict(changelog, show_unreleased=True) == {
"unreleased": {
- "version": "unreleased",
- "release_date": None,
"changed": ["Release note 1.", "Release note 2."],
"added": [
"Enhancement 1",
@@ -97,72 +95,86 @@ def test_changelog_with_versions_and_all_categories(changelog):
"uncategorized": ["Release note 0."],
"deprecated": ["Deprecated feature 1", "Future removal 2"],
"removed": ["Deprecated feature 2", "Future removal 1"],
- "url": "https://github.test_url/test_project/compare/v1.1.0...HEAD",
+ "metadata": {
+ "version": "unreleased",
+ "release_date": None,
+ "url": "https://github.test_url/test_project/compare/v1.1.0...HEAD",
+ },
},
"1.1.0": {
- "version": "1.1.0",
- "semantic_version": {
- "buildmetadata": None,
- "major": 1,
- "minor": 1,
- "patch": 0,
- "prerelease": None,
- },
- "release_date": "2018-05-31",
"changed": [
"Enhancement 1 (1.1.0)",
"sub *enhancement 1*",
"sub enhancement 2",
"Enhancement 2 (1.1.0)",
],
- "url": "https://github.test_url/test_project/compare/v1.0.2...v1.1.0",
+ "metadata": {
+ "version": "1.1.0",
+ "semantic_version": {
+ "buildmetadata": None,
+ "major": 1,
+ "minor": 1,
+ "patch": 0,
+ "prerelease": None,
+ },
+ "release_date": "2018-05-31",
+ "url": "https://github.test_url/test_project/compare/v1.0.2...v1.1.0",
+ },
},
"1.0.2": {
- "url": "https://github.test_url/test_project/compare/v1.0.1...v1.0.2",
- "version": "1.0.2",
+ "metadata": {
+ "url": "https://github.test_url/test_project/compare/v1.0.1...v1.0.2",
+ "version": "1.0.2",
+ },
},
"1.0.1": {
- "version": "1.0.1",
- "semantic_version": {
- "buildmetadata": None,
- "major": 1,
- "minor": 0,
- "patch": 1,
- "prerelease": None,
- },
- "release_date": "2018-05-31",
"fixed": [
"Bug fix 1 (1.0.1)",
"sub bug 1",
"sub bug 2",
"Bug fix 2 (1.0.1)",
],
- "url": "https://github.test_url/test_project/compare/v1.0.0...v1.0.1",
+ "metadata": {
+ "version": "1.0.1",
+ "semantic_version": {
+ "buildmetadata": None,
+ "major": 1,
+ "minor": 0,
+ "patch": 1,
+ "prerelease": None,
+ },
+ "release_date": "2018-05-31",
+ "url": "https://github.test_url/test_project/compare/v1.0.0...v1.0.1",
+ },
},
"1.0.0": {
- "version": "1.0.0",
- "semantic_version": {
- "buildmetadata": None,
- "major": 1,
- "minor": 0,
- "patch": 0,
- "prerelease": None,
- },
- "release_date": "2017-04-10",
"deprecated": ["Known issue 1 (1.0.0)", "Known issue 2 (1.0.0)"],
- "url": "https://github.test_url/test_project/releases/tag/v1.0.0",
+ "metadata": {
+ "version": "1.0.0",
+ "semantic_version": {
+ "buildmetadata": None,
+ "major": 1,
+ "minor": 0,
+ "patch": 0,
+ "prerelease": None,
+ },
+ "release_date": "2017-04-10",
+ "url": "https://github.test_url/test_project/releases/tag/v1.0.0",
+ },
},
"0.0.1": {
"added": ["First release"],
- "release_date": "2017-01-01",
- "semantic_version": {
- "buildmetadata": None,
- "major": 0,
- "minor": 0,
- "patch": 1,
- "prerelease": None,
+ "metadata": {
+ "release_date": "2017-01-01",
+ "semantic_version": {
+ "buildmetadata": None,
+ "major": 0,
+ "minor": 0,
+ "patch": 1,
+ "prerelease": None,
+ },
+ "version": "0.0.1",
},
- "version": "0.0.1",
},
}
diff --git a/tests/test_flask_restx.py b/tests/test_flask_restx.py
index 1a042fb..06a7e57 100644
--- a/tests/test_flask_restx.py
+++ b/tests/test_flask_restx.py
@@ -85,16 +85,18 @@ def test_changelog_endpoint_with_file(tmpdir):
"sub enhancement 2",
"Enhancement 2 (1.1.0)",
],
- "release_date": "2018-05-31",
- "version": "1.1.0",
- "semantic_version": {
- "buildmetadata": None,
- "major": 1,
- "minor": 1,
- "patch": 0,
- "prerelease": None,
+ "metadata": {
+ "release_date": "2018-05-31",
+ "version": "1.1.0",
+ "semantic_version": {
+ "buildmetadata": None,
+ "major": 1,
+ "minor": 1,
+ "patch": 0,
+ "prerelease": None,
+ },
+ "url": "https://github.test_url/test_project/compare/v1.0.1...v1.1.0",
},
- "url": "https://github.test_url/test_project/compare/v1.0.1...v1.1.0",
},
"1.0.1": {
"fixed": [
@@ -103,29 +105,33 @@ def test_changelog_endpoint_with_file(tmpdir):
"sub bug 2",
"Bug fix 2 (1.0.1)",
],
- "release_date": "2018-05-31",
- "version": "1.0.1",
- "semantic_version": {
- "buildmetadata": None,
- "major": 1,
- "minor": 0,
- "patch": 1,
- "prerelease": None,
+ "metadata": {
+ "release_date": "2018-05-31",
+ "version": "1.0.1",
+ "semantic_version": {
+ "buildmetadata": None,
+ "major": 1,
+ "minor": 0,
+ "patch": 1,
+ "prerelease": None,
+ },
+ "url": "https://github.test_url/test_project/compare/v1.0.0...v1.0.1",
},
- "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)"],
- "release_date": "2017-04-10",
- "version": "1.0.0",
- "semantic_version": {
- "buildmetadata": None,
- "major": 1,
- "minor": 0,
- "patch": 0,
- "prerelease": None,
+ "metadata": {
+ "release_date": "2017-04-10",
+ "version": "1.0.0",
+ "semantic_version": {
+ "buildmetadata": None,
+ "major": 1,
+ "minor": 0,
+ "patch": 0,
+ "prerelease": None,
+ },
+ "url": "https://github.test_url/test_project/releases/tag/v1.0.0",
},
- "url": "https://github.test_url/test_project/releases/tag/v1.0.0",
},
}
diff --git a/tests/test_non_standard_changelog.py b/tests/test_non_standard_changelog.py
index 27272d7..25147da 100644
--- a/tests/test_non_standard_changelog.py
+++ b/tests/test_non_standard_changelog.py
@@ -83,16 +83,18 @@ def test_changelog_with_versions_and_all_categories(changelog):
"changed": ["Release note 1.", "Release note 2."],
"deprecated": ["Deprecated feature 1", "Future removal 2"],
"fixed": ["Bug fix 1", "sub bug 1", "sub bug 2", "Bug fix 2"],
- "release_date": "august 28, 2019",
"removed": ["Deprecated feature 2", "Future removal 1"],
"security": ["Known issue 1", "Known issue 2"],
- "version": "1.2.0",
- "semantic_version": {
- "buildmetadata": None,
- "major": 1,
- "minor": 2,
- "patch": 0,
- "prerelease": None,
+ "metadata": {
+ "release_date": "august 28, 2019",
+ "version": "1.2.0",
+ "semantic_version": {
+ "buildmetadata": None,
+ "major": 1,
+ "minor": 2,
+ "patch": 0,
+ "prerelease": None,
+ },
},
},
"1.1.0": {
@@ -102,14 +104,16 @@ def test_changelog_with_versions_and_all_categories(changelog):
"sub enhancement 2",
"Enhancement 2 (1.1.0)",
],
- "release_date": "may 03, 2018",
- "version": "1.1.0",
- "semantic_version": {
- "buildmetadata": None,
- "major": 1,
- "minor": 1,
- "patch": 0,
- "prerelease": None,
+ "metadata": {
+ "release_date": "may 03, 2018",
+ "version": "1.1.0",
+ "semantic_version": {
+ "buildmetadata": None,
+ "major": 1,
+ "minor": 1,
+ "patch": 0,
+ "prerelease": None,
+ },
},
},
"1.0.1": {
@@ -119,26 +123,30 @@ def test_changelog_with_versions_and_all_categories(changelog):
"sub bug 2",
"Bug fix 2 (1.0.1)",
],
- "release_date": "may 01, 2018",
- "version": "1.0.1",
- "semantic_version": {
- "buildmetadata": None,
- "major": 1,
- "minor": 0,
- "patch": 1,
- "prerelease": None,
+ "metadata": {
+ "release_date": "may 01, 2018",
+ "version": "1.0.1",
+ "semantic_version": {
+ "buildmetadata": None,
+ "major": 1,
+ "minor": 0,
+ "patch": 1,
+ "prerelease": None,
+ },
},
},
"1.0.0": {
"deprecated": ["Known issue 1 (1.0.0)", "Known issue 2 (1.0.0)"],
- "release_date": "2017-01-01",
- "version": "1.0.0",
- "semantic_version": {
- "buildmetadata": None,
- "major": 1,
- "minor": 0,
- "patch": 0,
- "prerelease": None,
+ "metadata": {
+ "release_date": "2017-01-01",
+ "version": "1.0.0",
+ "semantic_version": {
+ "buildmetadata": None,
+ "major": 1,
+ "minor": 0,
+ "patch": 0,
+ "prerelease": None,
+ },
},
},
}
@@ -146,7 +154,9 @@ def test_changelog_with_versions_and_all_categories(changelog):
def test_changelog_with_unreleased_versions_and_all_categories(changelog):
assert keepachangelog.to_dict(changelog, show_unreleased=True) == {
- "master": {"release_date": None, "version": "master"},
+ "master": {
+ "metadata": {"release_date": None, "version": "master"},
+ },
"1.2.0": {
"added": [
"Enhancement 1",
@@ -157,16 +167,18 @@ def test_changelog_with_unreleased_versions_and_all_categories(changelog):
"changed": ["Release note 1.", "Release note 2."],
"deprecated": ["Deprecated feature 1", "Future removal 2"],
"fixed": ["Bug fix 1", "sub bug 1", "sub bug 2", "Bug fix 2"],
- "release_date": "august 28, 2019",
"removed": ["Deprecated feature 2", "Future removal 1"],
"security": ["Known issue 1", "Known issue 2"],
- "version": "1.2.0",
- "semantic_version": {
- "buildmetadata": None,
- "major": 1,
- "minor": 2,
- "patch": 0,
- "prerelease": None,
+ "metadata": {
+ "release_date": "august 28, 2019",
+ "version": "1.2.0",
+ "semantic_version": {
+ "buildmetadata": None,
+ "major": 1,
+ "minor": 2,
+ "patch": 0,
+ "prerelease": None,
+ },
},
},
"1.1.0": {
@@ -176,14 +188,16 @@ def test_changelog_with_unreleased_versions_and_all_categories(changelog):
"sub enhancement 2",
"Enhancement 2 (1.1.0)",
],
- "release_date": "may 03, 2018",
- "version": "1.1.0",
- "semantic_version": {
- "buildmetadata": None,
- "major": 1,
- "minor": 1,
- "patch": 0,
- "prerelease": None,
+ "metadata": {
+ "release_date": "may 03, 2018",
+ "version": "1.1.0",
+ "semantic_version": {
+ "buildmetadata": None,
+ "major": 1,
+ "minor": 1,
+ "patch": 0,
+ "prerelease": None,
+ },
},
},
"1.0.1": {
@@ -193,26 +207,30 @@ def test_changelog_with_unreleased_versions_and_all_categories(changelog):
"sub bug 2",
"Bug fix 2 (1.0.1)",
],
- "release_date": "may 01, 2018",
- "version": "1.0.1",
- "semantic_version": {
- "buildmetadata": None,
- "major": 1,
- "minor": 0,
- "patch": 1,
- "prerelease": None,
+ "metadata": {
+ "release_date": "may 01, 2018",
+ "version": "1.0.1",
+ "semantic_version": {
+ "buildmetadata": None,
+ "major": 1,
+ "minor": 0,
+ "patch": 1,
+ "prerelease": None,
+ },
},
},
"1.0.0": {
"deprecated": ["Known issue 1 (1.0.0)", "Known issue 2 (1.0.0)"],
- "release_date": "2017-01-01",
- "version": "1.0.0",
- "semantic_version": {
- "buildmetadata": None,
- "major": 1,
- "minor": 0,
- "patch": 0,
- "prerelease": None,
+ "metadata": {
+ "release_date": "2017-01-01",
+ "version": "1.0.0",
+ "semantic_version": {
+ "buildmetadata": None,
+ "major": 1,
+ "minor": 0,
+ "patch": 0,
+ "prerelease": None,
+ },
},
},
}
@@ -244,14 +262,16 @@ def test_raw_changelog_with_versions_and_all_categories(changelog):
- Deprecated feature 2
- Future removal 1
""",
- "release_date": "august 28, 2019",
- "version": "1.2.0",
- "semantic_version": {
- "buildmetadata": None,
- "major": 1,
- "minor": 2,
- "patch": 0,
- "prerelease": None,
+ "metadata": {
+ "release_date": "august 28, 2019",
+ "version": "1.2.0",
+ "semantic_version": {
+ "buildmetadata": None,
+ "major": 1,
+ "minor": 2,
+ "patch": 0,
+ "prerelease": None,
+ },
},
},
"1.1.0": {
@@ -261,14 +281,16 @@ def test_raw_changelog_with_versions_and_all_categories(changelog):
- sub enhancement 2
- Enhancement 2 (1.1.0)
""",
- "release_date": "may 03, 2018",
- "version": "1.1.0",
- "semantic_version": {
- "buildmetadata": None,
- "major": 1,
- "minor": 1,
- "patch": 0,
- "prerelease": None,
+ "metadata": {
+ "release_date": "may 03, 2018",
+ "version": "1.1.0",
+ "semantic_version": {
+ "buildmetadata": None,
+ "major": 1,
+ "minor": 1,
+ "patch": 0,
+ "prerelease": None,
+ },
},
},
"1.0.1": {
@@ -278,14 +300,16 @@ def test_raw_changelog_with_versions_and_all_categories(changelog):
- sub bug 2
- Bug fix 2 (1.0.1)
""",
- "release_date": "may 01, 2018",
- "version": "1.0.1",
- "semantic_version": {
- "buildmetadata": None,
- "major": 1,
- "minor": 0,
- "patch": 1,
- "prerelease": None,
+ "metadata": {
+ "release_date": "may 01, 2018",
+ "version": "1.0.1",
+ "semantic_version": {
+ "buildmetadata": None,
+ "major": 1,
+ "minor": 0,
+ "patch": 1,
+ "prerelease": None,
+ },
},
},
"1.0.0": {
@@ -293,14 +317,16 @@ def test_raw_changelog_with_versions_and_all_categories(changelog):
- Known issue 1 (1.0.0)
- Known issue 2 (1.0.0)
""",
- "release_date": "2017-01-01",
- "version": "1.0.0",
- "semantic_version": {
- "buildmetadata": None,
- "major": 1,
- "minor": 0,
- "patch": 0,
- "prerelease": None,
+ "metadata": {
+ "release_date": "2017-01-01",
+ "version": "1.0.0",
+ "semantic_version": {
+ "buildmetadata": None,
+ "major": 1,
+ "minor": 0,
+ "patch": 0,
+ "prerelease": None,
+ },
},
},
}
diff --git a/tests/test_starlette.py b/tests/test_starlette.py
index 7641aa9..0517fef 100644
--- a/tests/test_starlette.py
+++ b/tests/test_starlette.py
@@ -84,16 +84,18 @@ def test_changelog_endpoint_with_file(tmpdir):
"sub enhancement 2",
"Enhancement 2 (1.1.0)",
],
- "release_date": "2018-05-31",
- "version": "1.1.0",
- "semantic_version": {
- "buildmetadata": None,
- "major": 1,
- "minor": 1,
- "patch": 0,
- "prerelease": None,
+ "metadata": {
+ "release_date": "2018-05-31",
+ "version": "1.1.0",
+ "semantic_version": {
+ "buildmetadata": None,
+ "major": 1,
+ "minor": 1,
+ "patch": 0,
+ "prerelease": None,
+ },
+ "url": "https://github.test_url/test_project/compare/v1.0.1...v1.1.0",
},
- "url": "https://github.test_url/test_project/compare/v1.0.1...v1.1.0",
},
"1.0.1": {
"fixed": [
@@ -102,29 +104,33 @@ def test_changelog_endpoint_with_file(tmpdir):
"sub bug 2",
"Bug fix 2 (1.0.1)",
],
- "release_date": "2018-05-31",
- "version": "1.0.1",
- "semantic_version": {
- "buildmetadata": None,
- "major": 1,
- "minor": 0,
- "patch": 1,
- "prerelease": None,
+ "metadata": {
+ "release_date": "2018-05-31",
+ "version": "1.0.1",
+ "semantic_version": {
+ "buildmetadata": None,
+ "major": 1,
+ "minor": 0,
+ "patch": 1,
+ "prerelease": None,
+ },
+ "url": "https://github.test_url/test_project/compare/v1.0.0...v1.0.1",
},
- "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)"],
- "release_date": "2017-04-10",
- "version": "1.0.0",
- "semantic_version": {
- "buildmetadata": None,
- "major": 1,
- "minor": 0,
- "patch": 0,
- "prerelease": None,
+ "metadata": {
+ "release_date": "2017-04-10",
+ "version": "1.0.0",
+ "semantic_version": {
+ "buildmetadata": None,
+ "major": 1,
+ "minor": 0,
+ "patch": 0,
+ "prerelease": None,
+ },
+ "url": "https://github.test_url/test_project/releases/tag/v1.0.0",
},
- "url": "https://github.test_url/test_project/releases/tag/v1.0.0",
},
}
From 0584bac2c124e547cb6b7800da145beaa9611881 Mon Sep 17 00:00:00 2001
From: Colin-b
Date: Thu, 27 May 2021 16:05:10 +0200
Subject: [PATCH 8/8] Release version 2.0.0.dev0 today
---
CHANGELOG.md | 5 ++++-
keepachangelog/version.py | 2 +-
2 files changed, 5 insertions(+), 2 deletions(-)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 83de539..7be4b51 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -5,6 +5,8 @@ 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]
+
+## [2.0.0.dev0] - 2021-05-27
### Fixed
- `keepachangelog.to_dict` now contains releases that have a URL but no section.
- `keepachangelog.to_raw_dict` now contains releases that have a URL but no section.
@@ -71,7 +73,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### Added
- Initial release.
-[Unreleased]: https://github.com/Colin-b/keepachangelog/compare/v1.0.0...HEAD
+[Unreleased]: https://github.com/Colin-b/keepachangelog/compare/v2.0.0.dev0...HEAD
+[2.0.0.dev0]: https://github.com/Colin-b/keepachangelog/compare/v1.0.0...v2.0.0.dev0
[1.0.0]: https://github.com/Colin-b/keepachangelog/compare/v0.5.0...v1.0.0
[0.5.0]: https://github.com/Colin-b/keepachangelog/compare/v0.4.0...v0.5.0
[0.4.0]: https://github.com/Colin-b/keepachangelog/compare/v0.3.1...v0.4.0
diff --git a/keepachangelog/version.py b/keepachangelog/version.py
index 09fdcc6..d21e8e5 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__ = "1.0.0"
+__version__ = "2.0.0.dev0"