Skip to content

Commit

Permalink
Release 2.0.0 (#53)
Browse files Browse the repository at this point in the history
Co-authored-by: Jesse De Loore <[email protected]>
  • Loading branch information
Colin-b and JesseDeLoore committed Jun 14, 2024
1 parent 0231431 commit aa69a52
Show file tree
Hide file tree
Showing 19 changed files with 216 additions and 128 deletions.
6 changes: 3 additions & 3 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,12 @@ jobs:
runs-on: ubuntu-latest
strategy:
matrix:
python-version: ['3.7', '3.8', '3.9', '3.10', '3.11']
python-version: ['3.9', '3.10', '3.11', '3.12']

steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v4
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v2
uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python-version }}
- name: Install dependencies
Expand Down
6 changes: 3 additions & 3 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,12 @@ jobs:
runs-on: ubuntu-latest
strategy:
matrix:
python-version: ['3.7', '3.8', '3.9', '3.10', '3.11']
python-version: ['3.9', '3.10', '3.11', '3.12']

steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v4
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v2
uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python-version }}
- name: Install dependencies
Expand Down
2 changes: 1 addition & 1 deletion .pre-commit-config.yaml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
repos:
- repo: https://github.com/psf/black
rev: 22.12.0
rev: 24.4.2
hooks:
- id: black
17 changes: 16 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,20 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## [Unreleased]

## [2.0.0] - 2024-06-14
### Removed
- `Python` `3.7` and `3.8` are not supported anymore.

### Added
- `Python` `3.12` is now explicitly supported.

### Fixed
- Uncategorized change (usually comments) will no longer impact the release version.
- Typing is using built-in types for `tuple`, `list` and `dict` consistently.

### Changed
- `keepachangelog.starlette.add_changelog_endpoint` is now `keepachangelog.starlette.changelog_endpoint`. Refer to documentation for more details.

## [2.0.0.dev5] - 2023-01-03
### Changed
- `keepachangelog show` does not support `--raw` option anymore. It will always be the raw markdown output.
Expand Down Expand Up @@ -107,7 +121,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/v2.0.0.dev5...HEAD
[Unreleased]: https://github.com/Colin-b/keepachangelog/compare/v2.0.0...HEAD
[2.0.0]: https://github.com/Colin-b/keepachangelog/compare/v2.0.0.dev5...v2.0.0
[2.0.0.dev5]: https://github.com/Colin-b/keepachangelog/compare/v2.0.0.dev4...v2.0.0.dev5
[2.0.0.dev4]: https://github.com/Colin-b/keepachangelog/compare/v2.0.0.dev3...v2.0.0.dev4
[2.0.0.dev3]: https://github.com/Colin-b/keepachangelog/compare/v2.0.0.dev2...v2.0.0.dev3
Expand Down
10 changes: 3 additions & 7 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ Before creating an issue please make sure that it was not already reported.

1) Go to the *Issues* tab and click on the *New issue* button.
2) Title should be a small sentence describing the request.
3) The comment should contains as much information as possible
3) The comment should contain as much information as possible
* Actual behavior (including the version you used)
* Expected behavior
* Steps to reproduce
Expand All @@ -48,19 +48,15 @@ Before creating an issue please make sure that it was not already reported.
* To add the [pre-commit](https://pre-commit.com) hook, after the installation run: **pre-commit install**
6) Add at least one [`pytest`](http://doc.pytest.org/en/latest/index.html) test case.
* Unless it is an internal refactoring request or a documentation update.
7) Increment [version number](https://semver.org) and add related [changelog entry](https://keepachangelog.com/en/1.0.0/).
7) Add related [changelog entry](https://keepachangelog.com/en/1.1.0/).
* Unless it is a documentation update.

##### Changelog entry

Once the changelog entry is added, please don't forget to also add the link to the proper tag at the end of the changelog.

#### Enter pull request

1) Go to the *Pull requests* tab and click on the *New pull request* button.
2) *base* should always be set to `develop` and it should be compared to your branch.
3) Title should be a small sentence describing the request.
3) The comment should contains as much information as possible
4) The comment should contain as much information as possible
* Actual behavior (before the new code)
* Expected behavior (with the new code)
* Steps to reproduce (with and without the new code to see the difference)
2 changes: 1 addition & 1 deletion LICENSE
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
MIT License

Copyright (c) 2022 Colin Bounouar
Copyright (c) 2024 Colin Bounouar

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
Expand Down
14 changes: 7 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
<a href="https://github.com/Colin-b/keepachangelog/actions"><img alt="Build status" src="https://github.com/Colin-b/keepachangelog/workflows/Release/badge.svg"></a>
<a href="https://github.com/Colin-b/keepachangelog/actions"><img alt="Coverage" src="https://img.shields.io/badge/coverage-100%25-brightgreen"></a>
<a href="https://github.com/psf/black"><img alt="Code style: black" src="https://img.shields.io/badge/code%20style-black-000000.svg"></a>
<a href="https://github.com/Colin-b/keepachangelog/actions"><img alt="Number of tests" src="https://img.shields.io/badge/tests-47 passed-blue"></a>
<a href="https://github.com/Colin-b/keepachangelog/actions"><img alt="Number of tests" src="https://img.shields.io/badge/tests-48 passed-blue"></a>
<a href="https://pypi.org/project/keepachangelog/"><img alt="Number of downloads" src="https://img.shields.io/pypi/dm/keepachangelog"></a>
</p>

Expand Down Expand Up @@ -327,23 +327,23 @@ keepachangelog --help

### Starlette

An helper function is available to create a [starlette](https://www.starlette.io) endpoint to retrieve changelog as JSON.
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 keepachangelog.starlette import add_changelog_endpoint
from starlette.routing import Route
from keepachangelog.starlette import changelog_endpoint


app = Starlette()
# /changelog endpoint will return the dict extracted from the changelog as JSON.
add_changelog_endpoint(app, "path/to/CHANGELOG.md")
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

An helper function is available to create a [Flask-RestX](https://flask-restx.readthedocs.io/en/latest/) endpoint to retrieve changelog as JSON.
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
Expand Down
9 changes: 5 additions & 4 deletions keepachangelog/__main__.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import sys
from typing import List
import argparse

import keepachangelog
Expand All @@ -16,13 +15,15 @@ def _command_release(args: argparse.Namespace) -> None:
new_version = keepachangelog.release(args.file, args.release)

if not new_version:
sys.stderr.write(f"{args.file} must contains a description of the release content (within Unreleased section).")
sys.stderr.write(
f"{args.file} must contains a description of the release content (within Unreleased section)."
)
exit(2)

print(new_version)


def _parse_args(command_line: List[str]) -> argparse.Namespace:
def _parse_args(command_line: list[str]) -> argparse.Namespace:
class CustomFormatter(
argparse.ArgumentDefaultsHelpFormatter, argparse.RawDescriptionHelpFormatter
):
Expand Down Expand Up @@ -97,7 +98,7 @@ class CustomFormatter(
return parser.parse_args(command_line)


def main(command_line: List[str] = None) -> None:
def main(command_line: list[str] = None) -> None:
args = _parse_args(command_line)
args.func(args)

Expand Down
18 changes: 9 additions & 9 deletions keepachangelog/_changelog.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import datetime
import re
from typing import Dict, List, Optional, Iterable, Union
from typing import Optional, Iterable, Union

from keepachangelog._versioning import (
actual_version,
Expand All @@ -14,7 +14,7 @@ def is_release(line: str) -> bool:
return line.startswith("## ")


def add_release(changes: Dict[str, dict], line: str) -> 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]
Expand Down Expand Up @@ -49,7 +49,7 @@ def is_category(line: str) -> bool:
return line.startswith("### ")


def add_category(release: dict, line: str) -> List[str]:
def add_category(release: dict, line: str) -> list[str]:
category = line[4:].lower().strip(" ")
return release.setdefault(category, [])

Expand All @@ -62,13 +62,13 @@ def is_link(line: str) -> bool:
return link_pattern.fullmatch(line) is not None


def add_information(category: List[str], line: str):
def add_information(category: list[str], line: str) -> None:
category.append(line.lstrip(" *-").rstrip(" -"))


def to_dict(
changelog_path: Union[str, Iterable[str]], *, show_unreleased: bool = False
) -> Dict[str, dict]:
) -> dict[str, dict]:
"""
Convert changelog markdown file following keep a changelog format into python dict.
Expand All @@ -84,7 +84,7 @@ def to_dict(
return _to_dict(changelog_path, show_unreleased)


def _to_dict(change_log: Iterable[str], show_unreleased: bool) -> Dict[str, dict]:
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 = {}
Expand Down Expand Up @@ -127,7 +127,7 @@ def _to_dict(change_log: Iterable[str], show_unreleased: bool) -> Dict[str, dict
return changes


def from_dict(changes: Dict[str, dict]):
def from_dict(changes: dict[str, dict]) -> str:
content = """# Changelog
All notable changes to this project will be documented in this file.
Expand Down Expand Up @@ -173,7 +173,7 @@ def from_dict(changes: Dict[str, dict]):
return content


def to_raw_dict(changelog_path: str) -> Dict[str, dict]:
def to_raw_dict(changelog_path: str) -> dict[str, dict]:
changes = {}
# As URLs can be defined before actual usage, maintain a separate dict
urls = {}
Expand Down Expand Up @@ -227,7 +227,7 @@ def release(changelog_path: str, new_version: str = None) -> Optional[str]:

def release_version(
changelog_path: str, current_version: Optional[str], new_version: str
):
) -> None:
unreleased_link_pattern = re.compile(r"^\[Unreleased\]: (.*)$", re.DOTALL)
lines = []
with open(changelog_path, encoding="utf-8") as change_log:
Expand Down
32 changes: 18 additions & 14 deletions keepachangelog/_versioning.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import re
from functools import cmp_to_key
from typing import Tuple, Optional, Iterable, List
from typing import Optional, Iterable

initial_semantic_version = {
"major": 0,
Expand All @@ -23,25 +23,25 @@ def contains_breaking_changes(unreleased: dict) -> bool:


def only_contains_bug_fixes(unreleased: dict) -> bool:
return ["fixed"] == list(unreleased)
return {"fixed"} == set(unreleased) - {"uncategorized"}


def bump_major(semantic_version: dict):
def bump_major(semantic_version: dict) -> None:
semantic_version["major"] += 1
semantic_version["minor"] = 0
semantic_version["patch"] = 0
semantic_version["prerelease"] = None
semantic_version["buildmetadata"] = None


def bump_minor(semantic_version: dict) -> str:
def bump_minor(semantic_version: dict) -> None:
semantic_version["minor"] += 1
semantic_version["patch"] = 0
semantic_version["prerelease"] = None
semantic_version["buildmetadata"] = None


def bump_patch(semantic_version: dict) -> str:
def bump_patch(semantic_version: dict) -> None:
semantic_version["patch"] += 1
semantic_version["prerelease"] = None
semantic_version["buildmetadata"] = None
Expand Down Expand Up @@ -71,7 +71,7 @@ def _compare(first_version: str, second_version: str) -> int:


def semantic_order(
first_version: Tuple[str, dict], second_version: Tuple[str, dict]
first_version: tuple[str, dict], second_version: tuple[str, dict]
) -> int:
_, semantic_first_version = first_version
_, semantic_second_version = second_version
Expand All @@ -96,23 +96,27 @@ def semantic_order(

# Ensure release is "bigger than" pre-release
pre_release_difference = _compare(
f"0{semantic_first_version['prerelease']}"
if semantic_first_version["prerelease"]
else "1",
f"0{semantic_second_version['prerelease']}"
if semantic_second_version["prerelease"]
else "1",
(
f"0{semantic_first_version['prerelease']}"
if semantic_first_version["prerelease"]
else "1"
),
(
f"0{semantic_second_version['prerelease']}"
if semantic_second_version["prerelease"]
else "1"
),
)

return pre_release_difference


def actual_version(changelog: dict) -> Tuple[Optional[str], dict]:
def actual_version(changelog: dict) -> tuple[Optional[str], dict]:
versions = to_sorted_semantic(changelog.keys())
return versions.pop() if versions else (None, initial_semantic_version.copy())


def to_sorted_semantic(versions: Iterable[str]) -> List[Tuple[str, dict]]:
def to_sorted_semantic(versions: Iterable[str]) -> list[tuple[str, dict]]:
"""
Convert a list of string semantic versions to a sorted list of semantic versions.
Note: unreleased is not considered as a semantic version and will thus be removed from the resulting versions.
Expand Down
2 changes: 1 addition & 1 deletion keepachangelog/flask_restx.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@

def add_changelog_endpoint(
namespace: Union[flask_restx.Namespace, flask_restx.Api], changelog_path: str
):
) -> None:
"""
Create /changelog: Changelog endpoint parsing https://keepachangelog.com/en/1.0.0/
Expand Down
10 changes: 6 additions & 4 deletions keepachangelog/starlette.py
Original file line number Diff line number Diff line change
@@ -1,18 +1,18 @@
from starlette.applications import Starlette
from typing import Callable

from starlette.responses import JSONResponse

from keepachangelog._changelog import to_dict


def add_changelog_endpoint(app: Starlette, changelog_path: str):
def changelog_endpoint(changelog_path: str) -> Callable:
"""
Create /changelog: Changelog endpoint parsing https://keepachangelog.com/en/1.0.0/
:param app: The ASGI application.
:param changelog_path: Path to CHANGELOG.md.
:returns: The endpoint to add as a route.
"""

@app.route("/changelog")
async def changelog(request):
"""
responses:
Expand All @@ -29,3 +29,5 @@ async def changelog(request):
return JSONResponse(to_dict(changelog_path))
except FileNotFoundError:
return JSONResponse({})

return changelog
2 changes: 1 addition & 1 deletion keepachangelog/version.py
Original file line number Diff line number Diff line change
Expand Up @@ -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__ = "2.0.0.dev5"
__version__ = "2.0.0"
Loading

0 comments on commit aa69a52

Please sign in to comment.