diff options
author | Ben Pfaff <blp@ovn.org> | 2018-08-10 13:15:41 -0700 |
---|---|---|
committer | Ben Pfaff <blp@ovn.org> | 2018-08-13 14:52:42 -0700 |
commit | 3267343a84872dca7731a76d91357044f51fae35 (patch) | |
tree | 0dd69d04ff0e436264237ec7492b6259d476397b /utilities | |
parent | 2360464d629de3acacabd960ffc02fbb5081028d (diff) | |
download | openvswitch-3267343a84872dca7731a76d91357044f51fae35.tar.gz |
checkpatch: Improve accuracy and specificity of sign-off checking.
This also makes a start at a testsuite for checkpatch.
CC: Aaron Conole <aconole@redhat.com>
Signed-off-by: Ben Pfaff <blp@ovn.org>
Acked-by: Aaron Conole <aconole@bytheb.org>
Diffstat (limited to 'utilities')
-rwxr-xr-x | utilities/checkpatch.py | 70 |
1 files changed, 60 insertions, 10 deletions
diff --git a/utilities/checkpatch.py b/utilities/checkpatch.py index b2f27f5b7..48bd5eb97 100755 --- a/utilities/checkpatch.py +++ b/utilities/checkpatch.py @@ -668,7 +668,7 @@ def run_file_checks(text): check['check'](text) -def ovs_checkpatch_parse(text, filename): +def ovs_checkpatch_parse(text, filename, author=None, committer=None): global print_file_name, total_line, checking_file, \ empty_return_check_state @@ -686,6 +686,8 @@ def ovs_checkpatch_parse(text, filename): hunks = re.compile('^(---|\+\+\+) (\S+)') hunk_differences = re.compile( r'^@@ ([0-9-+]+),([0-9-+]+) ([0-9-+]+),([0-9-+]+) @@') + is_author = re.compile(r'^(Author|From): (.*)$', re.I | re.M | re.S) + is_committer = re.compile(r'^(Commit: )(.*)$', re.I | re.M | re.S) is_signature = re.compile(r'^(Signed-off-by: )(.*)$', re.I | re.M | re.S) is_co_author = re.compile(r'^(Co-authored-by: )(.*)$', @@ -718,13 +720,54 @@ def ovs_checkpatch_parse(text, filename): if seppatch.match(line): parse = PARSE_STATE_DIFF_HEADER if not skip_signoff_check: - if len(signatures) == 0: - print_error("No signatures found.") - elif len(signatures) != 1 + len(co_authors): - print_error("Too many signoffs; " - "are you missing Co-authored-by lines?") - if not set(co_authors) <= set(signatures): - print_error("Co-authored-by/Signed-off-by corruption") + + # Check that the patch has an author, that the + # author is not among the co-authors, and that the + # co-authors are unique. + if not author: + print_error("Patch lacks author.") + continue + if author in co_authors: + print_error("Author should not be also be co-author.") + continue + if len(set(co_authors)) != len(co_authors): + print_error("Duplicate co-author.") + + # Check that the author, all co-authors, and the + # committer (if any) signed off. + if author not in signatures: + print_error("Author %s needs to sign off." % author) + for ca in co_authors: + if ca not in signatures: + print_error("Co-author %s needs to sign off." % ca) + break + if (committer + and author != committer + and committer not in signatures): + print_error("Committer %s needs to sign off." + % committer) + + # Check for signatures that we do not expect. + # This is only a warning because there can be, + # rarely, a signature chain. + # + # If we don't have a known committer, and there is + # a single extra sign-off, then do not warn + # because that extra sign-off is probably the + # committer. + extra_sigs = [x for x in signatures + if x not in co_authors + and x != author + and x != committer] + if len(extra_sigs) > 1 or (committer and extra_sigs): + print_warning("Unexpected sign-offs from developers " + "who are not authors or co-authors or " + "committers: %s" + % ", ".join(extra_sigs)) + elif is_committer.match(line): + committer = is_committer.match(line).group(2) + elif is_author.match(line): + author = is_author.match(line).group(2) elif is_signature.match(line): m = is_signature.match(line) signatures.append(m.group(2)) @@ -815,7 +858,9 @@ def ovs_checkpatch_file(filename): for part in mail.walk(): if part.get_content_maintype() == 'multipart': continue - result = ovs_checkpatch_parse(part.get_payload(decode=False), filename) + result = ovs_checkpatch_parse(part.get_payload(decode=False), filename, + mail.get('Author', mail['From']), + mail['Commit']) ovs_checkpatch_print_result(result) return result @@ -890,7 +935,12 @@ if __name__ == '__main__': for i in reversed(range(0, n_patches)): revision, name = commits[i].split(" ", 1) - f = os.popen('git format-patch -1 --stdout %s' % revision, 'r') + f = os.popen('''git format-patch -1 --stdout --pretty=format:"\ +Author: %an <%ae> +Commit: %cn <%ce> +Subject: %s + +%b" ''' + revision, 'r') patch = f.read() f.close() |