def test_autoupdate_local_hooks(in_git_dir, store): config = sample_local_config() add_config_to_repo('.', config) assert autoupdate(C.CONFIG_FILE, store, freeze=False, tags_only=False) == 0 new_config_writen = read_config('.') assert len(new_config_writen['repos']) == 1 assert new_config_writen['repos'][0] == config
def test_useless_exclude_with_types_filter(capsys, tempdir_factory): config = { 'repos': [ { 'repo': 'meta', 'hooks': [ { 'id': 'check-useless-excludes', 'exclude': '.pre-commit-config.yaml', 'types': ['python'], }, ], }, ], } repo = git_dir(tempdir_factory) add_config_to_repo(repo, config) with cwd(repo): assert check_useless_excludes.main(()) == 1 out, _ = capsys.readouterr() out = out.strip() expected = ("The exclude pattern '.pre-commit-config.yaml' for " "check-useless-excludes does not match any files") assert expected == out
def test_local_hook_passes(repo_with_passing_hook, mock_out_store_directory): config = OrderedDict(( ('repo', 'local'), ('hooks', (OrderedDict(( ('id', 'pylint'), ('name', 'PyLint'), ('entry', 'python -m pylint.__main__'), ('language', 'system'), ('files', r'\.py$'), )), OrderedDict(( ('id', 'do_not_commit'), ('name', 'Block if "DO NOT COMMIT" is found'), ('entry', 'DO NOT COMMIT'), ('language', 'pcre'), ('files', '^(.*)$'), )))) )) 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, options={}, expected_outputs=[b''], expected_ret=0, stage=False )
def test_local_hook_fails(cap_out, store, repo_with_passing_hook): config = { 'repo': 'local', 'hooks': [{ 'id': 'no-todo', 'name': 'No TODO', 'entry': 'sh -c "! grep -iI todo $@" --', 'language': 'system', }], } 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( cap_out, store, repo_with_passing_hook, opts={}, expected_outputs=[b''], expected_ret=1, stage=False, )
def test_useless_exclude_with_types_filter(capsys, in_git_dir): config = { 'repos': [ { 'repo': 'meta', 'hooks': [ { 'id': 'check-useless-excludes', 'exclude': '.pre-commit-config.yaml', 'types': ['python'], }, ], }, ], } add_config_to_repo(in_git_dir.strpath, config) assert check_useless_excludes.main(()) == 1 out, _ = capsys.readouterr() out = out.strip() expected = ("The exclude pattern '.pre-commit-config.yaml' for " 'check-useless-excludes does not match any files') assert expected == out
def test_args_hook_only(cap_out, store, repo_with_passing_hook): config = { 'repo': 'local', 'hooks': [ { 'id': 'flake8', 'name': 'flake8', 'entry': "'{}' -m flake8".format(sys.executable), 'language': 'system', 'stages': ['commit'], }, { 'id': 'do_not_commit', 'name': 'Block if "DO NOT COMMIT" is found', 'entry': 'DO NOT COMMIT', 'language': 'pygrep', }, ], } add_config_to_repo(repo_with_passing_hook, config) stage_a_file() ret, printed = _do_run( cap_out, store, repo_with_passing_hook, run_opts(hook='do_not_commit'), ) assert b'flake8' not in printed
def test_local_hooks(tempdir_factory, mock_out_store_directory): config = OrderedDict(( ('repo', 'local'), ( 'hooks', ( OrderedDict(( ('id', 'arg-per-line'), ('name', 'Args per line hook'), ('entry', 'bin/hook.sh'), ('language', 'script'), ('files', ''), ('args', ['hello', 'world']), )), OrderedDict(( ('id', 'do_not_commit'), ('name', 'Block if "DO NOT COMMIT" is found'), ('entry', 'DO NOT COMMIT'), ('language', 'pcre'), ('files', '^(.*)$'), )), ), ), )) git_path = git_dir(tempdir_factory) add_config_to_repo(git_path, config) runner = Runner(git_path, C.CONFIG_FILE) assert len(runner.repositories) == 1 assert len(runner.repositories[0].hooks) == 2
def test_pre_push_environment_variables(tempdir_factory, store): config = { 'repo': 'local', 'hooks': [ { 'id': 'print-remote-info', 'name': 'print remote info', 'entry': 'bash -c "echo remote: $PRE_COMMIT_REMOTE_NAME"', 'language': 'system', 'verbose': True, }, ], } upstream = git_dir(tempdir_factory) clone = tempdir_factory.get() cmd_output('git', 'clone', upstream, clone) add_config_to_repo(clone, config) with cwd(clone): install(C.CONFIG_FILE, store, hook_types=['pre-push']) cmd_output('git', 'remote', 'rename', 'origin', 'origin2') retc, output = _get_push_output(tempdir_factory, remote='origin2') assert retc == 0 assert '\nremote: origin2\n' in output
def test_local_hooks_alt_config(tempdir_factory, mock_out_store_directory): config = OrderedDict( (('repo', 'local'), ('hooks', (OrderedDict(( ('id', 'arg-per-line'), ('name', 'Args per line hook'), ('entry', 'bin/hook.sh'), ('language', 'script'), ('files', ''), ('args', ['hello', 'world']), )), OrderedDict(( ('id', 'ugly-format-json'), ('name', 'Ugly format json'), ('entry', 'ugly-format-json'), ('language', 'python'), ('files', ''), )), OrderedDict(( ('id', 'do_not_commit'), ('name', 'Block if "DO NOT COMMIT" is found'), ('entry', 'DO NOT COMMIT'), ('language', 'pcre'), ('files', '^(.*)$'), )))))) git_path = git_dir(tempdir_factory) alt_config_file = 'alternate_config.yaml' add_config_to_repo(git_path, config, config_file=alt_config_file) runner = Runner(git_path, alt_config_file) assert len(runner.repositories) == 1 assert len(runner.repositories[0].hooks) == 3
def test_pcre_deprecation_warning( cap_out, repo_with_passing_hook, mock_out_store_directory, ): config = OrderedDict(( ('repo', 'local'), ( 'hooks', [ OrderedDict(( ('id', 'pcre-hook'), ('name', 'pcre-hook'), ('language', 'pcre'), ('entry', '.'), )) ], ), )) add_config_to_repo(repo_with_passing_hook, config) _test_run( cap_out, repo_with_passing_hook, opts={}, expected_outputs=[ b'[WARNING] `pcre-hook` (from local) uses the deprecated ' b'pcre language.', ], expected_ret=0, stage=False, )
def test_local_hook_passes( cap_out, repo_with_passing_hook, mock_out_store_directory, ): config = OrderedDict(( ('repo', 'local'), ('hooks', (OrderedDict(( ('id', 'flake8'), ('name', 'flake8'), ('entry', 'python -m flake8.__main__'), ('language', 'system'), ('files', r'\.py$'), )), OrderedDict(( ('id', 'do_not_commit'), ('name', 'Block if "DO NOT COMMIT" is found'), ('entry', 'DO NOT COMMIT'), ('language', 'pcre'), ('files', '^(.*)$'), )))) )) 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( cap_out, repo_with_passing_hook, opts={}, expected_outputs=[b''], expected_ret=0, stage=False, )
def test_args_hook_only(cap_out, store, repo_with_passing_hook): config = { 'repo': 'local', 'hooks': [ { 'id': 'identity-copy', 'name': 'identity-copy', 'entry': '{} -m pre_commit.meta_hooks.identity'.format( shlex.quote(sys.executable), ), 'language': 'system', 'files': r'\.py$', 'stages': ['commit'], }, { 'id': 'do_not_commit', 'name': 'Block if "DO NOT COMMIT" is found', 'entry': 'DO NOT COMMIT', 'language': 'pygrep', }, ], } add_config_to_repo(repo_with_passing_hook, config) stage_a_file() ret, printed = _do_run( cap_out, store, repo_with_passing_hook, run_opts(hook='do_not_commit'), ) assert b'identity-copy' not in printed
def test_args_hook_only(cap_out, store, repo_with_passing_hook): config = OrderedDict(( ('repo', 'local'), ( 'hooks', ( OrderedDict(( ('id', 'flake8'), ('name', 'flake8'), ('entry', "'{}' -m flake8".format(sys.executable)), ('language', 'system'), ('stages', ['commit']), )), OrderedDict(( ('id', 'do_not_commit'), ('name', 'Block if "DO NOT COMMIT" is found'), ('entry', 'DO NOT COMMIT'), ('language', 'pygrep'), )), ), ), )) add_config_to_repo(repo_with_passing_hook, config) stage_a_file() ret, printed = _do_run( cap_out, store, repo_with_passing_hook, run_opts(hook='do_not_commit'), ) assert b'flake8' not in printed
def test_local_hook_fails(cap_out, store, repo_with_passing_hook): config = { 'repo': 'local', 'hooks': [{ 'id': 'no-todo', 'name': 'No TODO', 'entry': 'sh -c "! grep -iI todo $@" --', 'language': 'system', }], } add_config_to_repo(repo_with_passing_hook, config) with open('dummy.py', 'w') as staged_file: staged_file.write('"""TODO: something"""\n') cmd_output('git', 'add', 'dummy.py') _test_run( cap_out, store, repo_with_passing_hook, opts={}, expected_outputs=[b''], expected_ret=1, stage=False, )
def test_local_hook_fails( cap_out, repo_with_passing_hook, mock_out_store_directory, ): config = OrderedDict(( ('repo', 'local'), ('hooks', [OrderedDict(( ('id', 'no-todo'), ('name', 'No TODO'), ('entry', 'sh -c "! grep -iI todo $@" --'), ('language', 'system'), ('files', ''), ))]) )) 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( cap_out, repo_with_passing_hook, opts={}, expected_outputs=[b''], expected_ret=1, stage=False, )
def test_valid_includes(capsys, tempdir_factory, mock_store_dir): config = OrderedDict(( ('repo', 'meta'), ( 'hooks', ( OrderedDict((('id', 'check-useless-excludes'), )), # Should not be reported as an error due to always_run OrderedDict(( ('id', 'check-useless-excludes'), ('files', '^$'), ('always_run', True), )), ), ), )) repo = git_dir(tempdir_factory) add_config_to_repo(repo, config) with cwd(repo): assert check_hooks_apply.main(()) == 0 out, _ = capsys.readouterr() assert out == ''
def test_local_hook_fails( cap_out, repo_with_passing_hook, mock_out_store_directory, ): config = OrderedDict(( ('repo', 'local'), ( 'hooks', [ OrderedDict(( ('id', 'no-todo'), ('name', 'No TODO'), ('entry', 'sh -c "! grep -iI todo $@" --'), ('language', 'system'), ('files', ''), )) ], ), )) 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( cap_out, repo_with_passing_hook, opts={}, expected_outputs=[b''], expected_ret=1, stage=False, )
def test_valid_language_fail(capsys, tempdir_factory, mock_store_dir): config = { 'repos': [ { 'repo': 'local', 'hooks': [ # Should not be reported as an error due to language: fail { 'id': 'changelogs-rst', 'name': 'changelogs must be rst', 'entry': 'changelog filenames must end in .rst', 'language': 'fail', 'files': r'changelog/.*(?<!\.rst)$', }, ], }, ], } repo = git_dir(tempdir_factory) add_config_to_repo(repo, config) with cwd(repo): assert check_hooks_apply.main(()) == 0 out, _ = capsys.readouterr() assert out == ''
def test_valid_always_run(capsys, tempdir_factory, mock_store_dir): config = { 'repos': [ { 'repo': 'meta', 'hooks': [ # Should not be reported as an error due to always_run { 'id': 'check-useless-excludes', 'files': '^$', 'always_run': True, }, ], }, ], } repo = git_dir(tempdir_factory) add_config_to_repo(repo, config) with cwd(repo): assert check_hooks_apply.main(()) == 0 out, _ = capsys.readouterr() assert out == ''
def test_autoupdate_local_hooks(in_git_dir, store): config = sample_local_config() add_config_to_repo('.', config) assert autoupdate(C.CONFIG_FILE, store, tags_only=False) == 0 new_config_writen = read_config('.') assert len(new_config_writen['repos']) == 1 assert new_config_writen['repos'][0] == config
def test_useless_exclude_for_hook(capsys, tempdir_factory): config = OrderedDict(( ('repo', 'meta'), ( 'hooks', ( OrderedDict(( ('id', 'check-useless-excludes'), ('exclude', 'foo'), )), ), ), )) repo = git_dir(tempdir_factory) add_config_to_repo(repo, config) with cwd(repo): assert check_useless_excludes.main(()) == 1 out, _ = capsys.readouterr() expected = ( "The exclude pattern 'foo' for check-useless-excludes " "does not match any files" ) assert expected in out
def test_pcre_deprecation_warning(cap_out, store, repo_with_passing_hook): config = { 'repo': 'local', 'hooks': [{ 'id': 'pcre-hook', 'name': 'pcre-hook', 'language': 'pcre', 'entry': '.', }], } add_config_to_repo(repo_with_passing_hook, config) _test_run( cap_out, store, repo_with_passing_hook, opts={}, expected_outputs=[ b'[WARNING] `pcre-hook` (from local) uses the deprecated ' b'pcre language.', ], expected_ret=0, stage=False, )
def test_useless_exclude_with_types_filter(capsys, in_git_dir): config = { 'repos': [ { 'repo': 'meta', 'hooks': [ { 'id': 'check-useless-excludes', 'exclude': '.pre-commit-config.yaml', 'types': ['python'], }, ], }, ], } add_config_to_repo(in_git_dir.strpath, config) assert check_useless_excludes.main(()) == 1 out, _ = capsys.readouterr() out = out.strip() expected = ( "The exclude pattern '.pre-commit-config.yaml' for " 'check-useless-excludes does not match any files' ) assert expected == out
def test_local_hooks_alt_config(tempdir_factory, mock_out_store_directory): config = OrderedDict(( ('repo', 'local'), ('hooks', (OrderedDict(( ('id', 'arg-per-line'), ('name', 'Args per line hook'), ('entry', 'bin/hook.sh'), ('language', 'script'), ('files', ''), ('args', ['hello', 'world']), )), OrderedDict(( ('id', 'ugly-format-json'), ('name', 'Ugly format json'), ('entry', 'ugly-format-json'), ('language', 'python'), ('files', ''), )), OrderedDict(( ('id', 'do_not_commit'), ('name', 'Block if "DO NOT COMMIT" is found'), ('entry', 'DO NOT COMMIT'), ('language', 'pcre'), ('files', '^(.*)$'), )))) )) git_path = git_dir(tempdir_factory) alt_config_file = 'alternate_config.yaml' add_config_to_repo(git_path, config, config_file=alt_config_file) runner = Runner(git_path, alt_config_file) assert len(runner.repositories) == 1 assert len(runner.repositories[0].hooks) == 3
def test_stages(cap_out, store, repo_with_passing_hook): config = { 'repo': 'local', 'hooks': [ { 'id': f'do-not-commit-{i}', 'name': f'hook {i}', 'entry': 'DO NOT COMMIT', 'language': 'pygrep', 'stages': [stage], } for i, stage in enumerate(('commit', 'push', 'manual'), 1) ], } add_config_to_repo(repo_with_passing_hook, config) stage_a_file() def _run_for_stage(stage): args = run_opts(hook_stage=stage) ret, printed = _do_run(cap_out, store, repo_with_passing_hook, args) assert not ret, (ret, printed) # this test should only run one hook assert printed.count(b'hook ') == 1 return printed assert _run_for_stage('commit').startswith(b'hook 1...') assert _run_for_stage('push').startswith(b'hook 2...') assert _run_for_stage('manual').startswith(b'hook 3...')
def test_local_hook_passes(cap_out, store, repo_with_passing_hook): config = { 'repo': 'local', 'hooks': [ { 'id': 'flake8', 'name': 'flake8', 'entry': "'{}' -m flake8".format(sys.executable), 'language': 'system', 'files': r'\.py$', }, { 'id': 'do_not_commit', 'name': 'Block if "DO NOT COMMIT" is found', 'entry': 'DO NOT COMMIT', 'language': 'pygrep', }, ], } 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( cap_out, store, repo_with_passing_hook, opts={}, expected_outputs=[b''], expected_ret=0, stage=False, )
def test_hook_types_excludes_everything( capsys, tempdir_factory, mock_store_dir, ): config = { 'repos': [ { 'repo': 'meta', 'hooks': [ { 'id': 'check-useless-excludes', 'exclude_types': ['yaml'], }, ], }, ], } repo = git_dir(tempdir_factory) add_config_to_repo(repo, config) with cwd(repo): assert check_hooks_apply.main(()) == 1 out, _ = capsys.readouterr() assert 'check-useless-excludes does not apply to this repository' in out
def test_stages(cap_out, repo_with_passing_hook, mock_out_store_directory): config = OrderedDict(( ('repo', 'local'), ( 'hooks', tuple({ 'id': 'do-not-commit-{}'.format(i), 'name': 'hook {}'.format(i), 'entry': 'DO NOT COMMIT', 'language': 'pygrep', 'stages': [stage], } for i, stage in enumerate(('commit', 'push', 'manual'), 1)), ), )) add_config_to_repo(repo_with_passing_hook, config) stage_a_file() def _run_for_stage(stage): args = run_opts(hook_stage=stage) ret, printed = _do_run(cap_out, repo_with_passing_hook, args) assert not ret, (ret, printed) # this test should only run one hook assert printed.count(b'hook ') == 1 return printed assert _run_for_stage('commit').startswith(b'hook 1...') assert _run_for_stage('push').startswith(b'hook 2...') assert _run_for_stage('manual').startswith(b'hook 3...')
def test_useless_exclude_global(capsys, tempdir_factory): config = OrderedDict(( ('exclude', 'foo'), ( 'repos', [ OrderedDict(( ('repo', 'meta'), ( 'hooks', (OrderedDict((('id', 'check-useless-excludes'), )), ), ), )), ], ), )) repo = git_dir(tempdir_factory) add_config_to_repo(repo, config) with cwd(repo): assert check_useless_excludes.main(()) == 1 out, _ = capsys.readouterr() assert "The global exclude pattern 'foo' does not match any files" in out
def test_local_hook_for_stages( cap_out, 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', 'flake8'), ('name', 'hook 1'), ('entry', 'python -m flake8.__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(cap_out, repo_with_passing_hook, {'hook_stage': hook_stage}, expected_outputs=expected_output, expected_ret=0, stage=False)
def test_meta_hook_passes(cap_out, store, repo_with_passing_hook): add_config_to_repo(repo_with_passing_hook, sample_meta_config()) _test_run( cap_out, store, repo_with_passing_hook, opts={}, expected_outputs=[b'Check for useless excludes'], expected_ret=0, stage=False, )
def test_useless_excludes_broken_symlink(capsys, in_git_dir, tempdir_factory): path = make_repo(tempdir_factory, 'script_hooks_repo') config = make_config_from_repo(path) config['hooks'][0]['exclude'] = 'broken-symlink' add_config_to_repo(in_git_dir.strpath, config) in_git_dir.join('broken-symlink').mksymlinkto('DNE') cmd_output('git', 'add', 'broken-symlink') git.commit() assert check_useless_excludes.main(('.pre-commit-config.yaml', )) == 0 out, _ = capsys.readouterr() assert out == ''
def test_no_excludes(capsys, in_git_dir): config = { 'repos': [ { 'repo': 'meta', 'hooks': [{'id': 'check-useless-excludes'}], }, ], } add_config_to_repo(in_git_dir.strpath, config) assert check_useless_excludes.main(()) == 0 out, _ = capsys.readouterr() assert out == ''
def test_always_run_alt_config( cap_out, repo_with_passing_hook, mock_out_store_directory, ): repo_root = '.' config = read_config(repo_root) config[0]['hooks'][0]['always_run'] = True alt_config_file = 'alternate_config.yaml' add_config_to_repo(repo_root, config, config_file=alt_config_file) _test_run(cap_out, repo_with_passing_hook, {}, (b'Bash hook', b'Passed'), 0, stage=False, config_file=alt_config_file)
def test_push_hook(cap_out, repo_with_passing_hook, mock_out_store_directory): config = OrderedDict(( ('repo', 'local'), ( 'hooks', ( OrderedDict(( ('id', 'flake8'), ('name', 'hook 1'), ('entry', "'{}' -m flake8".format(sys.executable)), ('language', 'system'), ('types', ['python']), ('stages', ['commit']), )), OrderedDict(( ('id', 'do_not_commit'), ('name', 'hook 2'), ('entry', 'DO NOT COMMIT'), ('language', 'pcre'), ('types', ['text']), ('stages', ['push']), )), ), ), )) add_config_to_repo(repo_with_passing_hook, config) open('dummy.py', 'a').close() cmd_output('git', 'add', 'dummy.py') _test_run( cap_out, repo_with_passing_hook, {'hook_stage': 'commit'}, expected_outputs=[b'hook 1'], expected_ret=0, stage=False, ) _test_run( cap_out, repo_with_passing_hook, {'hook_stage': 'push'}, expected_outputs=[b'hook 2'], expected_ret=0, stage=False, )
def test_always_run_alt_config(cap_out, store, repo_with_passing_hook): repo_root = '.' config = read_config(repo_root) config['repos'][0]['hooks'][0]['always_run'] = True alt_config_file = 'alternate_config.yaml' add_config_to_repo(repo_root, config, config_file=alt_config_file) _test_run( cap_out, store, repo_with_passing_hook, {}, (b'Bash hook', b'Passed'), 0, stage=False, config_file=alt_config_file, )
def test_no_excludes(capsys, tempdir_factory): config = OrderedDict(( ('repo', 'meta'), ( 'hooks', (OrderedDict((('id', 'check-useless-excludes'), )), ), ), )) repo = git_dir(tempdir_factory) add_config_to_repo(repo, config) with cwd(repo): assert check_useless_excludes.main(()) == 0 out, _ = capsys.readouterr() assert out == ''
def test_autoupdate_local_hooks(tmpdir_factory): git_path = git_dir(tmpdir_factory) config = config_with_local_hooks() path = add_config_to_repo(git_path, config) runner = Runner(path) assert autoupdate(runner) == 0 new_config_writen = load_config(runner.config_file_path) assert len(new_config_writen) == 1 assert new_config_writen[0] == config
def test_useless_exclude_global(capsys, in_git_dir): config = { 'exclude': 'foo', 'repos': [ { 'repo': 'meta', 'hooks': [{'id': 'check-useless-excludes'}], }, ], } add_config_to_repo(in_git_dir.strpath, config) assert check_useless_excludes.main(()) == 1 out, _ = capsys.readouterr() out = out.strip() assert "The global exclude pattern 'foo' does not match any files" == out
def test_autoupdate_local_hooks(tempdir_factory): git_path = git_dir(tempdir_factory) config = config_with_local_hooks() path = add_config_to_repo(git_path, config) runner = Runner(path, C.CONFIG_FILE) assert autoupdate(runner, tags_only=False) == 0 new_config_writen = load_config(runner.config_file_path) assert len(new_config_writen['repos']) == 1 assert new_config_writen['repos'][0] == config
def test_valid_exceptions(capsys, in_git_dir, mock_store_dir): config = { 'repos': [ { 'repo': 'local', 'hooks': [ # applies to a file { 'id': 'check-yaml', 'name': 'check yaml', 'entry': './check-yaml', 'language': 'script', 'files': r'\.yaml$', }, # Should not be reported as an error due to language: fail { 'id': 'changelogs-rst', 'name': 'changelogs must be rst', 'entry': 'changelog filenames must end in .rst', 'language': 'fail', 'files': r'changelog/.*(?<!\.rst)$', }, # Should not be reported as an error due to always_run { 'id': 'i-always-run', 'name': 'make check', 'entry': 'make check', 'language': 'system', 'files': '^$', 'always_run': True, }, ], }, ], } add_config_to_repo(in_git_dir.strpath, config) assert check_hooks_apply.main(()) == 0 out, _ = capsys.readouterr() assert out == ''
def test_hook_types_excludes_everything(capsys, in_git_dir, mock_store_dir): config = { 'repos': [ { 'repo': 'meta', 'hooks': [ { 'id': 'check-useless-excludes', 'exclude_types': ['yaml'], }, ], }, ], } add_config_to_repo(in_git_dir.strpath, config) assert check_hooks_apply.main(()) == 1 out, _ = capsys.readouterr() assert 'check-useless-excludes does not apply to this repository' in out
def test_useless_exclude_for_hook(capsys, in_git_dir): config = { 'repos': [ { 'repo': 'meta', 'hooks': [{'id': 'check-useless-excludes', 'exclude': 'foo'}], }, ], } add_config_to_repo(in_git_dir.strpath, config) assert check_useless_excludes.main(()) == 1 out, _ = capsys.readouterr() out = out.strip() expected = ( "The exclude pattern 'foo' for check-useless-excludes " 'does not match any files' ) assert expected == out
def test_valid_exclude(capsys, in_git_dir): config = { 'repos': [ { 'repo': 'meta', 'hooks': [ { 'id': 'check-useless-excludes', 'exclude': '.pre-commit-config.yaml', }, ], }, ], } add_config_to_repo(in_git_dir.strpath, config) assert check_useless_excludes.main(()) == 0 out, _ = capsys.readouterr() assert out == ''
def test_local_hook_for_stages( cap_out, 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', 'flake8'), ('name', 'hook 1'), ('entry', 'python -m flake8.__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( cap_out, repo_with_passing_hook, {'hook_stage': hook_stage}, expected_outputs=expected_output, expected_ret=0, stage=False )
def test_local_hook_passes( cap_out, repo_with_passing_hook, mock_out_store_directory, ): config = OrderedDict(( ('repo', 'local'), ( 'hooks', ( OrderedDict(( ('id', 'flake8'), ('name', 'flake8'), ('entry', "'{}' -m flake8".format(sys.executable)), ('language', 'system'), ('files', r'\.py$'), )), OrderedDict(( ('id', 'do_not_commit'), ('name', 'Block if "DO NOT COMMIT" is found'), ('entry', 'DO NOT COMMIT'), ('language', 'pcre'), ('files', '^(.*)$'), )), ), ), )) 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( cap_out, repo_with_passing_hook, opts={}, expected_outputs=[b''], expected_ret=0, stage=False, )
def test_stages(cap_out, store, repo_with_passing_hook): config = { 'repo': 'local', 'hooks': [ { 'id': 'do-not-commit-{}'.format(i), 'name': 'hook {}'.format(i), 'entry': 'DO NOT COMMIT', 'language': 'pygrep', 'stages': [stage], } for i, stage in enumerate( ( 'commit', 'push', 'manual', 'prepare-commit-msg', 'commit-msg', ), 1, ) ], } add_config_to_repo(repo_with_passing_hook, config) stage_a_file() def _run_for_stage(stage): args = run_opts(hook_stage=stage) ret, printed = _do_run(cap_out, store, repo_with_passing_hook, args) assert not ret, (ret, printed) # this test should only run one hook assert printed.count(b'hook ') == 1 return printed assert _run_for_stage('commit').startswith(b'hook 1...') assert _run_for_stage('push').startswith(b'hook 2...') assert _run_for_stage('manual').startswith(b'hook 3...') assert _run_for_stage('prepare-commit-msg').startswith(b'hook 4...') assert _run_for_stage('commit-msg').startswith(b'hook 5...')