Add back in git commit message checking.

Change-Id: If608a117b9584c1138b5fbbdd56599922bdfa49e
Reviewed-on: https://review.openstack.org/28219
Reviewed-by: Joe Gordon <jogo@cloudscaling.com>
Approved: Sean Dague <sean@dague.net>
Reviewed-by: Sean Dague <sean@dague.net>
Tested-by: Jenkins
This commit is contained in:
Monty Taylor 2013-05-03 18:18:30 -04:00 committed by Jenkins
parent ec4833b206
commit 78cb53f086
3 changed files with 87 additions and 38 deletions

View File

@ -536,22 +536,32 @@ def hacking_not_in(logical_line):
yield (logical_line.find('not'), "H902: Use the 'not in' "
"operator for collection membership evaluation")
_has_run_registry = dict()
def once_git_check_commit_title():
"""Check git commit messages.
nova HACKING recommends not referencing a bug or blueprint in first line,
it should provide an accurate description of the change
H801
H802 Title limited to 72 chars
"""
#Get title of most recent commit
class GlobalCheck(object):
"""Base class for checks that should be run only once."""
subp = subprocess.Popen(['git', 'log', '--no-merges', '--pretty=%s', '-1'],
stdout=subprocess.PIPE)
title = subp.communicate()[0]
if subp.returncode:
raise Exception("git log failed with code %s" % subp.returncode)
version = '0.0.1'
def run(self):
"""Make run a no-op if run() has been called before.
Store in a global registry the list of checks we've run. If we have
run that one before, just skip doing anything the subsequent times.
This way, since pep8 is file/line based, we don't wind up re-running
a check on a git commit message over and over again.
"""
global _has_run_registry
if self.name not in _has_run_registry.keys():
_has_run_registry[self.name] = True
ret = self.run_once()
if ret is not None:
for r in ret:
yield ret
class GitCheck(GlobalCheck):
#From https://github.com/openstack/openstack-ci-puppet
# /blob/master/modules/gerrit/manifests/init.pp#L74
@ -561,29 +571,66 @@ def once_git_check_commit_title():
'([Bb]lue[Pp]rint|[Bb][Pp])[\s\#:]*([A-Za-z0-9\\-]+)')
GIT_REGEX = re.compile(git_keywords)
error = False
#NOTE(jogo) if match regex but over 3 words, acceptable title
if GIT_REGEX.search(title) is not None and len(title.split()) <= 3:
print ("H801: git commit title ('%s') should provide an accurate "
"description of the change, not just a reference to a bug "
"or blueprint" % title.strip())
error = True
# HACKING.rst recommends commit titles 50 chars or less, but enforces
# a 72 character limit
if len(title.decode('utf-8')) > 72:
print ("H802: git commit title ('%s') should be under 50 chars"
% title.strip())
error = True
return error
def __init__(self, tree, *args):
pass
@classmethod
def add_options(cls, parser):
parser.add_option('--git-message', action='store_true',
default=False, dest='git_message',
help="Check for well-formed git commit messages")
parser.config_options.append('git-message')
def _get_commit_title(self):
if not os.path.exists('.git'):
return None
@classmethod
def parse_options(cls, options):
if options.git_message:
once_git_check_commit_title()
#Get title of most recent commit
subp = subprocess.Popen(
['git', 'log', '--no-merges', '--pretty=%s', '-1'],
stdout=subprocess.PIPE)
title = subp.communicate()[0]
if subp.returncode:
raise Exception("git log failed with code %s" % subp.returncode)
return title
class OnceGitCheckCommitTitleBug(GitCheck):
"""Check git commit messages for bugs.
nova HACKING recommends not referencing a bug or blueprint in first line,
it should provide an accurate description of the change
H801
"""
name = "GitCheckCommitTitleBug"
def __init__(self, tree, *args):
pass
def run_once(self):
title = self._get_commit_title()
#NOTE(jogo) if match regex but over 3 words, acceptable title
if (title and self.GIT_REGEX.search(title) is not None
and len(title.split()) <= 3):
return(1, 0,
"H801: git commit title ('%s') should provide an accurate "
"description of the change, not just a reference to a bug "
"or blueprint" % title.strip(), self.name)
class OnceGitCheckCommitTitleLength(GitCheck):
"""Check git commit message length.
HACKING.rst recommends commit titles 50 chars or less, but enforces
a 72 character limit
H802 Title limited to 72 chars
"""
name = "GitCheckCommitTitleLength"
def __init__(self, tree, *args):
pass
def run_once(self):
title = self._get_commit_title()
if title and len(title.decode('utf-8')) > 72:
return(
1, 0,
"H802: git commit title ('%s') should be under 50 chars"
% title.strip(),
self.name)

View File

@ -37,6 +37,8 @@ flake8.extension =
H404 = hacking.core:hacking_docstring_multiline_start
H601 = hacking.core:hacking_no_cr
H700 = hacking.core:hacking_localization_strings
H801 = hacking.core:OnceGitCheckCommitTitleBug
H802 = hacking.core:OnceGitCheckCommitTitleLength
H901 = hacking.core:hacking_is_not
H902 = hacking.core:hacking_not_in

View File

@ -27,5 +27,5 @@ commands =
commands = {posargs}
[flake8]
exclude = .venv,.tox,dist,doc,*.egg
exclude = .venv,.tox,dist,doc,*.egg,build
show-source = true