Skip to content

Commit

Permalink
fixup! CI: Check commit message compliance
Browse files Browse the repository at this point in the history
  • Loading branch information
norihiro committed Mar 20, 2023
1 parent 33ae11b commit 0c0d876
Show file tree
Hide file tree
Showing 3 changed files with 137 additions and 81 deletions.
8 changes: 6 additions & 2 deletions .github/workflows/commit-msg.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,14 @@ jobs:
with:
fetch-depth: 0

- name: Setup environment
run: |
pip3 install -U gitpython
- name: Fetch OBS Studio master
run: |
git fetch https://github.com/obsproject/obs-studio.git
git fetch origin
- name: Check the log messages
run: |
git log FETCH_HEAD.. | ./CI/check-log-msg.awk -v GITHUB_EVENT_NAME=${{env.GITHUB_EVENT_NAME}}
./CI/check-log-msg.py origin/master..
79 changes: 0 additions & 79 deletions CI/check-log-msg.awk

This file was deleted.

131 changes: 131 additions & 0 deletions CI/check-log-msg.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
#! /bin/env python3

import git
import re

has_error = False

LOG_ERROR = 100
LOG_WARNING = 200
LOG_INFO = 300
current_commit = None

def blog(level, txt):
if level == LOG_ERROR:
global has_error
has_error = True
s_level = "Error: "
elif level == LOG_WARNING:
s_level = "Warning: "
elif level == LOG_INFO:
s_level = "Info: "
print('{level}commit {hexsha}: {txt}'.format(level = s_level, hexsha = current_commit.hexsha[:9], txt = txt))

def find_directory_name(name, tree, max_depth):
for t in tree.trees:
if name == t.name:
return True
if max_depth > 1:
for t in tree.trees:
if find_directory_name(name, t, max_depth - 1):
return True
for b in tree.blobs:
if name == b.name:
return True
return False

def check_path(path, tree):
paths = path.split('/', 1)
name = paths[0]
if len(paths) == 1:
return find_directory_name(name, tree, 1)
else:
for t in tree.trees:
if name == t.name:
return check_path(paths[1], t)
return False

def find_submodule_name(name, submodules):
for s in submodules:
sname = s.name.split('/')[-1]
if name == sname:
return True

def check_module_names(names):
for name in names:
if name.find('/') >= 0:
if check_path(name, current_commit.tree):
return True
else:
if find_directory_name(name, current_commit.tree, 3):
return True
# TODO: Cannot handle removed submodules. Implement to parse .gitmodules file.
if find_submodule_name(name, current_commit.repo.submodules):
return True
blog(LOG_ERROR, "unknown module name '%s'" % name)

def check_message_title(title):
global has_error
title_split = title.split(': ', 1)
if len(title_split) == 2:
check_module_names(re.split(r', *', title_split[0]))
title_text = title_split[1]
else:
title_text = title_split[0]

if len(title) > 72:
blog(LOG_ERROR, 'Too long title: %s' % title)

if len(title_text) > 50:
blog(LOG_WARNING, 'Too long title excluding module name: %s' % title_text)

if not re.match(r"([A-Z][a-z]*(-[a-z]+)*|Don't) ", title_text):
blog(LOG_ERROR, 'Invalid first word: %s' % title_text.split(' ', 1)[0])
has_error = True

def check_message_body(body):
for line in body.split('\n'):
if len(line) > 72 and line.find(' ') > 0:
blog(LOG_ERROR, 'Too long description in a line: %s' % line)
pass

def check_message(c):
msg = c.message.split('\n', 2)
if len(msg) == 0:
blog(LOG_ERROR, 'Commit message is empty.')
return True

if re.match(r'Revert ', msg[0]):
return False
if re.match(r'Merge [0-9a-f]{40} into [0-9a-f]{40}$', msg[0]):
return False
if re.match(r'Merge pull request', msg[0]):
return False

if len(msg) > 0:
check_message_title(msg[0])
if len(msg) > 1:
if len(msg[1]):
blog(LOG_ERROR, '2nd line is not empty.')
if len(msg) > 2:
check_message_body(msg[2])
return has_error

def main():
import sys
import argparse
parser = argparse.ArgumentParser(prog='check-log-msg.py', description='Log message compliance checker')
parser.add_argument('commits')
args = parser.parse_args()

repo = git.Repo('.')
global has_error
for c in repo.iter_commits(args.commits): # '27.1.0-rc2..27.1.0'):
global current_commit
current_commit = c
check_message(c)
if has_error:
sys.exit(1)

if __name__ == '__main__':
ret = main()

0 comments on commit 0c0d876

Please sign in to comment.