validate_commit_message_author.py
92 lines
| 3.4 KiB
| text/x-python
|
PythonLexer
r3211 | # Example to validate commit message or author using some sort of rules | |||
@has_kwargs({ | ||||
'server_url': 'url of instance that triggered this hook', | ||||
'config': 'path to .ini config used', | ||||
'scm': 'type of version control "git", "hg", "svn"', | ||||
'username': 'username of actor who triggered this event', | ||||
'ip': 'ip address of actor who triggered this hook', | ||||
'action': '', | ||||
'repository': 'repository name', | ||||
'repo_store_path': 'full path to where repositories are stored', | ||||
'commit_ids': 'pre transaction metadata for commit ids', | ||||
'hook_type': '', | ||||
'user_agent': 'Client user agent, e.g git or mercurial CLI version', | ||||
}) | ||||
@has_kwargs({ | ||||
'server_url': 'url of instance that triggered this hook', | ||||
'config': 'path to .ini config used', | ||||
'scm': 'type of version control "git", "hg", "svn"', | ||||
'username': 'username of actor who triggered this event', | ||||
'ip': 'ip address of actor who triggered this hook', | ||||
'action': '', | ||||
'repository': 'repository name', | ||||
'repo_store_path': 'full path to where repositories are stored', | ||||
'commit_ids': 'pre transaction metadata for commit ids', | ||||
'hook_type': '', | ||||
'user_agent': 'Client user agent, e.g git or mercurial CLI version', | ||||
}) | ||||
def _pre_push_hook(*args, **kwargs): | ||||
""" | ||||
Post push hook | ||||
To stop version control from storing the transaction and send a message to user | ||||
use non-zero HookResponse with a message, e.g return HookResponse(1, 'Not allowed') | ||||
This message will be shown back to client during PUSH operation | ||||
Commit ids might look like that:: | ||||
[{u'hg_env|git_env': ..., | ||||
u'multiple_heads': [], | ||||
u'name': u'default', | ||||
u'new_rev': u'd0befe0692e722e01d5677f27a104631cf798b69', | ||||
u'old_rev': u'd0befe0692e722e01d5677f27a104631cf798b69', | ||||
u'ref': u'', | ||||
u'total_commits': 2, | ||||
u'type': u'branch'}] | ||||
""" | ||||
import re | ||||
from .helpers import extra_fields, extract_pre_commits | ||||
from .utils import str2bool | ||||
# returns list of dicts with key-val fetched from extra fields | ||||
repo_extra_fields = extra_fields.run(**kwargs) | ||||
# optionally use 'extra fields' to control the logic per repo | ||||
r3365 | validate_author = repo_extra_fields.get('validate_author', {}).get('field_value') | |||
should_validate = str2bool(validate_author) | ||||
r3211 | ||||
# optionally store validation regex into extra fields | ||||
r3365 | validation_regex = repo_extra_fields.get('validation_regex', {}).get('field_value') | |||
r3211 | ||||
def validate_commit_message(commit_message, message_regex=None): | ||||
""" | ||||
This function validates commit_message against some sort of rules. | ||||
It should return a valid boolean, and a reason for failure | ||||
""" | ||||
if "secret_string" in commit_message: | ||||
msg = "!!Push forbidden: secret string found in commit messages" | ||||
return False, msg | ||||
if validation_regex: | ||||
regexp = re.compile(validation_regex) | ||||
if not regexp.match(message): | ||||
msg = "!!Push forbidden: commit message does not match regexp" | ||||
return False, msg | ||||
return True, '' | ||||
if should_validate: | ||||
# returns list of dicts with key-val fetched from extra fields | ||||
commit_list = extract_pre_commits.run(**kwargs) | ||||
for commit_data in commit_list: | ||||
message = commit_data['message'] | ||||
message_valid, reason = validate_commit_message(message, validation_regex) | ||||
if not message_valid: | ||||
return HookResponse(1, reason) | ||||
return HookResponse(0, '') | ||||