X-Git-Url: https://git.proxmox.com/?a=blobdiff_plain;f=BaseTools%2FScripts%2FPatchCheck.py;h=13da6967785d45e0ab5186054f14d53682000379;hb=c37cce7a843dd8a77aa449b4763fd71c08837f81;hp=3b6d77081e7e08ae852d6e5a1d2d09bf7ca28dda;hpb=8ffa47fb3abd58ded6fe852ee9f518d19f9f9858;p=mirror_edk2.git diff --git a/BaseTools/Scripts/PatchCheck.py b/BaseTools/Scripts/PatchCheck.py index 3b6d77081e..13da696778 100755 --- a/BaseTools/Scripts/PatchCheck.py +++ b/BaseTools/Scripts/PatchCheck.py @@ -1,7 +1,7 @@ ## @file # Check a patch for various format issues # -# Copyright (c) 2015 - 2019, Intel Corporation. All rights reserved.
+# Copyright (c) 2015 - 2020, Intel Corporation. All rights reserved.
# Copyright (C) 2020, Red Hat, Inc.
# # SPDX-License-Identifier: BSD-2-Clause-Patent @@ -26,18 +26,22 @@ class Verbose: class EmailAddressCheck: """Checks an email address.""" - def __init__(self, email): + def __init__(self, email, description): self.ok = True if email is None: self.error('Email address is missing!') return + if description is None: + self.error('Email description is missing!') + return + self.description = "'" + description + "'" self.check_email_address(email) def error(self, *err): if self.ok and Verbose.level > Verbose.ONELINE: - print('The email address is not valid:') + print('The ' + self.description + ' email address is not valid:') self.ok = False if Verbose.level < Verbose.NORMAL: return @@ -75,6 +79,10 @@ class EmailAddressCheck: self.error("The email address cannot contain a space: " + mo.group(3)) + if ' via Groups.Io' in name and mo.group(3).endswith('@groups.io'): + self.error("Email rewritten by lists DMARC / DKIM / SPF: " + + email) + class CommitMessageCheck: """Checks the contents of a git commit message.""" @@ -88,6 +96,8 @@ class CommitMessageCheck: self.subject = subject self.msg = message + print (subject) + self.check_contributed_under() self.check_signed_off_by() self.check_misc_signatures() @@ -174,7 +184,7 @@ class CommitMessageCheck: if s[2] != ' ': self.error("There should be a space after '" + sig + ":'") - EmailAddressCheck(s[3]) + EmailAddressCheck(s[3], sig) return sigs @@ -204,6 +214,8 @@ class CommitMessageCheck: for sig in self.sig_types: self.find_signatures(sig) + cve_re = re.compile('CVE-[0-9]{4}-[0-9]{5}[^0-9]') + def check_overall_format(self): lines = self.msg.splitlines() @@ -221,9 +233,26 @@ class CommitMessageCheck: self.error('Empty commit message!') return - if count >= 1 and len(lines[0].rstrip()) >= 72: - self.error('First line of commit message (subject line) ' + - 'is too long.') + if count >= 1 and re.search(self.cve_re, lines[0]): + # + # If CVE-xxxx-xxxxx is present in subject line, then limit length of + # subject line to 92 characters + # + if len(lines[0].rstrip()) >= 93: + self.error( + 'First line of commit message (subject line) is too long (%d >= 93).' % + (len(lines[0].rstrip())) + ) + else: + # + # If CVE-xxxx-xxxxx is not present in subject line, then limit + # length of subject line to 75 characters + # + if len(lines[0].rstrip()) >= 76: + self.error( + 'First line of commit message (subject line) is too long (%d >= 76).' % + (len(lines[0].rstrip())) + ) if count >= 1 and len(lines[0].strip()) == 0: self.error('First line of commit message (subject line) ' + @@ -237,7 +266,14 @@ class CommitMessageCheck: if (len(lines[i]) >= 76 and len(lines[i].split()) > 1 and not lines[i].startswith('git-svn-id:')): - self.error('Line %d of commit message is too long.' % (i + 1)) + # + # Print a warning if body line is longer than 75 characters + # + print( + 'WARNING - Line %d of commit message is too long (%d >= 76).' % + (i + 1, len(lines[i])) + ) + print(lines[i]) last_sig_line = None for i in range(count - 1, 0, -1): @@ -309,7 +345,21 @@ class GitDiffCheck: self.state = PRE_PATCH self.filename = line[13:].split(' ', 1)[0] self.is_newfile = False - self.force_crlf = not self.filename.endswith('.sh') + self.force_crlf = True + self.force_notabs = True + if self.filename.endswith('.sh'): + # + # Do not enforce CR/LF line endings for linux shell scripts. + # + self.force_crlf = False + if self.filename == '.gitmodules': + # + # .gitmodules is updated by git and uses tabs and LF line + # endings. Do not enforce no tabs and do not enforce + # CR/LF line endings. + # + self.force_crlf = False + self.force_notabs = False elif len(line.rstrip()) != 0: self.format_error("didn't find diff command") self.line_num += 1 @@ -323,6 +373,11 @@ class GitDiffCheck: self.binary = True if self.is_newfile: self.new_bin.append(self.filename) + elif line.startswith('new file mode 160000'): + # + # New submodule. Do not enforce CR/LF line endings + # + self.force_crlf = False else: ok = False self.is_newfile = self.newfile_prefix_re.match(line) @@ -397,7 +452,7 @@ class GitDiffCheck: if self.force_crlf and eol != '\r\n': self.added_line_error('Line ending (%s) is not CRLF' % repr(eol), line) - if '\t' in line: + if self.force_notabs and '\t' in line: self.added_line_error('Tab character used', line) if len(stripped) < len(line): self.added_line_error('Trailing whitespace found', line) @@ -447,6 +502,9 @@ class CheckOnePatch: self.patch = patch self.find_patch_pieces() + email_check = EmailAddressCheck(self.author_email, 'Author') + email_ok = email_check.ok + msg_check = CommitMessageCheck(self.commit_subject, self.commit_msg) msg_ok = msg_check.ok @@ -455,7 +513,7 @@ class CheckOnePatch: diff_check = GitDiffCheck(self.diff) diff_ok = diff_check.ok - self.ok = msg_ok and diff_ok + self.ok = email_ok and msg_ok and diff_ok if Verbose.level == Verbose.ONELINE: if self.ok: @@ -528,11 +586,30 @@ class CheckOnePatch: else: self.stat = mo.group('stat') self.commit_msg = mo.group('commit_message') + # + # Parse subject line from email header. The subject line may be + # composed of multiple parts with different encodings. Decode and + # combine all the parts to produce a single string with the contents of + # the decoded subject line. + # + parts = email.header.decode_header(pmail.get('subject')) + subject = '' + for (part, encoding) in parts: + if encoding: + part = part.decode(encoding) + else: + try: + part = part.decode() + except: + pass + subject = subject + part - self.commit_subject = pmail['subject'].replace('\r\n', '') + self.commit_subject = subject.replace('\r\n', '') self.commit_subject = self.commit_subject.replace('\n', '') self.commit_subject = self.subject_prefix_re.sub('', self.commit_subject, 1) + self.author_email = pmail['from'] + class CheckGitCommits: """Reads patches from git based on the specified git revision range. @@ -552,6 +629,8 @@ class CheckGitCommits: else: blank_line = True print('Checking git commit:', commit) + email = self.read_committer_email_address_from_git(commit) + self.ok &= EmailAddressCheck(email, 'Committer').ok patch = self.read_patch_from_git(commit) self.ok &= CheckOnePatch(commit, patch).ok if not commits: @@ -568,7 +647,13 @@ class CheckGitCommits: def read_patch_from_git(self, commit): # Run git to get the commit patch - return self.run_git('show', '--pretty=email', '--no-textconv', commit) + return self.run_git('show', '--pretty=email', '--no-textconv', + '--no-use-mailmap', commit) + + def read_committer_email_address_from_git(self, commit): + # Run git to get the committer email + return self.run_git('show', '--pretty=%cn <%ce>', '--no-patch', + '--no-use-mailmap', commit) def run_git(self, *args): cmd = [ 'git' ]