74 lines
1.9 KiB
Python
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"
|