diff --git a/contrib/check-valid-commit.py b/contrib/check-valid-commit.py new file mode 100755 index 0000000000..ca1785ecdb --- /dev/null +++ b/contrib/check-valid-commit.py @@ -0,0 +1,104 @@ +#!/usr/bin/env python +import commands +import getopt +import sys + + +SSH_USER = 'bot' +SSH_HOST = 'localhost' +SSH_PORT = 29418 +SSH_COMMAND = 'ssh %s@%s -p %d gerrit approve ' % (SSH_USER, SSH_HOST, SSH_PORT) +FAILURE_SCORE = '--code-review=-2' +FAILURE_MESSAGE = 'This commit message does not match the standard.' \ + + ' Please correct the commit message and upload a replacement patch.' +PASS_SCORE = '--code-review=0' +PASS_MESSAGE = '' + +def main(): + change = None + project = None + branch = None + commit = None + patchset = None + + try: + opts, args = getopt.getopt(sys.argv[1:], '', \ + ['change=', 'project=', 'branch=', 'commit=', 'patchset=']) + except getopt.GetoptError, err: + print 'Error: %s' % (err) + usage() + sys.exit(-1) + + for arg, value in opts: + if arg == '--change': + change = value + elif arg == '--project': + project = value + elif arg == '--branch': + branch = value + elif arg == '--commit': + commit = value + elif arg == '--patchset': + patchset = value + else: + print 'Error: option %s not recognized' % (arg) + usage() + sys.exit(-1) + + if change == None or project == None or branch == None \ + or commit == None or patchset == None: + usage() + sys.exit(-1) + + command = 'git cat-file commit %s' % (commit) + status, output = commands.getstatusoutput(command) + + if status != 0: + print 'Error running \'%s\'. status: %s, output:\n\n%s' % \ + (command, status, output) + sys.exit(-1) + + commitMessage = output[(output.find('\n\n')+2):] + commitLines = commitMessage.split('\n') + + if len(commitLines) > 1 and len(commitLines[1]) != 0: + fail(commit, 'Invalid commit summary. The summary must be ' \ + + 'one line followed by a blank line.') + + i = 0 + for line in commitLines: + i = i + 1 + if len(line) > 80: + fail(commit, 'Line %d is over 80 characters.' % i) + + passes(commit) + +def usage(): + print 'Usage:\n' + print sys.argv[0] + ' --change --project ' \ + + '--branch --commit --patchset ' + +def fail( commit, message ): + command = SSH_COMMAND + FAILURE_SCORE + ' -m \\\"' \ + + _shell_escape( FAILURE_MESSAGE + '\n\n' + message) \ + + '\\\" ' + commit + commands.getstatusoutput(command) + sys.exit(1) + +def passes( commit ): + command = SSH_COMMAND + PASS_SCORE + ' -m \\\"' \ + + _shell_escape(PASS_MESSAGE) + ' \\\" ' + commit + commands.getstatusoutput(command) + +def _shell_escape(x): + s = '' + for c in x: + if c in '\n': + s = s + '\\\"$\'\\n\'\\\"' + else: + s = s + c + return s + +if __name__ == '__main__': + main() +