Filtering of hooks for commit or push stages

This commit is contained in:
Barry Steyn
2015-10-02 12:54:25 -07:00
committed by Travis CI
parent e3a22061c5
commit dd73ffd02f
8 changed files with 89 additions and 3 deletions

View File

@@ -25,6 +25,13 @@ MANIFEST_JSON_SCHEMA = {
'language_version': {'type': 'string', 'default': 'default'},
'files': {'type': 'string'},
'expected_return_value': {'type': 'number', 'default': 0},
'stages': {
'type': 'array',
'default': [],
'items': {
'type': 'string',
},
},
'args': {
'type': 'array',
'default': [],

View File

@@ -20,10 +20,11 @@ PREVIOUS_IDENTIFYING_HASHES = (
'4d9958c90bc262f47553e2c073f14cfe',
'd8ee923c46731b42cd95cc869add4062',
'49fd668cb42069aa1b6048464be5d395',
'79f09a650522a87b0da915d0d983b2de'
)
IDENTIFYING_HASH = '79f09a650522a87b0da915d0d983b2de'
IDENTIFYING_HASH = 'e358c9dae00eac5d06b38dfdb1e33a8c'
def is_our_pre_commit(filename):

View File

@@ -175,6 +175,7 @@ def run(runner, args, write=sys_stdout_write_wrapper, environ=os.environ):
with ctx:
repo_hooks = list(get_repo_hooks(runner))
if args.hook:
repo_hooks = [
(repo, hook) for repo, hook in repo_hooks
@@ -183,4 +184,11 @@ def run(runner, args, write=sys_stdout_write_wrapper, environ=os.environ):
if not repo_hooks:
write('No hook with id `{0}`\n'.format(args.hook))
return 1
# Filter hooks for stages
repo_hooks = [
(repo, hook) for repo, hook in repo_hooks
if not hook['stages'] or args.hook_stage in hook['stages']
]
return _run_hooks(repo_hooks, args, write, environ)

View File

@@ -87,7 +87,6 @@ def main(argv=None):
run_parser.add_argument(
'--verbose', '-v', action='store_true', default=False,
)
run_parser.add_argument(
'--origin', '-o',
help='The origin branch\'s commit_id when using `git push`',
@@ -101,6 +100,10 @@ def main(argv=None):
help='Allow an unstaged config to be present. Note that this will'
'be stashed before parsing unless --no-stash is specified'
)
run_parser.add_argument(
'--hook-stage', choices=('commit', 'push'), default='commit',
help='The stage during which the hook is fired e.g. commit or push'
)
run_mutex_group = run_parser.add_mutually_exclusive_group(required=False)
run_mutex_group.add_argument(
'--all-files', '-a', action='store_true', default=False,

View File

@@ -1,6 +1,6 @@
#!/usr/bin/env bash
# This is a randomish md5 to identify this script
# 79f09a650522a87b0da915d0d983b2de
# e358c9dae00eac5d06b38dfdb1e33a8c
pushd `dirname $0` > /dev/null
HERE=`pwd`

View File

@@ -10,3 +10,5 @@ do
fi
fi
done
args="$args --hook-stage push"

View File

@@ -59,6 +59,7 @@ def _get_opts(
origin='',
source='',
allow_unstaged_config=False,
hook_stage='commit'
):
# These are mutually exclusive
assert not (all_files and files)
@@ -68,6 +69,7 @@ def _get_opts(
color=color,
verbose=verbose,
hook=hook,
hook_stage=hook_stage,
no_stash=no_stash,
origin=origin,
source=source,
@@ -89,6 +91,7 @@ def _test_run(repo, options, expected_outputs, expected_ret, stage):
stage_a_file()
args = _get_opts(**options)
ret, printed = _do_run(repo, args)
assert ret == expected_ret, (ret, expected_ret, printed)
for expected_output_part in expected_outputs:
assert expected_output_part in printed
@@ -371,6 +374,66 @@ def test_lots_of_files(mock_out_store_directory, tempdir_factory):
)
@pytest.mark.parametrize(
('hook_stage', 'stage_for_first_hook', 'stage_for_second_hook',
'expected_output'),
(
('push', ['commit'], ['commit'], [b'', b'']),
('push', ['commit', 'push'], ['commit', 'push'],
[b'hook 1', b'hook 2']),
('push', [], [], [b'hook 1', b'hook 2']),
('push', [], ['commit'], [b'hook 1', b'']),
('push', ['push'], ['commit'], [b'hook 1', b'']),
('push', ['commit'], ['push'], [b'', b'hook 2']),
('commit', ['commit', 'push'], ['commit', 'push'],
[b'hook 1', b'hook 2']),
('commit', ['commit'], ['commit'], [b'hook 1', b'hook 2']),
('commit', [], [], [b'hook 1', b'hook 2']),
('commit', [], ['commit'], [b'', b'hook 2']),
('commit', ['push'], ['commit'], [b'', b'hook 2']),
('commit', ['commit'], ['push'], [b'hook 1', b'']),
)
)
def test_local_hook_for_stages(
repo_with_passing_hook, mock_out_store_directory,
stage_for_first_hook,
stage_for_second_hook,
hook_stage,
expected_output
):
config = OrderedDict((
('repo', 'local'),
('hooks', (OrderedDict((
('id', 'pylint'),
('name', 'hook 1'),
('entry', 'python -m pylint.__main__'),
('language', 'system'),
('files', r'\.py$'),
('stages', stage_for_first_hook)
)), OrderedDict((
('id', 'do_not_commit'),
('name', 'hook 2'),
('entry', 'DO NOT COMMIT'),
('language', 'pcre'),
('files', '^(.*)$'),
('stages', stage_for_second_hook)
))))
))
add_config_to_repo(repo_with_passing_hook, config)
with io.open('dummy.py', 'w') as staged_file:
staged_file.write('"""TODO: something"""\n')
cmd_output('git', 'add', 'dummy.py')
_test_run(
repo_with_passing_hook,
{'hook_stage': hook_stage},
expected_outputs=expected_output,
expected_ret=0,
stage=False
)
def test_local_hook_passes(
repo_with_passing_hook, mock_out_store_directory,
):

View File

@@ -29,6 +29,7 @@ def test_manifest_contents(manifest):
'language': 'script',
'language_version': 'default',
'name': 'Bash hook',
'stages': [],
}]
@@ -44,4 +45,5 @@ def test_hooks(manifest):
'language': 'script',
'language_version': 'default',
'name': 'Bash hook',
'stages': [],
}