From b751d102f158968aab681cb663d27b4c32197f62 Mon Sep 17 00:00:00 2001 From: Ogulcan Celik Date: Tue, 2 Jun 2026 21:48:02 +0300 Subject: feat: add preview update channel --- scripts/conventional_commits.py | 74 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 74 insertions(+) create mode 100644 scripts/conventional_commits.py (limited to 'scripts/conventional_commits.py') 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[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()) -- cgit v1.2.3