From 08fa4acb12bb181670d8339fb0287451a79d183f Mon Sep 17 00:00:00 2001
From: Colin-b
Date: Thu, 22 Dec 2022 15:51:14 +0100
Subject: [PATCH 1/3] Add more documentation on CLI
---
README.md | 103 +++++++++++++++++++++++++++++++++++-------------------
1 file changed, 68 insertions(+), 35 deletions(-)
diff --git a/README.md b/README.md
index d4dfdee..edf2d56 100644
--- a/README.md
+++ b/README.md
@@ -9,6 +9,7 @@
+* [Command line utility](#usage-from-command-line)
* [Convert to dict](#convert-changelog-to-dict)
* [Convert from dict](#convert-dict-to-changelog)
* [Release a new version](#release)
@@ -156,6 +157,16 @@ Note that `release_date` metadata will be set to None in such as case.
### Retrieving the raw content
+#### Using CLI
+
+```shell
+keepachangelog show 1.0.0 --raw
+```
+
+For details on what is actually performed, refer to the section below as it is what is used underneath the hood.
+
+#### Using python module
+
If for some reason you would like to retrieve the raw content of a release you can use `to_raw_dict` instead.
```python
@@ -239,6 +250,16 @@ content = keepachangelog.from_dict(changes)
## Release
+### Using CLI
+
+```shell
+keepachangelog release
+```
+
+For details on what is actually performed, refer to the section below as it is what is used underneath the hood.
+
+### Using python module
+
You can create a new release by using `keepachangelog.release` function.
```python
@@ -257,6 +278,52 @@ This will:
* `[Unreleased]` link will be updated.
* New link will be created corresponding to the new section (based on the format of the Unreleased link).
+## Usage from command line
+
+`keepachangelog` can be used directly via command line.
+
+The main usage is within your CI to be able to [Release a new version](#release) and then [Create the appropriate release body](#retrieving-the-raw-content).
+As in the following sample:
+```shell
+NEW_VERSION=$(keepachangelog release)
+GITHUB_RELEASE_BODY=$(keepachangelog show ${GIT_TAG} --raw)
+```
+
+You can use it as a python module:
+```sh
+python -m keepachangelog --help
+```
+
+Or as a shell command:
+```sh
+keepachangelog --help
+```
+
+```sh
+# usage: keepachangelog [-h] [-v] {show,release} ...
+#
+# Manipulate keep a changelog files
+#
+# options:
+# -h, --help show this help message and exit
+# -v, --version show program's version number and exit
+#
+# commands:
+# {show,release}
+# show Show the content of a release from the changelog
+# release Create a new release in the changelog
+#
+# Examples:
+#
+# keepachangelog show 1.0.0
+# keepachangelog show 1.0.0 --raw
+# keepachangelog show 1.0.0 path/to/CHANGELOG.md
+#
+# keepachangelog release
+# keepachangelog release 1.0.1
+# keepachangelog release 1.0.1 -f path/to/CHANGELOG.md
+```
+
## Endpoint
### Starlette
@@ -298,38 +365,4 @@ Note: [flask-restx](https://pypi.python.org/pypi/flask-restx) module must be ins
2. Use pip to install module:
```sh
python -m pip install keepachangelog
-```
-
-## Usage from command line
-
-`keepachangelog` can be used directly via command line:
-
-```sh
-# Run it as a Python module
-python -m keepachangelog --help
-# or as a shell command
-keepachangelog --help
-
-# usage: keepachangelog [-h] [-v] {show,release} ...
-#
-# Manipulate keep a changelog files
-#
-# options:
-# -h, --help show this help message and exit
-# -v, --version show program's version number and exit
-#
-# commands:
-# {show,release}
-# show Show the content of a release from the changelog
-# release Create a new release in the changelog
-#
-# Examples:
-#
-# keepachangelog show 1.0.0
-# keepachangelog show 1.0.0 --raw
-# keepachangelog show 1.0.0 path/to/CHANGELOG.md
-#
-# keepachangelog release
-# keepachangelog release 1.0.1
-# keepachangelog release 1.0.1 -f path/to/CHANGELOG.md
-```
+```
\ No newline at end of file
From a6f25d791e000070117cb87d95cb7aa9764480b8 Mon Sep 17 00:00:00 2001
From: Colin-b
Date: Thu, 22 Dec 2022 15:55:09 +0100
Subject: [PATCH 2/3] Add more type hinting
---
keepachangelog/__main__.py | 16 +++++++---------
1 file changed, 7 insertions(+), 9 deletions(-)
diff --git a/keepachangelog/__main__.py b/keepachangelog/__main__.py
index 834b2e9..b9ba7a5 100644
--- a/keepachangelog/__main__.py
+++ b/keepachangelog/__main__.py
@@ -5,16 +5,14 @@
from keepachangelog.version import __version__
-def _format_change_section(change_type: str, changes: List[str]):
+def _format_change_section(change_type: str, changes: List[str]) -> str:
body = "".join([f" - {change}\r\n" for change in changes])
return f"""{change_type.capitalize()}
{body}"""
-def _command_show(args):
- output = None
-
+def _command_show(args: argparse.Namespace) -> None:
if args.raw:
changelog = keepachangelog.to_raw_dict(args.file)
else:
@@ -36,14 +34,14 @@ def _command_show(args):
print(output)
-def _command_release(args):
+def _command_release(args: argparse.Namespace) -> None:
new_version = keepachangelog.release(args.file, args.release)
if new_version:
print(new_version)
-def _parse_args(cmdline: List[str]):
+def _parse_args(command_line: List[str]) -> argparse.Namespace:
class CustomFormatter(
argparse.ArgumentDefaultsHelpFormatter, argparse.RawDescriptionHelpFormatter
):
@@ -119,11 +117,11 @@ class CustomFormatter(
"-v", "--version", action="version", version=f"%(prog)s {__version__}"
)
- return parser.parse_args(cmdline)
+ return parser.parse_args(command_line)
-def main(cmdline: List[str] = None):
- args = _parse_args(cmdline)
+def main(command_line: List[str] = None) -> None:
+ args = _parse_args(command_line)
args.func(args)
From da7e1f60261557ea65d121df0d6adc1cb23c6dbd Mon Sep 17 00:00:00 2001
From: Colin-b
Date: Tue, 3 Jan 2023 16:00:00 +0100
Subject: [PATCH 3/3] Fail if there is nothing to release
---
CHANGELOG.md | 11 ++++++++-
README.md | 5 ++--
keepachangelog/__main__.py | 39 +++++++-----------------------
keepachangelog/version.py | 2 +-
tests/test_cli.py | 49 ++++++++++++++++++++++++++++----------
5 files changed, 57 insertions(+), 49 deletions(-)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index d2f71f4..beb61fd 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -6,6 +6,14 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
## [Unreleased]
+## [2.0.0.dev5] - 2023-01-03
+### Changed
+- `keepachangelog show` does not support `--raw` option anymore. It will always be the raw markdown output.
+- `keepachangelog release` will now fail if there is nothing to release.
+
+### Removed
+- `keepachangelog show` does not support `--raw` option anymore.
+
## [2.0.0.dev4] - 2022-12-22
### Added
- Add a CLI to interact with `keepachangelog` API. (Thanks [Luca Faggianelli](https://github.com/lucafaggianelli))
@@ -99,7 +107,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.dev4...HEAD
+[Unreleased]: https://github.com/Colin-b/keepachangelog/compare/v2.0.0.dev5...HEAD
+[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
[2.0.0.dev2]: https://github.com/Colin-b/keepachangelog/compare/v2.0.0.dev1...v2.0.0.dev2
diff --git a/README.md b/README.md
index edf2d56..069a076 100644
--- a/README.md
+++ b/README.md
@@ -160,7 +160,7 @@ Note that `release_date` metadata will be set to None in such as case.
#### Using CLI
```shell
-keepachangelog show 1.0.0 --raw
+keepachangelog show 1.0.0
```
For details on what is actually performed, refer to the section below as it is what is used underneath the hood.
@@ -286,7 +286,7 @@ The main usage is within your CI to be able to [Release a new version](#release)
As in the following sample:
```shell
NEW_VERSION=$(keepachangelog release)
-GITHUB_RELEASE_BODY=$(keepachangelog show ${GIT_TAG} --raw)
+GITHUB_RELEASE_BODY=$(keepachangelog show ${NEW_VERSION})
```
You can use it as a python module:
@@ -316,7 +316,6 @@ keepachangelog --help
# Examples:
#
# keepachangelog show 1.0.0
-# keepachangelog show 1.0.0 --raw
# keepachangelog show 1.0.0 path/to/CHANGELOG.md
#
# keepachangelog release
diff --git a/keepachangelog/__main__.py b/keepachangelog/__main__.py
index b9ba7a5..da3d8f4 100644
--- a/keepachangelog/__main__.py
+++ b/keepachangelog/__main__.py
@@ -1,3 +1,4 @@
+import sys
from typing import List
import argparse
@@ -5,40 +6,20 @@
from keepachangelog.version import __version__
-def _format_change_section(change_type: str, changes: List[str]) -> str:
- body = "".join([f" - {change}\r\n" for change in changes])
-
- return f"""{change_type.capitalize()}
-{body}"""
-
-
def _command_show(args: argparse.Namespace) -> None:
- if args.raw:
- changelog = keepachangelog.to_raw_dict(args.file)
- else:
- changelog = keepachangelog.to_dict(args.file)
-
+ changelog = keepachangelog.to_raw_dict(args.file)
content = changelog.get(args.release)
-
- if args.raw:
- output = content["raw"]
- else:
- output = "\n".join(
- [
- _format_change_section(change_type, changes)
- for change_type, changes in content.items()
- if change_type != "metadata"
- ]
- )
-
- print(output)
+ print(content["raw"])
def _command_release(args: argparse.Namespace) -> None:
new_version = keepachangelog.release(args.file, args.release)
- if new_version:
- print(new_version)
+ if not new_version:
+ 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:
@@ -54,7 +35,6 @@ class CustomFormatter(
Examples:
keepachangelog show 1.0.0
- keepachangelog show 1.0.0 --raw
keepachangelog show 1.0.0 path/to/CHANGELOG.md
keepachangelog release
@@ -83,9 +63,6 @@ class CustomFormatter(
default="CHANGELOG.md",
help="The path to the changelog file",
)
- parser_show.add_argument(
- "-r", "--raw", action="store_true", help="Show the raw markdown body"
- )
parser_show.set_defaults(func=_command_show)
diff --git a/keepachangelog/version.py b/keepachangelog/version.py
index 89c4624..e38d355 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__ = "2.0.0.dev4"
+__version__ = "2.0.0.dev5"
diff --git a/tests/test_cli.py b/tests/test_cli.py
index e707a28..f464579 100644
--- a/tests/test_cli.py
+++ b/tests/test_cli.py
@@ -69,6 +69,28 @@ def changelog(tmpdir):
return changelog_file_path
+@pytest.fixture
+def changelog_without_unreleased(tmpdir):
+ changelog_file_path = os.path.join(tmpdir, "CHANGELOG_without_unreleased.md")
+ with open(changelog_file_path, mode="wt", encoding="utf-8") 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.0.0] - 2017-04-10
+### Deprecated
+- Known issue 1 (1.0.0) 漢字
+- Known issue 2 (1.0.0)
+"""
+ )
+ return changelog_file_path
+
+
def test_print_help(changelog: str, capsys: pytest.CaptureFixture):
with pytest.raises(SystemExit) as exc:
cli(["--help"])
@@ -93,20 +115,8 @@ def test_print_version(changelog: str, capsys: pytest.CaptureFixture):
assert captured.out.strip() == f"keepachangelog {__version__}"
-def test_show_release_pretty(changelog: str, capsys: pytest.CaptureFixture):
- cli(["show", "1.0.0", changelog])
-
- captured = capsys.readouterr()
-
- assert captured.err == ""
- assert (
- captured.out.strip()
- == "Deprecated\n - Known issue 1 (1.0.0) 漢字\r\n - Known issue 2 (1.0.0)"
- )
-
-
def test_show_release_raw(changelog: str, capsys: pytest.CaptureFixture):
- cli(["show", "1.0.0", changelog, "--raw"])
+ cli(["show", "1.0.0", changelog])
captured = capsys.readouterr()
@@ -130,6 +140,19 @@ def test_create_release_automatic_version(
assert captured.out.strip() == "2.0.0"
+def test_create_release_nothing_to_release(
+ changelog_without_unreleased: str, capsys: pytest.CaptureFixture
+):
+ with pytest.raises(SystemExit) as cm:
+ cli(["release", "-f", changelog_without_unreleased])
+ assert cm.value.code == 2
+
+ captured = capsys.readouterr()
+
+ assert captured.err == f"{changelog_without_unreleased} must contains a description of the release content (within Unreleased section)."
+ assert captured.out == ""
+
+
def test_create_release_specific_version(changelog: str, capsys: pytest.CaptureFixture):
cli(["release", "3.2.1", "-f", changelog])