commitstash 0.3.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- autocommit/__init__.py +1 -0
- autocommit/changelog.py +86 -0
- autocommit/cli.py +777 -0
- autocommit/config.py +35 -0
- autocommit/explain.py +43 -0
- autocommit/git.py +167 -0
- autocommit/llm.py +298 -0
- autocommit/pr.py +78 -0
- autocommit/providers.py +119 -0
- autocommit/review.py +83 -0
- autocommit/secrets.py +85 -0
- autocommit/split.py +106 -0
- commitstash-0.3.0.dist-info/METADATA +429 -0
- commitstash-0.3.0.dist-info/RECORD +17 -0
- commitstash-0.3.0.dist-info/WHEEL +4 -0
- commitstash-0.3.0.dist-info/entry_points.txt +2 -0
- commitstash-0.3.0.dist-info/licenses/LICENSE +21 -0
autocommit/__init__.py
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
__version__ = "0.3.0"
|
autocommit/changelog.py
ADDED
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
"""Changelog generation from conventional commit history.
|
|
2
|
+
|
|
3
|
+
Deliberately deterministic — a changelog should be reproducible from the
|
|
4
|
+
same history, so no LLM is involved. Commits are grouped by conventional
|
|
5
|
+
type; breaking changes (`!` marker) get their own section up top.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
import datetime
|
|
9
|
+
import re
|
|
10
|
+
|
|
11
|
+
CC_PATTERN = re.compile(
|
|
12
|
+
r"^(?P<type>[a-z]+)(?:\((?P<scope>[^)]*)\))?(?P<bang>!)?:\s*(?P<desc>.+)$"
|
|
13
|
+
)
|
|
14
|
+
|
|
15
|
+
SECTIONS = [
|
|
16
|
+
("feat", "Features"),
|
|
17
|
+
("fix", "Bug Fixes"),
|
|
18
|
+
("perf", "Performance"),
|
|
19
|
+
("refactor", "Refactoring"),
|
|
20
|
+
("docs", "Documentation"),
|
|
21
|
+
("test", "Tests"),
|
|
22
|
+
("build", "Build"),
|
|
23
|
+
("ci", "CI"),
|
|
24
|
+
("chore", "Chores"),
|
|
25
|
+
]
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
def group_commits(subjects):
|
|
29
|
+
"""Split subjects into (sections, breaking, other).
|
|
30
|
+
|
|
31
|
+
sections: {heading: [entry, ...]} in SECTIONS order, empty headings omitted.
|
|
32
|
+
breaking: entries whose type carried a `!`.
|
|
33
|
+
other: subjects that don't parse as conventional commits.
|
|
34
|
+
"""
|
|
35
|
+
by_type: dict = {}
|
|
36
|
+
breaking = []
|
|
37
|
+
other = []
|
|
38
|
+
|
|
39
|
+
for subject in subjects:
|
|
40
|
+
m = CC_PATTERN.match(subject.strip())
|
|
41
|
+
if not m:
|
|
42
|
+
other.append(subject.strip())
|
|
43
|
+
continue
|
|
44
|
+
scope = m.group("scope")
|
|
45
|
+
entry = f"**{scope}:** {m.group('desc')}" if scope else m.group("desc")
|
|
46
|
+
if m.group("bang"):
|
|
47
|
+
breaking.append(entry)
|
|
48
|
+
by_type.setdefault(m.group("type"), []).append(entry)
|
|
49
|
+
|
|
50
|
+
sections = {}
|
|
51
|
+
for ctype, heading in SECTIONS:
|
|
52
|
+
if ctype in by_type:
|
|
53
|
+
sections[heading] = by_type[ctype]
|
|
54
|
+
return sections, breaking, other
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
def build_changelog(subjects, label="Unreleased", date=None):
|
|
58
|
+
"""Render a markdown changelog block for one release."""
|
|
59
|
+
date = date or datetime.date.today().isoformat()
|
|
60
|
+
sections, breaking, other = group_commits(subjects)
|
|
61
|
+
|
|
62
|
+
lines = [f"## {label} ({date})", ""]
|
|
63
|
+
|
|
64
|
+
if breaking:
|
|
65
|
+
lines.append("### ⚠ Breaking Changes")
|
|
66
|
+
lines.append("")
|
|
67
|
+
lines.extend(f"- {e}" for e in breaking)
|
|
68
|
+
lines.append("")
|
|
69
|
+
|
|
70
|
+
for heading, entries in sections.items():
|
|
71
|
+
lines.append(f"### {heading}")
|
|
72
|
+
lines.append("")
|
|
73
|
+
lines.extend(f"- {e}" for e in entries)
|
|
74
|
+
lines.append("")
|
|
75
|
+
|
|
76
|
+
if other:
|
|
77
|
+
lines.append("### Other")
|
|
78
|
+
lines.append("")
|
|
79
|
+
lines.extend(f"- {e}" for e in other)
|
|
80
|
+
lines.append("")
|
|
81
|
+
|
|
82
|
+
if not sections and not breaking and not other:
|
|
83
|
+
lines.append("_No changes._")
|
|
84
|
+
lines.append("")
|
|
85
|
+
|
|
86
|
+
return "\n".join(lines)
|