Compare commits
2 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a4b29b4d49 | ||
|
|
4e83779459 |
@@ -1,5 +1,12 @@
|
||||
# Changelog
|
||||
|
||||
## [2.0.1] - 2026-09-18
|
||||
|
||||
* A release no longer ends *CHANGELOG.md* on a blank line, which is MD012.
|
||||
* The entry's separator only belongs there when another entry follows it.
|
||||
* Affects the first entry a file receives, so it shows on an opening release.
|
||||
* Four tests cover the placements in *_insert_after_h1*, one per branch.
|
||||
|
||||
## [2.0.0] - 2026-09-18
|
||||
|
||||
Breaking
|
||||
|
||||
@@ -32,7 +32,7 @@
|
||||
rec {
|
||||
pkgmgr = pyPkgs.buildPythonApplication {
|
||||
pname = "package-manager";
|
||||
version = "2.0.0";
|
||||
version = "2.0.1";
|
||||
|
||||
# Use the git repo as source
|
||||
src = ./.;
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
# Maintainer: Kevin Veen-Birkenbach <info@veen.world>
|
||||
|
||||
pkgname=package-manager
|
||||
pkgver=2.0.0
|
||||
pkgver=2.0.1
|
||||
pkgrel=1
|
||||
pkgdesc="Local-flake wrapper for Kevin's package-manager (Nix-based)."
|
||||
arch=('any')
|
||||
|
||||
@@ -1,3 +1,12 @@
|
||||
package-manager (2.0.1-1) unstable; urgency=medium
|
||||
|
||||
* A release no longer ends *CHANGELOG.md* on a blank line, which is MD012.
|
||||
* The entry's separator only belongs there when another entry follows it.
|
||||
* Affects the first entry a file receives, so it shows on an opening release.
|
||||
* Four tests cover the placements in *_insert_after_h1*, one per branch.
|
||||
|
||||
-- Kevin Veen-Birkenbach <kevin@veen.world> Fri, 18 Sep 2026 17:15:35 +0200
|
||||
|
||||
package-manager (2.0.0-1) unstable; urgency=medium
|
||||
|
||||
Breaking
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
Name: package-manager
|
||||
Version: 2.0.0
|
||||
Version: 2.0.1
|
||||
Release: 1%{?dist}
|
||||
Summary: Wrapper that runs Kevin's package-manager via Nix flake
|
||||
|
||||
@@ -74,6 +74,12 @@ echo ">>> package-manager removed. Nix itself was not removed."
|
||||
/usr/lib/package-manager/
|
||||
|
||||
%changelog
|
||||
* Fri Sep 18 2026 Kevin Veen-Birkenbach <kevin@veen.world> - 2.0.1-1
|
||||
- * A release no longer ends *CHANGELOG.md* on a blank line, which is MD012.
|
||||
- * The entry's separator only belongs there when another entry follows it.
|
||||
- * Affects the first entry a file receives, so it shows on an opening release.
|
||||
- * Four tests cover the placements in *_insert_after_h1*, one per branch.
|
||||
|
||||
* Fri Sep 18 2026 Kevin Veen-Birkenbach <kevin@veen.world> - 2.0.0-1
|
||||
- Breaking
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@ build-backend = "setuptools.build_meta"
|
||||
|
||||
[project]
|
||||
name = "kpmx"
|
||||
version = "2.0.0"
|
||||
version = "2.0.1"
|
||||
description = "Kevin's package-manager tool (pkgmgr)"
|
||||
readme = "README.md"
|
||||
requires-python = ">=3.9"
|
||||
|
||||
@@ -16,6 +16,11 @@ H1_RE = re.compile(r"^#\s+\S", re.MULTILINE)
|
||||
H2_RE = re.compile(r"^##\s+\S", re.MULTILINE)
|
||||
|
||||
|
||||
def _at_end_of_file(entry: str) -> str:
|
||||
"""Return *entry* without the blank line that separates it from a next one."""
|
||||
return entry.rstrip("\n") + "\n"
|
||||
|
||||
|
||||
def _insert_after_h1(existing: str, entry: str) -> str:
|
||||
"""Place *entry* after the H1 (and any intro prose), above the first H2.
|
||||
|
||||
@@ -26,7 +31,7 @@ def _insert_after_h1(existing: str, entry: str) -> str:
|
||||
``## ``) is preserved: *entry* is prepended unchanged.
|
||||
"""
|
||||
if not existing.strip():
|
||||
return f"# Changelog\n\n{entry}"
|
||||
return f"# Changelog\n\n{_at_end_of_file(entry)}"
|
||||
|
||||
if not H1_RE.search(existing):
|
||||
# Legacy layout: file starts with `## [version]` and has no H1.
|
||||
@@ -43,7 +48,7 @@ def _insert_after_h1(existing: str, entry: str) -> str:
|
||||
if existing.endswith("\n\n")
|
||||
else ("\n" if existing.endswith("\n") else "\n\n")
|
||||
)
|
||||
return f"{existing}{suffix}{entry}"
|
||||
return f"{existing}{suffix}{_at_end_of_file(entry)}"
|
||||
|
||||
# Insert new entry just before the first H2.
|
||||
head = existing[: h2_match.start()].rstrip("\n") + "\n\n"
|
||||
|
||||
41
tests/unit/pkgmgr/actions/release/test_changelog_md.py
Normal file
41
tests/unit/pkgmgr/actions/release/test_changelog_md.py
Normal file
@@ -0,0 +1,41 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import unittest
|
||||
|
||||
from pkgmgr.actions.release.files.changelog_md import _insert_after_h1
|
||||
|
||||
ENTRY = "## [1.0.0] - 2026-09-18\n\nOfficial Release\n\n"
|
||||
|
||||
|
||||
class TestInsertAfterH1(unittest.TestCase):
|
||||
def _assert_lint_clean(self, document: str) -> None:
|
||||
self.assertNotIn(
|
||||
"\n\n\n",
|
||||
document,
|
||||
f"MD012: multiple consecutive blank lines in\n{document!r}",
|
||||
)
|
||||
self.assertTrue(
|
||||
document.endswith("\n") and not document.endswith("\n\n"),
|
||||
f"MD012: blank line at end of file in\n{document!r}",
|
||||
)
|
||||
|
||||
def test_an_empty_changelog_gets_one_trailing_newline(self) -> None:
|
||||
self._assert_lint_clean(_insert_after_h1("", ENTRY))
|
||||
|
||||
def test_a_first_entry_under_a_bare_h1_gets_one_trailing_newline(self) -> None:
|
||||
self._assert_lint_clean(_insert_after_h1("# Changelog\n", ENTRY))
|
||||
|
||||
def test_a_second_entry_stays_separated_from_the_first(self) -> None:
|
||||
existing = "# Changelog\n\n## [0.9.0] - 2026-09-01\n\nOlder\n"
|
||||
document = _insert_after_h1(existing, ENTRY)
|
||||
self._assert_lint_clean(document)
|
||||
self.assertIn("Official Release\n\n## [0.9.0]", document)
|
||||
|
||||
def test_a_legacy_headerless_changelog_gains_an_h1(self) -> None:
|
||||
document = _insert_after_h1("## [0.9.0] - 2026-09-01\n\nOlder\n", ENTRY)
|
||||
self._assert_lint_clean(document)
|
||||
self.assertTrue(document.startswith("# Changelog\n\n## [1.0.0]"))
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
Reference in New Issue
Block a user