Coverage for conventional_commits_check.py: 0%

31 statements  

« prev     ^ index     » next       coverage.py v7.9.1, created at 2025-06-21 15:08 +0000

1#!/usr/bin/env python3 

2import argparse 

3import re 

4import string 

5import sys 

6 

7 

8RED = "\033[31m" 

9 

10COMMIT_TYPES = { 

11 'feat': r'^feat(\(.+\))?:', 

12 'fix': r'^fix(\(.+\))?:', 

13 'docs': r'^docs(\(.+\))?:', 

14 'style': r'^style(\(.+\))?:', 

15 'refactor': r'^refactor(\(.+\))?:', 

16 'perf': r'^perf(\(.+\))?:', 

17 'test': r'^test(\(.+\))?:', 

18 'build': r'^build(\(.+\))?:', 

19 'ci': r'^ci(\(.+\))?:', 

20 'chore': r'^chore(\(.+\))?:', 

21 'revert': '^revert: ', 

22} 

23 

24EMOJIS = { 

25 'feat': '✨', 

26 'fix': '🐛', 

27 'docs': '📚', 

28 'style': '💅', 

29 'refactor': '🧹', 

30 'perf': '🚀', 

31 'test': '🧪', 

32 'build': '🏗️', 

33 'ci': '👷', 

34 'chore': '♻️', 

35 'revert': '⏪', 

36 'merge': '🔀', 

37} 

38 

39 

40def main(): 

41 parser = argparse.ArgumentParser() 

42 parser.add_argument('commit_message_file') 

43 args = parser.parse_args() 

44 

45 with open(args.commit_message_file) as file: 

46 commit_message = file.read() 

47 

48 commit_message = commit_message.strip(string.whitespace + ''.join(EMOJIS.values())) 

49 

50 commit_type = None 

51 for commit, pattern in COMMIT_TYPES.items(): 

52 if re.match(pattern, commit_message): 

53 commit_type = commit 

54 break 

55 

56 if not commit_type: 

57 print( 

58 f'{RED}Commit message does not follow Conventional Commits rules.\n' \ 

59 f'It must begin with : {", ".join(COMMIT_TYPES.keys())}' 

60 ) 

61 sys.exit(1) 

62 

63 emoji = EMOJIS.get(commit_type) 

64 

65 if emoji: 

66 new_commit_message = f'{emoji} {commit_message}' 

67 with open(args.commit_message_file, 'w') as file: 

68 file.write(new_commit_message) 

69 

70 print('Commit message follows Conventional Commits rules and has been updated with an emoji.') 

71 sys.exit(0) 

72 

73 

74if __name__ == '__main__': 

75 main()