fw4spl
check_commit.py
1 #!/usr/bin/env python2
2 # -*- coding: UTF-8 -*-
3 
4 import re
5 
6 import common
7 
8 
9 class _Const(object):
10  @apply
11  def TYPES():
12  def fset(self, value):
13  raise TypeError
14 
15  def fget(self):
16  return ['feat', 'fix', 'perf', 'revert', 'docs', 'chore', 'style', 'refactor', 'test', 'merge']
17 
18  return property(**locals())
19 
20 
21 CONST = _Const()
22 
23 
24 # return all unpushed commit message
25 def unpushed_commit_message():
26  command_result = common.execute_command('git log --branches --not --remotes --pretty=format:%h:%aE:%s')
27 
28  if command_result.status != 0:
29  return []
30  else:
31  return command_result.out.split('\n')
32 
33 
34 def commit_in_path(old_path=None, new_path=None):
35  git_command = 'git log --first-parent --pretty=format:%h:%aE:%s'
36 
37  if old_path is not None and len(old_path) > 0:
38  git_command += ' ' + old_path
39 
40  if new_path is not None and len(new_path) > 0:
41  git_command += '..' + new_path
42 
43  command_result = common.execute_command(git_command)
44 
45  if command_result.status != 0:
46  return []
47  else:
48  return command_result.out.split('\n')
49 
50 
51 # check the title conformance against commitizen/angularjs/... rules
52 def __check_commit_title(commit_hash, commit_title):
53  # Test the title against regex
54  title_pattern = re.compile(r'(?P<type>' + '|'.join(CONST.TYPES) + ')\((?P<scope>\S+)\):(?P<subject>.*)')
55  title_match = title_pattern.match(commit_title)
56 
57  # Convert into a boolean
58  title_have_not_matched = title_match is None
59 
60  if title_have_not_matched is True:
62  "Commit '"
63  + commit_hash
64  + "' with title '"
65  + commit_title
66  + "' does not follow Sheldon rules: '<" + "|".join(CONST.TYPES) + ">(<scope>): <subject>'.")
67 
68  return title_have_not_matched
69 
70 
71 # check that the author is not anonymous
72 def __check_commit_author(commit_hash, commit_author):
73  # Test the title against regex
74  author_pattern = re.compile(r'\.*anonymous\.*')
75  author_match = author_pattern.match(commit_author.lower())
76 
77  # Convert into a boolean
78  author_have_matched = author_match is not None
79 
80  if author_have_matched is True:
82  "Commit '"
83  + commit_hash
84  + "' has anonymous author.")
85 
86  return author_have_matched
87 
88 
89 def check_commit_messages(commit_messages):
90  results = [False]
91 
92  for commit_message in commit_messages:
93  # Split commit message according to "--pretty=format:%h:%aE:%s"
94  split_message = commit_message.split(':', 2)
95 
96  if len(split_message) == 3:
97  # Extract the type
98  commit_hash = split_message[0]
99  commit_author = split_message[1]
100  commit_title = split_message[2]
101 
102  results.append(__check_commit_title(commit_hash, commit_title))
103  results.append(__check_commit_author(commit_hash, commit_author))
104 
105  common.note('%d commit(s) checked, %d error(s) found.' % (len(commit_messages), results.count(True)))
106 
107  return results
def error(msg)
Definition: common.py:52
def note(msg)
Definition: common.py:43
def execute_command(proc)
Definition: common.py:132