checkpatch: require commit text

Commit text is almost always necessary to explain why a change is
needed. Exceptions are rare enough that these can be granted through
manual checkpatch overrides.

Change-Id: I926b2276f717940c2fec77a6709fa3088b1bf0c3
Signed-off-by: Steve Muckle <smuckle@codeaurora.org>
Signed-off-by: Stepan Moskovchenko <stepanm@codeaurora.org>
diff --git a/scripts/checkpatch.pl b/scripts/checkpatch.pl
index b6d2977..07d8643 100755
--- a/scripts/checkpatch.pl
+++ b/scripts/checkpatch.pl
@@ -12,9 +12,10 @@
 use Term::ANSIColor qw(:constants);
 
 use constant BEFORE_SHORTTEXT => 0;
-use constant IN_SHORTTEXT => 1;
-use constant AFTER_SHORTTEXT => 2;
-use constant CHECK_NEXT_SHORTTEXT => 3;
+use constant IN_SHORTTEXT_BLANKLINE => 1;
+use constant IN_SHORTTEXT => 2;
+use constant AFTER_SHORTTEXT => 3;
+use constant CHECK_NEXT_SHORTTEXT => 4;
 use constant SHORTTEXT_LIMIT => 75;
 
 my $P = $0;
@@ -2152,6 +2153,7 @@
 	my $camelcase_file_seeded = 0;
 	my $shorttext = BEFORE_SHORTTEXT;
 	my $shorttext_exspc = 0;
+	my $commit_text_present = 0;
 
 	sanitise_line_reset();
 	cleanup_continuation_headers();
@@ -2345,8 +2347,26 @@
 		my $hereprev = "$here\n$prevrawline\n$rawline\n";
 
 		if ($shorttext != AFTER_SHORTTEXT) {
+			if ($shorttext == IN_SHORTTEXT_BLANKLINE && $line=~/\S/) {
+				# the subject line was just processed,
+				# a blank line must be next
+				WARN("NONBLANK_AFTER_SUMMARY",
+				     "non-blank line after summary line\n" . $herecurr);
+				$shorttext = IN_SHORTTEXT;
+				# this non-blank line may or may not be commit text -
+				# a warning has been generated so assume it is commit
+				# text and move on
+				$commit_text_present = 1;
+				# fall through and treat this line as IN_SHORTTEXT
+			}
 			if ($shorttext == IN_SHORTTEXT) {
 				if ($line=~/^---/ || $line=~/^diff.*/) {
+					if ($commit_text_present == 0) {
+						WARN("NO_COMMIT_TEXT",
+						     "please add commit text explaining " .
+						     "*why* the change is needed\n" .
+						     $herecurr);
+					}
 					$shorttext = AFTER_SHORTTEXT;
 				} elsif (length($line) > (SHORTTEXT_LIMIT +
 							  $shorttext_exspc)
@@ -2357,7 +2377,23 @@
 					     "commit text line over " .
 					     SHORTTEXT_LIMIT .
 					     " characters\n" . $herecurr);
+				} elsif ($line=~/^\s*[\x21-\x39\x3b-\x7e]+:/) {
+					# this is a tag, there must be commit
+					# text by now
+					if ($commit_text_present == 0) {
+						WARN("NO_COMMIT_TEXT",
+						     "please add commit text explaining " .
+						     "*why* the change is needed\n" .
+						     $herecurr);
+						# prevent duplicate warnings
+						$commit_text_present = 1;
+					}
+				} elsif ($line=~/\S/) {
+					$commit_text_present = 1;
 				}
+			} elsif ($shorttext == IN_SHORTTEXT_BLANKLINE) {
+				# case of non-blank line in this state handled above
+				$shorttext = IN_SHORTTEXT;
 			} elsif ($shorttext == CHECK_NEXT_SHORTTEXT) {
 # The Subject line doesn't have to be the last header in the patch.
 # Avoid moving to the IN_SHORTTEXT state until clear of all headers.
@@ -2365,7 +2401,7 @@
 # text which looks like a header is definitely a header.
 				if ($line!~/^[\x21-\x39\x3b-\x7e]+:/) {
 					$shorttext = IN_SHORTTEXT;
-# Check for Subject line followed by a blank line.
+					# Check for Subject line followed by a blank line.
 					if (length($line) != 0) {
 						WARN("NONBLANK_AFTER_SUMMARY",
 						     "non-blank line after " .
@@ -2373,9 +2409,18 @@
 						     $sublinenr . $here .
 						     "\n" . $subjectline .
 						     "\n" . $line . "\n");
+						# this non-blank line may or may not
+						# be commit text - a warning has been
+						# generated so assume it is commit
+						# text and move on
+						$commit_text_present = 1;
 					}
 				}
+			# The next two cases are BEFORE_SHORTTEXT.
 			} elsif ($line=~/^Subject: \[[^\]]*\] (.*)/) {
+				# This is the subject line. Go to
+				# CHECK_NEXT_SHORTTEXT to wait for the commit
+				# text to show up.
 				$shorttext = CHECK_NEXT_SHORTTEXT;
 				$subjectline = $line;
 				$sublinenr = "#$linenr & ";
@@ -2387,7 +2432,10 @@
 					     " characters\n" . $herecurr);
 				}
 			} elsif ($line=~/^    (.*)/) {
-				$shorttext = IN_SHORTTEXT;
+				# Indented format, this must be the summary
+				# line (i.e. git show). There will be no more
+				# headers so we are now in the shorttext.
+				$shorttext = IN_SHORTTEXT_BLANKLINE;
 				$shorttext_exspc = 4;
 				if (length($1) > SHORTTEXT_LIMIT) {
 					WARN("LONG_SUMMARY_LINE",