def test_autoupdate_out_of_date_repo_with_wrong_repo_name( out_of_date, in_tmpdir, store, ): config = make_config_from_repo( out_of_date.path, rev=out_of_date.original_rev, check=False, ) write_config('.', config) with open(C.CONFIG_FILE) as f: before = f.read() # It will not update it, because the name doesn't match ret = autoupdate( C.CONFIG_FILE, store, freeze=False, tags_only=False, repos=('dne', ), ) with open(C.CONFIG_FILE) as f: after = f.read() assert ret == 0 assert before == after
def test_autoupdate_tagged_repo(tagged, in_tmpdir, store): config = make_config_from_repo(tagged.path, rev=tagged.original_rev) write_config('.', config) assert autoupdate(C.CONFIG_FILE, store, freeze=False, tags_only=False) == 0 with open(C.CONFIG_FILE) as f: assert 'v1.2.3' in f.read()
def test_autoupdate_old_revision_broken( tempdir_factory, in_tmpdir, mock_out_store_directory, ): """In $FUTURE_VERSION, hooks.yaml will no longer be supported. This asserts that when that day comes, pre-commit will be able to autoupdate despite not being able to read hooks.yaml in that repository. """ path = make_repo(tempdir_factory, 'python_hooks_repo') config = make_config_from_repo(path, check=False) with cwd(path): cmd_output('git', 'mv', C.MANIFEST_FILE, 'nope.yaml') cmd_output('git', 'commit', '-m', 'simulate old repo') # Assume this is the revision the user's old repository was at rev = git.head_sha(path) cmd_output('git', 'mv', 'nope.yaml', C.MANIFEST_FILE) cmd_output('git', 'commit', '-m', 'move hooks file') update_rev = git.head_sha(path) config['sha'] = rev write_config('.', config) before = open(C.CONFIG_FILE).read() ret = autoupdate(Runner('.', C.CONFIG_FILE), tags_only=False) after = open(C.CONFIG_FILE).read() assert ret == 0 assert before != after assert update_rev in after
def test_post_commit_integration(tempdir_factory, store): path = git_dir(tempdir_factory) config = [ { 'repo': 'local', 'hooks': [{ 'id': 'post-commit', 'name': 'Post commit', 'entry': 'touch post-commit.tmp', 'language': 'system', 'always_run': True, 'verbose': True, 'stages': ['post-commit'], }], }, ] write_config(path, config) with cwd(path): _get_commit_output(tempdir_factory) assert not os.path.exists('post-commit.tmp') install(C.CONFIG_FILE, store, hook_types=['post-commit']) _get_commit_output(tempdir_factory) assert os.path.exists('post-commit.tmp')
def test_post_checkout_integration(tempdir_factory, store): path = git_dir(tempdir_factory) config = [ { 'repo': 'local', 'hooks': [{ 'id': 'post-checkout', 'name': 'Post checkout', 'entry': 'bash -c "echo ${PRE_COMMIT_TO_REF}"', 'language': 'system', 'always_run': True, 'verbose': True, 'stages': ['post-checkout'], }], }, {'repo': 'meta', 'hooks': [{'id': 'identity'}]}, ] write_config(path, config) with cwd(path): cmd_output('git', 'add', '.') git_commit() # add a file only on `feature`, it should not be passed to hooks cmd_output('git', 'checkout', '-b', 'feature') open('some_file', 'a').close() cmd_output('git', 'add', '.') git_commit() cmd_output('git', 'checkout', 'master') install(C.CONFIG_FILE, store, hook_types=['post-checkout']) retc, _, stderr = cmd_output('git', 'checkout', 'feature') assert stderr is not None assert retc == 0 assert git.head_rev(path) in stderr assert 'some_file' not in stderr
def test_skips_post_checkout_unstaged_changes(tempdir_factory, store): path = git_dir(tempdir_factory) config = { 'repo': 'local', 'hooks': [{ 'id': 'fail', 'name': 'fail', 'entry': 'fail', 'language': 'fail', 'always_run': True, 'stages': ['post-checkout'], }], } write_config(path, config) with cwd(path): cmd_output('git', 'add', '.') _get_commit_output(tempdir_factory) install(C.CONFIG_FILE, store, hook_types=['pre-commit']) install(C.CONFIG_FILE, store, hook_types=['post-checkout']) # make an unstaged change so staged_files_only fires open('file', 'a').close() cmd_output('git', 'add', 'file') with open('file', 'w') as f: f.write('unstaged changes') retc, out = _get_commit_output(tempdir_factory, all_files=False) assert retc == 0
def test_post_rewrite_integration(tempdir_factory, store): path = git_dir(tempdir_factory) config = [ { 'repo': 'local', 'hooks': [{ 'id': 'post-rewrite', 'name': 'Post rewrite', 'entry': 'touch post-rewrite.tmp', 'language': 'system', 'always_run': True, 'verbose': True, 'stages': ['post-rewrite'], }], }, ] write_config(path, config) with cwd(path): open('init', 'a').close() cmd_output('git', 'add', '.') install(C.CONFIG_FILE, store, hook_types=['post-rewrite']) git_commit() assert not os.path.exists('post-rewrite.tmp') git_commit('--amend', '-m', 'ammended message') assert os.path.exists('post-rewrite.tmp')
def prepare_commit_msg_repo(tempdir_factory): path = git_dir(tempdir_factory) script_name = 'add_sign_off.sh' config = { 'repo': 'local', 'hooks': [{ 'id': 'add-signoff', 'name': 'Add "Signed off by:"', 'entry': './{}'.format(script_name), 'language': 'script', 'stages': ['prepare-commit-msg'], }], } write_config(path, config) with cwd(path): with io.open(script_name, 'w') as script_file: script_file.write( '#!/usr/bin/env bash\n' 'set -eu\n' 'echo "\nSigned off by: " >> "$1"\n', ) make_executable(script_name) cmd_output('git', 'add', '.') git_commit(msg=prepare_commit_msg_repo.__name__) yield path
def test_autoupdate_old_revision_broken( tempdir_factory, in_tmpdir, mock_out_store_directory, ): """In $FUTURE_VERSION, hooks.yaml will no longer be supported. This asserts that when that day comes, pre-commit will be able to autoupdate despite not being able to read hooks.yaml in that repository. """ path = make_repo(tempdir_factory, 'python_hooks_repo') config = make_config_from_repo(path, check=False) with cwd(path): cmd_output('git', 'mv', C.MANIFEST_FILE, 'nope.yaml') cmd_output('git', 'commit', '-m', 'simulate old repo') # Assume this is the revision the user's old repository was at rev = get_head_sha(path) cmd_output('git', 'mv', 'nope.yaml', C.MANIFEST_FILE) cmd_output('git', 'commit', '-m', 'move hooks file') update_rev = get_head_sha(path) config['sha'] = rev write_config('.', config) before = open(C.CONFIG_FILE).read() ret = autoupdate(Runner('.', C.CONFIG_FILE), tags_only=False) after = open(C.CONFIG_FILE).read() assert ret == 0 assert before != after assert update_rev in after
def test_gc_unused_local_repo_with_env(store, in_git_dir, cap_out): config = { 'repo': 'local', 'hooks': [{ 'id': 'flake8', 'name': 'flake8', 'entry': 'flake8', # a `language: python` local hook will create an environment 'types': ['python'], 'language': 'python', }], } write_config('.', config) store.mark_config_used(C.CONFIG_FILE) # this causes the repositories to be created all_hooks(load_config(C.CONFIG_FILE), store) assert _config_count(store) == 1 assert _repo_count(store) == 1 assert not gc(store) assert _config_count(store) == 1 assert _repo_count(store) == 1 assert cap_out.get().splitlines()[-1] == '0 repo(s) removed.' _remove_config_assert_cleared(store, cap_out)
def test_autoupdate_old_revision_broken(tempdir_factory, in_tmpdir, store): """In $FUTURE_VERSION, hooks.yaml will no longer be supported. This asserts that when that day comes, pre-commit will be able to autoupdate despite not being able to read hooks.yaml in that repository. """ path = make_repo(tempdir_factory, 'python_hooks_repo') config = make_config_from_repo(path, check=False) cmd_output('git', 'mv', C.MANIFEST_FILE, 'nope.yaml', cwd=path) git_commit(cwd=path) # Assume this is the revision the user's old repository was at rev = git.head_rev(path) cmd_output('git', 'mv', 'nope.yaml', C.MANIFEST_FILE, cwd=path) git_commit(cwd=path) update_rev = git.head_rev(path) config['rev'] = rev write_config('.', config) with open(C.CONFIG_FILE) as f: before = f.read() ret = autoupdate(C.CONFIG_FILE, store, tags_only=False) with open(C.CONFIG_FILE) as f: after = f.read() assert ret == 0 assert before != after assert update_rev in after
def prepare_commit_msg_repo(tempdir_factory): path = git_dir(tempdir_factory) script_name = 'add_sign_off.sh' config = { 'repo': 'local', 'hooks': [{ 'id': 'add-signoff', 'name': 'Add "Signed off by:"', 'entry': f'./{script_name}', 'language': 'script', 'stages': ['prepare-commit-msg'], }], } write_config(path, config) with cwd(path): with open(script_name, 'w') as script_file: script_file.write( '#!/usr/bin/env bash\n' 'set -eu\n' 'echo "\nSigned off by: " >> "$1"\n', ) make_executable(script_name) cmd_output('git', 'add', '.') git_commit(msg=prepare_commit_msg_repo.__name__) yield path
def test_autoupdate_out_of_date_repo_with_correct_repo_name( out_of_date_repo, in_tmpdir, store, ): stale_config = make_config_from_repo( out_of_date_repo.path, rev=out_of_date_repo.original_rev, check=False, ) local_config = config_with_local_hooks() config = {'repos': [stale_config, local_config]} # Write out the config write_config('.', config) runner = Runner('.', C.CONFIG_FILE) with open(C.CONFIG_FILE) as f: before = f.read() repo_name = 'file://{}'.format(out_of_date_repo.path) ret = autoupdate(runner, store, tags_only=False, repos=(repo_name, )) with open(C.CONFIG_FILE) as f: after = f.read() assert ret == 0 assert before != after assert out_of_date_repo.head_rev in after assert local_config['repo'] in after
def test_autoupdate_old_revision_broken(tempdir_factory, in_tmpdir, store): """In $FUTURE_VERSION, hooks.yaml will no longer be supported. This asserts that when that day comes, pre-commit will be able to autoupdate despite not being able to read hooks.yaml in that repository. """ path = make_repo(tempdir_factory, 'python_hooks_repo') config = make_config_from_repo(path, check=False) cmd_output('git', 'mv', C.MANIFEST_FILE, 'nope.yaml', cwd=path) git_commit(cwd=path) # Assume this is the revision the user's old repository was at rev = git.head_rev(path) cmd_output('git', 'mv', 'nope.yaml', C.MANIFEST_FILE, cwd=path) git_commit(cwd=path) update_rev = git.head_rev(path) config['rev'] = rev write_config('.', config) with open(C.CONFIG_FILE) as f: before = f.read() assert autoupdate(C.CONFIG_FILE, store, freeze=False, tags_only=False) == 0 with open(C.CONFIG_FILE) as f: after = f.read() assert before != after assert update_rev in after
def test_autoupdate_out_of_date_repo_with_correct_repo_name( out_of_date, in_tmpdir, store, ): stale_config = make_config_from_repo( out_of_date.path, rev=out_of_date.original_rev, check=False, ) local_config = sample_local_config() config = {'repos': [stale_config, local_config]} write_config('.', config) with open(C.CONFIG_FILE) as f: before = f.read() repo_name = f'file://{out_of_date.path}' ret = autoupdate( C.CONFIG_FILE, store, freeze=False, tags_only=False, repos=(repo_name, ), ) with open(C.CONFIG_FILE) as f: after = f.read() assert ret == 0 assert before != after assert out_of_date.head_rev in after assert 'local' in after
def test_verbose_duration(cap_out, store, in_git_dir, t1, t2, expected): write_config('.', {'repo': 'meta', 'hooks': [{'id': 'identity'}]}) cmd_output('git', 'add', '.') opts = run_opts(verbose=True) with mock.patch.object(time, 'time', side_effect=(t1, t2)): ret, printed = _do_run(cap_out, store, str(in_git_dir), opts) assert ret == 0 assert expected in printed
def test_gc_deletes_invalid_configs(store, in_git_dir, cap_out): config = {'i am': 'invalid'} write_config('.', config) store.mark_config_used(C.CONFIG_FILE) assert _config_count(store) == 1 assert not gc(store) assert _config_count(store) == 0 assert cap_out.get().splitlines()[-1] == '0 repo(s) removed.'
def test_autoupdate_tags_only(tagged, in_tmpdir, store): # add some commits after the tag git_commit(cwd=tagged.path) config = make_config_from_repo(tagged.path, rev=tagged.original_rev) write_config('.', config) assert autoupdate(C.CONFIG_FILE, store, freeze=False, tags_only=True) == 0 with open(C.CONFIG_FILE) as f: assert 'v1.2.3' in f.read()
def test_autoupdate_tagged_repo(tagged_repo, in_tmpdir, store): config = make_config_from_repo( tagged_repo.path, rev=tagged_repo.original_rev, ) write_config('.', config) ret = autoupdate(C.CONFIG_FILE, store, tags_only=False) assert ret == 0 with open(C.CONFIG_FILE) as f: assert 'v1.2.3' in f.read()
def test_autoupdate_tags_only(tagged_repo_with_more_commits, in_tmpdir, store): config = make_config_from_repo( tagged_repo_with_more_commits.path, rev=tagged_repo_with_more_commits.original_rev, ) write_config('.', config) ret = autoupdate(Runner('.', C.CONFIG_FILE), store, tags_only=True) assert ret == 0 assert 'v1.2.3' in open(C.CONFIG_FILE).read()
def test_autoupdate_tagged_repo( tagged_repo, in_tmpdir, mock_out_store_directory, ): config = make_config_from_repo( tagged_repo.path, sha=tagged_repo.original_sha, ) write_config('.', config) ret = autoupdate(Runner('.', C.CONFIG_FILE), tags_only=False) assert ret == 0 assert 'v1.2.3' in open(C.CONFIG_FILE).read()
def test_autoupdate_tagged_repo(tagged_repo, in_tmpdir, store): config = make_config_from_repo( tagged_repo.path, rev=tagged_repo.original_rev, ) write_config('.', config) ret = autoupdate(Runner('.', C.CONFIG_FILE), store, tags_only=False) assert ret == 0 with open(C.CONFIG_FILE) as f: assert 'v1.2.3' in f.read()
def test_gc_repo_not_cloned(tempdir_factory, store, in_git_dir, cap_out): path = make_repo(tempdir_factory, 'script_hooks_repo') write_config('.', make_config_from_repo(path)) store.mark_config_used(C.CONFIG_FILE) assert _config_count(store) == 1 assert _repo_count(store) == 0 assert not gc(store) assert _config_count(store) == 1 assert _repo_count(store) == 0 assert cap_out.get().splitlines()[-1] == '0 repo(s) removed.'
def test_autoupdate_up_to_date_repo(up_to_date_repo, in_tmpdir, store): # Write out the config config = make_config_from_repo(up_to_date_repo, check=False) write_config('.', config) before = open(C.CONFIG_FILE).read() assert '^$' not in before ret = autoupdate(Runner('.', C.CONFIG_FILE), store, tags_only=False) after = open(C.CONFIG_FILE).read() assert ret == 0 assert before == after
def test_autoupdate_latest_no_config(out_of_date, in_tmpdir, store): config = make_config_from_repo( out_of_date.path, rev=out_of_date.original_rev, ) write_config('.', config) cmd_output('git', 'rm', '-r', ':/', cwd=out_of_date.path) git_commit(cwd=out_of_date.path) assert autoupdate(C.CONFIG_FILE, store, freeze=False, tags_only=False) == 1 with open(C.CONFIG_FILE) as f: assert out_of_date.original_rev in f.read()
def test_autoupdate_up_to_date_repo( up_to_date_repo, in_tmpdir, mock_out_store_directory, ): # Write out the config config = make_config_from_repo(up_to_date_repo, check=False) write_config('.', config) before = open(C.CONFIG_FILE).read() assert '^$' not in before ret = autoupdate(Runner('.', C.CONFIG_FILE), tags_only=False) after = open(C.CONFIG_FILE).read() assert ret == 0 assert before == after
def test_autoupdate_local_hooks_with_out_of_date_repo( out_of_date_repo, in_tmpdir, store, ): stale_config = make_config_from_repo( out_of_date_repo.path, rev=out_of_date_repo.original_rev, check=False, ) local_config = sample_local_config() config = {'repos': [local_config, stale_config]} write_config('.', config) assert autoupdate(C.CONFIG_FILE, store, tags_only=False) == 0 new_config_writen = read_config('.') assert len(new_config_writen['repos']) == 2 assert new_config_writen['repos'][0] == local_config
def test_autoupdate_up_to_date_repo(up_to_date_repo, in_tmpdir, store): # Write out the config config = make_config_from_repo(up_to_date_repo, check=False) write_config('.', config) with open(C.CONFIG_FILE) as f: before = f.read() assert '^$' not in before ret = autoupdate(C.CONFIG_FILE, store, tags_only=False) with open(C.CONFIG_FILE) as f: after = f.read() assert ret == 0 assert before == after
def test_autoupdate_latest_no_config(out_of_date_repo, in_tmpdir, store): config = make_config_from_repo( out_of_date_repo.path, rev=out_of_date_repo.original_rev, ) write_config('.', config) cmd_output('git', 'rm', '-r', ':/', cwd=out_of_date_repo.path) git_commit(cwd=out_of_date_repo.path) ret = autoupdate(C.CONFIG_FILE, store, tags_only=False) assert ret == 1 with open(C.CONFIG_FILE) as f: assert out_of_date_repo.original_rev in f.read()
def test_autoupdate_freeze(tagged, in_tmpdir, store): config = make_config_from_repo(tagged.path, rev=tagged.original_rev) write_config('.', config) assert autoupdate(C.CONFIG_FILE, store, freeze=True, tags_only=False) == 0 with open(C.CONFIG_FILE) as f: expected = f'rev: {tagged.head_rev} # frozen: v1.2.3' assert expected in f.read() # if we un-freeze it should remove the frozen comment assert autoupdate(C.CONFIG_FILE, store, freeze=False, tags_only=False) == 0 with open(C.CONFIG_FILE) as f: assert 'rev: v1.2.3\n' in f.read()
def test_autoupdate_local_hooks_with_out_of_date_repo( out_of_date_repo, in_tmpdir, mock_out_store_directory, ): stale_config = make_config_from_repo( out_of_date_repo.path, sha=out_of_date_repo.original_sha, check=False, ) local_config = config_with_local_hooks() config = {'repos': [local_config, stale_config]} write_config('.', config) runner = Runner('.', 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']) == 2 assert new_config_writen['repos'][0] == local_config
def test_autoupdate_local_hooks_with_out_of_date_repo( out_of_date_repo, in_tmpdir, mock_out_store_directory ): stale_config = make_config_from_repo( out_of_date_repo.path, sha=out_of_date_repo.original_sha, check=False, ) local_config = config_with_local_hooks() config = [local_config, stale_config] write_config('.', config) runner = Runner('.') assert autoupdate(runner) == 0 new_config_writen = load_config(runner.config_file_path) assert len(new_config_writen) == 2 assert new_config_writen[0] == local_config
def test_autoupdate_up_to_date_repo( up_to_date_repo, in_tmpdir, mock_out_store_directory, ): # Write out the config config = make_config_from_repo(up_to_date_repo, check=False) write_config('.', config) before = open(C.CONFIG_FILE).read() assert '^$' not in before runner = Runner('.') ret = autoupdate(runner) after = open(C.CONFIG_FILE).read() assert ret == 0 assert before == after
def test_autoupdate_latest_no_config(out_of_date_repo, in_tmpdir, store): config = make_config_from_repo( out_of_date_repo.path, rev=out_of_date_repo.original_rev, ) write_config('.', config) cmd_output('git', '-C', out_of_date_repo.path, 'rm', '-r', ':/') cmd_output('git', '-C', out_of_date_repo.path, 'commit', '-m', 'rm') ret = autoupdate(Runner('.', C.CONFIG_FILE), store, tags_only=False) assert ret == 1 with open(C.CONFIG_FILE) as f: assert out_of_date_repo.original_rev in f.read()
def test_global_files(cap_out, store, in_git_dir): config = { 'files': r'^bar\.py$', 'repos': [{'repo': 'meta', 'hooks': [{'id': 'identity'}]}], } write_config('.', config) open('foo.py', 'a').close() open('bar.py', 'a').close() cmd_output('git', 'add', '.') opts = run_opts(verbose=True) ret, printed = _do_run(cap_out, store, str(in_git_dir), opts) assert ret == 0 # Does not contain foo.py since it was excluded assert printed.startswith(f'identity{"." * 65}Passed\n'.encode()) assert printed.endswith(b'\n\nbar.py\n\n')
def test_autoupdate_local_hooks_with_out_of_date_repo( out_of_date_repo, in_tmpdir, mock_out_store_directory): stale_config = make_config_from_repo( out_of_date_repo.path, sha=out_of_date_repo.original_sha, check=False, ) local_config = config_with_local_hooks() config = [local_config, stale_config] write_config('.', config) runner = Runner('.') assert autoupdate(runner) == 0 new_config_writen = load_config(runner.config_file_path) assert len(new_config_writen) == 2 assert new_config_writen[0] == local_config
def test_autoupdate_hook_disappearing_repo(hook_disappearing_repo, in_tmpdir, mock_out_store_directory): config = make_config_from_repo( hook_disappearing_repo.path, sha=hook_disappearing_repo.original_sha, hooks=[OrderedDict((('id', 'foo'), ))], check=False, ) write_config('.', config) before = open(C.CONFIG_FILE).read() ret = autoupdate(Runner('.', C.CONFIG_FILE), tags_only=False) after = open(C.CONFIG_FILE).read() assert ret == 1 assert before == after
def test_autoupdate_hook_disappearing_repo( hook_disappearing_repo, in_tmpdir, mock_out_store_directory, ): config = make_config_from_repo( hook_disappearing_repo.path, sha=hook_disappearing_repo.original_sha, hooks=[OrderedDict((('id', 'foo'),))], check=False, ) write_config('.', config) before = open(C.CONFIG_FILE).read() ret = autoupdate(Runner('.', C.CONFIG_FILE), tags_only=False) after = open(C.CONFIG_FILE).read() assert ret == 1 assert before == after
def test_autoupdate_out_of_date_repo_with_wrong_repo_name( out_of_date_repo, in_tmpdir, mock_out_store_directory, ): # Write out the config config = make_config_from_repo( out_of_date_repo.path, rev=out_of_date_repo.original_rev, check=False, ) write_config('.', config) runner = Runner('.', C.CONFIG_FILE) before = open(C.CONFIG_FILE).read() # It will not update it, because the name doesn't match ret = autoupdate(runner, tags_only=False, repos=('wrong_repo_name',)) after = open(C.CONFIG_FILE).read() assert ret == 0 assert before == after
def test_autoupdate_out_of_date_repo(out_of_date_repo, in_tmpdir, store): # Write out the config config = make_config_from_repo( out_of_date_repo.path, rev=out_of_date_repo.original_rev, check=False, ) write_config('.', config) with open(C.CONFIG_FILE) as f: before = f.read() ret = autoupdate(C.CONFIG_FILE, store, tags_only=False) with open(C.CONFIG_FILE) as f: after = f.read() assert ret == 0 assert before != after # Make sure we don't add defaults assert 'exclude' not in after assert out_of_date_repo.head_rev in after
def test_autoupdate_out_of_date_repo( out_of_date_repo, in_tmpdir, mock_out_store_directory, ): # Write out the config config = make_config_from_repo( out_of_date_repo.path, sha=out_of_date_repo.original_sha, check=False, ) write_config('.', config) before = open(C.CONFIG_FILE).read() ret = autoupdate(Runner('.', C.CONFIG_FILE), tags_only=False) after = open(C.CONFIG_FILE).read() assert ret == 0 assert before != after # Make sure we don't add defaults assert 'exclude' not in after assert out_of_date_repo.head_sha in after
def failing_prepare_commit_msg_repo(tempdir_factory): path = git_dir(tempdir_factory) config = { 'repo': 'local', 'hooks': [{ 'id': 'add-signoff', 'name': 'Add "Signed off by:"', 'entry': 'bash -c "exit 1"', 'language': 'system', 'stages': ['prepare-commit-msg'], }], } write_config(path, config) with cwd(path): cmd_output('git', 'add', '.') git_commit(msg=failing_prepare_commit_msg_repo.__name__) yield path
def commit_msg_repo(tempdir_factory): path = git_dir(tempdir_factory) config = { 'repo': 'local', 'hooks': [{ 'id': 'must-have-signoff', 'name': 'Must have "Signed off by:"', 'entry': 'grep -q "Signed off by:"', 'language': 'system', 'stages': ['commit-msg'], }], } write_config(path, config) with cwd(path): cmd_output('git', 'add', '.') git_commit(msg=commit_msg_repo.__name__) yield path
def test_autoupdate_out_of_date_repo_with_wrong_repo_name( out_of_date_repo, in_tmpdir, store, ): # Write out the config config = make_config_from_repo( out_of_date_repo.path, rev=out_of_date_repo.original_rev, check=False, ) write_config('.', config) with open(C.CONFIG_FILE) as f: before = f.read() # It will not update it, because the name doesn't match ret = autoupdate(C.CONFIG_FILE, store, tags_only=False, repos=('dne',)) with open(C.CONFIG_FILE) as f: after = f.read() assert ret == 0 assert before == after
def test_autoupdate_hook_disappearing_repo( hook_disappearing_repo, in_tmpdir, store, ): config = make_config_from_repo( hook_disappearing_repo.path, rev=hook_disappearing_repo.original_rev, hooks=[{'id': 'foo'}], check=False, ) write_config('.', config) with open(C.CONFIG_FILE) as f: before = f.read() ret = autoupdate(C.CONFIG_FILE, store, tags_only=False) with open(C.CONFIG_FILE) as f: after = f.read() assert ret == 1 assert before == after
def test_invalid_manifest_gcd(tempdir_factory, store, in_git_dir, cap_out): # clean up repos from old pre-commit versions path = make_repo(tempdir_factory, 'script_hooks_repo') write_config('.', make_config_from_repo(path)) store.mark_config_used(C.CONFIG_FILE) # trigger a clone assert not autoupdate(C.CONFIG_FILE, store, tags_only=False) # we'll "break" the manifest to simulate an old version clone (_, _, path), = store.select_all_repos() os.remove(os.path.join(path, C.MANIFEST_FILE)) assert _config_count(store) == 1 assert _repo_count(store) == 1 assert not gc(store) assert _config_count(store) == 1 assert _repo_count(store) == 0 assert cap_out.get().splitlines()[-1] == '1 repo(s) removed.'
def test_gc(tempdir_factory, store, in_git_dir, cap_out): path = make_repo(tempdir_factory, 'script_hooks_repo') old_rev = git.head_rev(path) git_commit(cwd=path) write_config('.', make_config_from_repo(path, rev=old_rev)) store.mark_config_used(C.CONFIG_FILE) # update will clone both the old and new repo, making the old one gc-able assert not autoupdate(C.CONFIG_FILE, store, tags_only=False) assert _config_count(store) == 1 assert _repo_count(store) == 2 assert not gc(store) assert _config_count(store) == 1 assert _repo_count(store) == 1 assert cap_out.get().splitlines()[-1] == '1 repo(s) removed.' _remove_config_assert_cleared(store, cap_out)
def commit_msg_repo(tempdir_factory): path = git_dir(tempdir_factory) config = collections.OrderedDict(( ('repo', 'local'), ( 'hooks', [collections.OrderedDict(( ('id', 'must-have-signoff'), ('name', 'Must have "Signed off by:"'), ('entry', 'grep -q "Signed off by:"'), ('language', 'system'), ('stages', ['commit-msg']), ))], ), )) write_config(path, config) with cwd(path): cmd_output('git', 'add', '.') cmd_output('git', 'commit', '-m', 'add hooks') yield path
def test_autoupdate_out_of_date_repo_with_correct_repo_name( out_of_date_repo, in_tmpdir, store, ): stale_config = make_config_from_repo( out_of_date_repo.path, rev=out_of_date_repo.original_rev, check=False, ) local_config = sample_local_config() config = {'repos': [stale_config, local_config]} # Write out the config write_config('.', config) with open(C.CONFIG_FILE) as f: before = f.read() repo_name = 'file://{}'.format(out_of_date_repo.path) ret = autoupdate(C.CONFIG_FILE, store, tags_only=False, repos=(repo_name,)) with open(C.CONFIG_FILE) as f: after = f.read() assert ret == 0 assert before != after assert out_of_date_repo.head_rev in after assert 'local' in after
def test_gc_config_with_missing_hook( tempdir_factory, store, in_git_dir, cap_out, ): path = make_repo(tempdir_factory, 'script_hooks_repo') write_config('.', make_config_from_repo(path)) store.mark_config_used(C.CONFIG_FILE) # to trigger a clone all_hooks(load_config(C.CONFIG_FILE), store) with modify_config() as config: # add a hook which does not exist, make sure we don't crash config['repos'][0]['hooks'].append({'id': 'does-not-exist'}) assert _config_count(store) == 1 assert _repo_count(store) == 1 assert not gc(store) assert _config_count(store) == 1 assert _repo_count(store) == 1 assert cap_out.get().splitlines()[-1] == '0 repo(s) removed.' _remove_config_assert_cleared(store, cap_out)
def test_gc_local_repo_does_not_crash(store, in_git_dir, cap_out): write_config('.', sample_local_config()) store.mark_config_used(C.CONFIG_FILE) assert not gc(store) assert cap_out.get().splitlines()[-1] == '0 repo(s) removed.'