11#!/usr/bin/env python
22
33from __future__ import print_function
4+ import io
45import sys
56
67MAX_SLEN = 52
78MAX_OLEN = 72
89
10+ LABEL_TO_TAG = {
11+ 'Closes-Bug' : set (['[BUGFIX]' ]),
12+ 'DocImpact' : set (['[SECURITY]' , '[TASK]' ]),
13+ 'Implements' : set (['[FEATURE]' ]),
14+ 'Partial-Bug' : set (['[BUGFIX]' ]),
15+ 'Related-Bug' : set (['[BUGFIX]' , '[FEATURE]' ]),
16+ 'SecurityImpact' : set (['[SECURITY]' ]),
17+ 'UpgradeImpact' : set (),
18+ }
19+
20+ for key in LABEL_TO_TAG .keys ():
21+ LABEL_TO_TAG [key ].add ('[API]' )
22+ LABEL_TO_TAG [key ].add ('[CONF]' )
23+ LABEL_TO_TAG [key ].add ('[DB]' )
24+
25+
26+ def good_labels (subject_tags , labels ):
27+ label_tags = set ()
28+
29+ for label in labels :
30+ label_tags .update (LABEL_TO_TAG [label ])
31+
32+ if subject_tags .issubset (label_tags ):
33+ return True
34+ elif '[TASK]' in subject_tags and len (label_tags ) == 0 :
35+ return True
36+ else :
37+ return False
38+
939
1040def analyze_tags (line ):
1141 invalid_tags = []
@@ -45,8 +75,7 @@ def verify_subject_length(subject_line):
4575 exit (1 )
4676
4777
48- def verify_subject_tags (subject_line ):
49- invalid_tags , required_tags , _ = analyze_tags (subject_line )
78+ def verify_subject_tags (invalid_tags , required_tags ):
5079 num_invalid = len (invalid_tags )
5180 num_require = len (required_tags )
5281
@@ -72,40 +101,42 @@ def verify_other_lengths(other_lines):
72101 exit (5 )
73102
74103
75- def verify_metadata (last_line ):
76- try :
77- metadata_label , _ = last_line .split (':' )
78-
79- if metadata_label not in ('Closes-Bug' ,
80- 'Partial-Bug' ,
81- 'Related-Bug' ,
82- 'Implements' ,
83- 'UpgradeImpact' ,
84- 'SecurityImpact' ,
85- 'DocImpact' ):
86- warning ('Invalid metadata label: %s' % metadata_label )
87- exit (6 )
88- except ValueError :
89- warning ('Corresponding metadata label is missing' )
104+ def verify_metadata (valid_tags , last_lines ):
105+ subject_tags = set (valid_tags )
106+ subject_tags .discard ('[!!!]' )
107+
108+ if '[TASK]' not in subject_tags and len (last_lines ) == 0 :
109+ warning ('Required metadata tags' )
110+ exit (6 )
111+
112+ labels = map (lambda l : l .split (':' )[0 ], last_lines )
113+
114+ if good_labels (subject_tags , labels ) is False :
115+ warning ('Invalid metadata label(s)' )
90116 exit (7 )
91117
92118
93119def main ():
120+
94121 commit_flname = sys .argv [1 ]
95- commit_fl = open (commit_flname )
96-
97- try :
98- subject_line = commit_fl .readline ()
99- other_lines = commit_fl .readlines ()
100- last_line = other_lines [- 1 ]
101- except IndexError :
102- warning ('One-liners are unacceptable' )
103- exit (8 )
104-
105- verify_subject_length (subject_line )
106- verify_subject_tags (subject_line )
107- verify_other_lengths (other_lines )
108- verify_metadata (last_line )
122+
123+ with io .open (commit_flname ) as fl :
124+ commit_fl = fl .read ().splitlines ()
125+ subject_line = commit_fl .pop (0 )
126+ i_tags , r_tags , s_tags = analyze_tags (subject_line )
127+
128+ last_lines = filter (
129+ lambda l : len (l .split (':' )) == 2 , commit_fl )
130+
131+ valid_tags = r_tags + s_tags
132+
133+ verify_subject_length (subject_line )
134+ verify_subject_tags (i_tags , r_tags )
135+
136+ if len (commit_fl ) > 1 :
137+ verify_other_lengths (commit_fl )
138+
139+ verify_metadata (valid_tags , last_lines )
109140
110141if __name__ == '__main__' :
111142 main ()
0 commit comments