Add check to ensure all patches are contributions

This essentially just checks that commit messages do not contain the
string 'not a contribution' as such patches cannot be accepted into
Chromium OS.

BUG=None
TEST=This commit message fails to upload.

Change-Id: Ica5e48dde7320a5a2e7c0bd234fbc98f57e90d49
Reviewed-on: https://chromium-review.googlesource.com/321798
Commit-Ready: Bernie Thompson <bhthompson@chromium.org>
Tested-by: Bernie Thompson <bhthompson@chromium.org>
Reviewed-by: Mike Frysinger <vapier@chromium.org>
diff --git a/pre-upload.py b/pre-upload.py
index a98b16c..b406f95 100755
--- a/pre-upload.py
+++ b/pre-upload.py
@@ -495,6 +495,15 @@
     return HookFailure(msg, [example, str(ex)])
 
 
+def _check_change_is_contribution(_project, commit):
+  """Check that the change is a contribution."""
+  NO_CONTRIB = 'not a contribution'
+  if NO_CONTRIB in _get_commit_desc(commit).lower():
+    msg = ('Changelist is not a contribution, this cannot be accepted.\n'
+           'Please remove the "%s" text from the commit message.') % NO_CONTRIB
+    return HookFailure(msg)
+
+
 def _check_change_has_bug_field(project, commit):
   """Check for a correctly formatted 'BUG=' field in the commit message."""
   OLD_BUG_RE = r'\nBUG=.*chromium-os'
@@ -1264,6 +1273,7 @@
     _check_change_has_test_field,
     _check_change_has_proper_changeid,
     _check_commit_message_style,
+    _check_change_is_contribution,
 ]
 
 
@@ -1308,6 +1318,7 @@
     'bug_field_check': _check_change_has_bug_field,
     'test_field_check': _check_change_has_test_field,
     'manifest_check': _check_manifests,
+    'contribution_check': _check_change_is_contribution,
 }
 
 
diff --git a/pre-upload_unittest.py b/pre-upload_unittest.py
index 36ec973..830b46e 100755
--- a/pre-upload_unittest.py
+++ b/pre-upload_unittest.py
@@ -778,6 +778,26 @@
     self.assertMessageRejected('\nCQ-DEPEND=None\n')
 
 
+class CheckCommitMessageContribution(CommitMessageTestCase):
+  """Tests for _check_change_is_contribution."""
+
+  @staticmethod
+  def CheckMessage(project, commit):
+    return pre_upload._check_change_is_contribution(project, commit)
+
+  def testNormal(self):
+    """Accept a commit message which is a contribution."""
+    self.assertMessageAccepted('\nThis is cool code I am contributing.\n')
+
+  def testFailureLowerCase(self):
+    """Deny a commit message which is not a contribution."""
+    self.assertMessageRejected('\nThis is not a contribution.\n')
+
+  def testFailureUpperCase(self):
+    """Deny a commit message which is not a contribution."""
+    self.assertMessageRejected('\nNOT A CONTRIBUTION\n')
+
+
 class CheckCommitMessageTest(CommitMessageTestCase):
   """Tests for _check_change_has_test_field."""