Added config parameter hide_skipped

This commit is contained in:
allburov 2019-10-15 15:58:47 +07:00
parent b3582dfd31
commit 7c883d038d
7 changed files with 130 additions and 8 deletions

View file

@ -262,6 +262,7 @@ CONFIG_SCHEMA = cfgv.Map(
), ),
cfgv.Optional('exclude', cfgv.check_regex, '^$'), cfgv.Optional('exclude', cfgv.check_regex, '^$'),
cfgv.Optional('fail_fast', cfgv.check_bool, False), cfgv.Optional('fail_fast', cfgv.check_bool, False),
cfgv.Optional('hide_skipped', cfgv.check_bool, False),
cfgv.Optional( cfgv.Optional(
'minimum_pre_commit_version', 'minimum_pre_commit_version',
cfgv.check_and(cfgv.check_string, check_min_version), cfgv.check_and(cfgv.check_string, check_min_version),
@ -274,6 +275,7 @@ CONFIG_SCHEMA = cfgv.Map(
'default_stages', 'default_stages',
'exclude', 'exclude',
'fail_fast', 'fail_fast',
'hide_skipped',
'minimum_pre_commit_version', 'minimum_pre_commit_version',
), ),
warn_unknown_keys_root, warn_unknown_keys_root,

View file

@ -19,7 +19,6 @@ from pre_commit.staged_files_only import staged_files_only
from pre_commit.util import cmd_output_b from pre_commit.util import cmd_output_b
from pre_commit.util import noop_context from pre_commit.util import noop_context
logger = logging.getLogger('pre_commit') logger = logging.getLogger('pre_commit')
@ -70,10 +69,16 @@ def _hook_msg_start(hook, verbose):
SKIPPED = 'Skipped' SKIPPED = 'Skipped'
FAILED = 'Failed'
PASSED = 'Passed'
NO_FILES = '(no files to check)' NO_FILES = '(no files to check)'
def _run_single_hook(classifier, hook, args, skips, cols, use_color): def _run_single_hook(
classifier, hook, args, skips, cols,
use_color,
hide_skipped,
):
filenames = classifier.filenames_for_hook(hook) filenames = classifier.filenames_for_hook(hook)
if hook.language == 'pcre': if hook.language == 'pcre':
@ -93,6 +98,7 @@ def _run_single_hook(classifier, hook, args, skips, cols, use_color):
use_color=args.color, use_color=args.color,
cols=cols, cols=cols,
), ),
cond=not hide_skipped,
) )
return 0 return 0
elif not filenames and not hook.always_run: elif not filenames and not hook.always_run:
@ -105,6 +111,7 @@ def _run_single_hook(classifier, hook, args, skips, cols, use_color):
use_color=args.color, use_color=args.color,
cols=cols, cols=cols,
), ),
cond=not hide_skipped,
) )
return 0 return 0
@ -131,11 +138,11 @@ def _run_single_hook(classifier, hook, args, skips, cols, use_color):
if retcode: if retcode:
retcode = 1 retcode = 1
print_color = color.RED print_color = color.RED
pass_fail = 'Failed' pass_fail = FAILED
else: else:
retcode = 0 retcode = 0
print_color = color.GREEN print_color = color.GREEN
pass_fail = 'Passed' pass_fail = PASSED
output.write_line(color.format_color(pass_fail, print_color, args.color)) output.write_line(color.format_color(pass_fail, print_color, args.color))
@ -202,10 +209,12 @@ def _run_hooks(config, hooks, args, environ):
filenames = _all_filenames(args) filenames = _all_filenames(args)
filenames = filter_by_include_exclude(filenames, '', config['exclude']) filenames = filter_by_include_exclude(filenames, '', config['exclude'])
classifier = Classifier(filenames) classifier = Classifier(filenames)
hide_skipped = False if args.verbose else config['hide_skipped']
retval = 0 retval = 0
for hook in hooks: for hook in hooks:
retval |= _run_single_hook( retval |= _run_single_hook(
classifier, hook, args, skips, cols, args.color, classifier, hook, args, skips, cols, args.color,
hide_skipped,
) )
if retval and config['fail_fast']: if retval and config['fail_fast']:
break break
@ -219,6 +228,7 @@ def _run_hooks(config, hooks, args, environ):
'`pre-commit install`.', '`pre-commit install`.',
) )
output.write_line('All changes made by hooks:') output.write_line('All changes made by hooks:')
# args.color is a boolean. # args.color is a boolean.
# See user_color function in color.py # See user_color function in color.py
subprocess.call(( subprocess.call((

View file

@ -67,12 +67,21 @@ def get_hook_message(
stdout_byte_stream = getattr(sys.stdout, 'buffer', sys.stdout) stdout_byte_stream = getattr(sys.stdout, 'buffer', sys.stdout)
def write(s, stream=stdout_byte_stream): def write(s, stream=stdout_byte_stream, cond=True):
if not cond:
return
stream.write(five.to_bytes(s)) stream.write(five.to_bytes(s))
stream.flush() stream.flush()
def write_line(s=None, stream=stdout_byte_stream, logfile_name=None): def write_line(
s=None,
stream=stdout_byte_stream,
logfile_name=None,
cond=True,
):
if not cond:
return
output_streams = [stream] output_streams = [stream]
if logfile_name: if logfile_name:
ctx = open(logfile_name, 'ab') ctx = open(logfile_name, 'ab')

View file

@ -0,0 +1,15 @@
- id: passing_hook
name: Passing hook
entry: bin/hook.sh
args: ['0']
language: script
- id: failing_hook
name: Failing hook
entry: bin/hook.sh
args: ['1']
language: script
- id: skipping_hook
name: Skipping hook
entry: bin/hook.sh
language: script
files: 'no-exist-file'

View file

@ -0,0 +1,5 @@
#!/usr/bin/env bash
echo $@
echo 'Hello World'
exit $1

View file

@ -315,3 +315,24 @@ def test_warn_additional(schema):
x for x in schema.items if isinstance(x, cfgv.WarnAdditionalKeys) x for x in schema.items if isinstance(x, cfgv.WarnAdditionalKeys)
] ]
assert allowed_keys == set(warn_additional.keys) assert allowed_keys == set(warn_additional.keys)
def test_hide_skipped_passing(tmpdir, caplog):
f = tmpdir.join('cfg.yaml')
f.write(
'hide_skipped: True\n'
'repos:\n'
'- repo: https://gitlab.com/pycqa/flake8\n'
' rev: 3.7.7\n'
' hooks:\n'
' - id: flake8\n',
)
ret_val = validate_config_main((f.strpath,))
assert not ret_val
assert caplog.record_tuples != [
(
'pre_commit',
logging.WARNING,
'Unexpected key(s) present at root: hide_skipped',
),
]

View file

@ -71,9 +71,12 @@ def _do_run(cap_out, store, repo, args, environ={}, config_file=C.CONFIG_FILE):
def _test_run( def _test_run(
cap_out, store, repo, opts, expected_outputs, expected_ret, stage, cap_out, store, repo, opts, expected_outputs, expected_ret, stage,
config_file=C.CONFIG_FILE, config_file=C.CONFIG_FILE,
unexpected_outputs=None,
): ):
unexpected_outputs = unexpected_outputs or []
if stage: if stage:
stage_a_file() stage_a_file()
args = run_opts(**opts) args = run_opts(**opts)
@ -82,6 +85,8 @@ def _test_run(
assert ret == expected_ret, (ret, expected_ret, printed) assert ret == expected_ret, (ret, expected_ret, printed)
for expected_output_part in expected_outputs: for expected_output_part in expected_outputs:
assert expected_output_part in printed assert expected_output_part in printed
for unexpected_output_part in unexpected_outputs:
assert unexpected_output_part not in printed
def test_run_all_hooks_failing(cap_out, store, repo_with_failing_hook): def test_run_all_hooks_failing(cap_out, store, repo_with_failing_hook):
@ -101,6 +106,61 @@ def test_run_all_hooks_failing(cap_out, store, repo_with_failing_hook):
) )
PASSED_MSG = (
b'Passing hook',
b'Passed',
)
FAILED_MSG = (
b'Failing hook',
b'Failed',
b'hookid: failing_hook',
b'foo.py',
)
SKIPPED_MSG = (
b'Skipping hook',
b'(no files to check)',
b'Skipped',
)
@pytest.mark.parametrize(
('expected_outputs', 'unexpected_outputs', 'hide_skipped', 'args'), [
([*PASSED_MSG, *FAILED_MSG, *SKIPPED_MSG], [], None, {}),
([*PASSED_MSG, *FAILED_MSG, *SKIPPED_MSG], [], False, {}),
([*FAILED_MSG, *PASSED_MSG], [*SKIPPED_MSG], True, {}),
(
[*PASSED_MSG, *FAILED_MSG, *SKIPPED_MSG], [], True,
{'verbose': True},
),
],
)
def test_hide_skipped(
cap_out,
store,
tempdir_factory,
expected_outputs,
unexpected_outputs,
hide_skipped,
args,
):
git_path = make_consuming_repo(tempdir_factory, 'all_statuses_hooks_repo')
with cwd(git_path):
if hide_skipped is not None:
with modify_config() as config:
config['hide_skipped'] = hide_skipped
_test_run(
cap_out,
store,
git_path,
args,
expected_outputs,
expected_ret=1,
stage=True,
unexpected_outputs=unexpected_outputs,
)
def test_arbitrary_bytes_hook(cap_out, store, tempdir_factory): def test_arbitrary_bytes_hook(cap_out, store, tempdir_factory):
git_path = make_consuming_repo(tempdir_factory, 'arbitrary_bytes_repo') git_path = make_consuming_repo(tempdir_factory, 'arbitrary_bytes_repo')
with cwd(git_path): with cwd(git_path):