diff options
| author | Ogulcan Celik <ogulcancelik@gmail.com> | 2026-06-02 21:48:02 +0300 |
|---|---|---|
| committer | Ogulcan Celik <ogulcancelik@gmail.com> | 2026-06-02 21:48:02 +0300 |
| commit | b751d102f158968aab681cb663d27b4c32197f62 (patch) | |
| tree | 85d03609314559df7705c2cb0ab4e37ab6d9715f /scripts/conventional_commits.py | |
| parent | 295b09ca25edbccac65401ee84fa420dd3888aad (diff) | |
feat: add preview update channel
Diffstat (limited to 'scripts/conventional_commits.py')
| -rw-r--r-- | scripts/conventional_commits.py | 74 |
1 files changed, 74 insertions, 0 deletions
diff --git a/scripts/conventional_commits.py b/scripts/conventional_commits.py new file mode 100644 index 00000000..3c61d49b --- /dev/null +++ b/scripts/conventional_commits.py @@ -0,0 +1,74 @@ +#!/usr/bin/env python3 +from __future__ import annotations + +import argparse +import re +import subprocess +from pathlib import Path + +ALLOWED_TYPES = { + "feat", + "fix", + "perf", + "docs", + "ci", + "test", + "refactor", + "chore", + "release", +} +SUBJECT_RE = re.compile(r"^(?P<kind>[a-z]+)(?:\([^)]+\))?!?:\s+\S") + + +def git_subjects(rev_range: str) -> list[str]: + output = subprocess.check_output( + ["git", "log", "--pretty=format:%s", rev_range], text=True + ).strip() + return [line.strip() for line in output.splitlines() if line.strip()] + + +def valid_subject(subject: str) -> bool: + match = SUBJECT_RE.match(subject) + return bool(match and match.group("kind") in ALLOWED_TYPES) + + +def commit_message_subject(path: Path) -> str | None: + for line in path.read_text(encoding="utf-8").splitlines(): + subject = line.strip() + if subject and not subject.startswith("#"): + return subject + return None + + +def main() -> int: + parser = argparse.ArgumentParser(description="Validate conventional commit subjects") + parser.add_argument("subjects", nargs="*") + parser.add_argument("--range", dest="rev_range") + parser.add_argument("--message-file") + args = parser.parse_args() + + subjects = list(args.subjects) + if args.rev_range: + subjects.extend(git_subjects(args.rev_range)) + if args.message_file: + subject = commit_message_subject(Path(args.message_file)) + if subject: + subjects.append(subject) + + invalid = [subject for subject in subjects if not valid_subject(subject)] + if invalid: + print("invalid commit subject(s):") + for subject in invalid: + print(f" {subject}") + print( + "commit subjects must use conventional commits because preview notes are generated from them." + ) + print("example: fix(update): install selected channel") + print("expected: type(optional-scope): subject") + print("allowed types: " + ", ".join(sorted(ALLOWED_TYPES))) + return 1 + return 0 + + +if __name__ == "__main__": + raise SystemExit(main()) |
