Files
overub/core/changelog.py
2025-12-21 17:12:32 +01:00

74 lines
1.9 KiB
Python

from collections import defaultdict
from typing import Dict, List
TYPE_MAP = {
"feat": "New Features",
"fix": "Bug Fixes",
"perf": "Performance",
"refactor": "Changes",
"docs": "Documentation",
"style": "Style",
"test": "Tests",
"chore": "Maintenance",
}
ORDER = [
"Breaking Changes",
"New Features",
"Bug Fixes",
"Performance",
"Changes",
"Documentation",
"Style",
"Tests",
"Maintenance",
"Other",
]
def parse_conventional(commits: List[str]) -> Dict[str, List[str]]:
buckets: Dict[str, List[str]] = defaultdict(list)
for line in commits:
parts = line.split(" ", 1)
if len(parts) != 2:
continue
message = parts[1].strip()
header = message
subject = ""
if ":" in message:
header, subject = message.split(":", 1)
header = header.strip()
subject = subject.strip() or message
breaking = False
if "!" in header:
header = header.split("!", 1)[0]
breaking = True
base_type = header.split("(", 1)[0].strip()
category = TYPE_MAP.get(base_type, "Other")
buckets[category].append(subject)
if "BREAKING" in message.upper():
breaking = True
if breaking:
buckets["Breaking Changes"].append(subject)
return buckets
def format_changelog(buckets: Dict[str, List[str]], inline: bool = False) -> str:
if inline:
parts = []
for key in ORDER:
items = buckets.get(key, [])
if items:
parts.append(f"{key}: {len(items)}")
return " | ".join(parts) if parts else "No changes"
lines = []
for key in ORDER:
items = buckets.get(key, [])
if not items:
continue
lines.append(key)
for item in items:
lines.append(f"- {item}")
return "\n".join(lines) if lines else "No changelog entries"