This repository has been archived by the owner on Jan 31, 2018. It is now read-only.
[bug 1108755] Add a git commit message linter #422
Merged
Merged
Changes from all commits
Commits
File filter
Filter by extension
Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
#!/bin/bash | ||
# | ||
# Run the commit message linters | ||
# | ||
# If this file is not in the `.git/hooks` directory, executing it will | ||
# prompt to install it. | ||
|
||
DIR=$(dirname $0) | ||
COMMIT_MSG_FILE=$1 | ||
|
||
function lint() { | ||
echo 'Linting the commit message...' | ||
./bin/lint_commit_msg.py $COMMIT_MSG_FILE | ||
LINT_STATUS=$? | ||
if [[ $LINT_STATUS -ne 0 ]]; then | ||
echo | ||
echo "Lint errors found. Please fix the above and retry." | ||
echo "Alternatively, run 'git commit --no-verify' to ignore lint errors." | ||
exit 1 | ||
fi | ||
} | ||
|
||
function install() { | ||
echo -ne "Would you like to install the commit message linter? " | ||
while true; do | ||
read yn | ||
case $yn in | ||
[Yy]* ) break;; | ||
[Nn]* ) exit 1;; | ||
* ) echo "Please enter 'y' or 'n'." | ||
esac | ||
done | ||
|
||
GITDIR=$(git rev-parse --git-dir) | ||
if [[ -e $GITDIR/hooks/commit-msg ]]; then | ||
echo "You already have a git commit message hook. Bailing." | ||
exit 1 | ||
fi | ||
|
||
ln -s ../../bin/hooks/lint.commit-msg $GITDIR/hooks/commit-msg | ||
} | ||
|
||
if echo $DIR | grep -E ".git/hooks$" > /dev/null; then | ||
lint | ||
else | ||
install | ||
fi |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,79 @@ | ||
#!/usr/bin/env python | ||
|
||
import sys | ||
import re | ||
|
||
import requests | ||
from requests.exceptions import ( | ||
ConnectionError, | ||
Timeout | ||
) | ||
|
||
BUG_PREFIX_REGEX = r'\[bug (\d+)\]' | ||
|
||
|
||
def are_lines_not_more_than_79_chars(contents): | ||
if filter(lambda x: len(x) > 79, contents): | ||
print('Error:') | ||
print('The commit message should not have more than ' | ||
'79 characters per line') | ||
return False | ||
return True | ||
|
||
|
||
def is_bug_number_in_right_format(contents): | ||
summary = contents[0] | ||
if (re.compile(r'\bbug\b', flags=re.IGNORECASE).search(summary) and | ||
re.search(r'\b#{0,1}\d+\b', summary)): | ||
bug_format_regex = re.compile(BUG_PREFIX_REGEX, | ||
flags=re.IGNORECASE) | ||
valid_bug_format = bug_format_regex.match(summary) | ||
if not valid_bug_format: | ||
print('Specify the bug number in the format ' | ||
'[bug xxxxxxx] at the beginning of the commit summary') | ||
return False | ||
return True | ||
|
||
|
||
def print_bug_info(contents): | ||
summary = contents[0] | ||
bug_id_regex = re.compile(BUG_PREFIX_REGEX, | ||
flags=re.IGNORECASE) | ||
is_a_bug = bug_id_regex.match(summary) | ||
if is_a_bug: | ||
bug_id = is_a_bug.group(1) | ||
url = 'https://bugzilla.mozilla.org/rest/bug/{}'.format(bug_id) | ||
try: | ||
response = requests.get(url, timeout=60.0) | ||
response_dict = response.json() | ||
if ('error' in response_dict and response_dict['error']): | ||
print('Bug with id {} not found.'.format(bug_id)) | ||
return False | ||
bug_info = response_dict['bugs'][0] | ||
print('{} - {}'.format(bug_id, | ||
bug_info['summary'])) | ||
print('Assigned to: {}'.format(bug_info['assigned_to'])) | ||
except ValueError: | ||
print('Error parsing response from Bugzilla REST API') | ||
except (ConnectionError, Timeout): | ||
print('Unable to contact Mozilla Bugzilla') | ||
return True | ||
|
||
LINT_FUNCTIONS = [is_bug_number_in_right_format, | ||
are_lines_not_more_than_79_chars, | ||
print_bug_info] | ||
|
||
|
||
def lint_commit_msg(commit_msg_file): | ||
with open(commit_msg_file) as commit_contents: | ||
commit_msg = commit_contents.readlines() | ||
return_values = map(lambda x: x(commit_msg), LINT_FUNCTIONS) | ||
if not all(return_values): | ||
return 1 | ||
return 0 | ||
|
||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Nit: Need an extra blank line here. It's probably worth running flake8 on this file. |
||
if __name__ == '__main__': | ||
commit_msg_file = sys.argv[1] | ||
errors_found = lint_commit_msg(commit_msg_file) | ||
if errors_found: | ||
sys.exit(1) |
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pretty sure this regex could be pulled into a "constant" because it's used in multiple places with slightly different forms.