def test_loses_formatting_when_not_detectable( out_of_date_repo, store, in_tmpdir, ): """A best-effort attempt is made at updating rev without rewriting formatting. When the original formatting cannot be detected, this is abandoned. """ config = ('repos: [\n' ' {{\n' ' repo: {}, rev: {},\n' ' hooks: [\n' ' # A comment!\n' ' {{id: foo}},\n' ' ],\n' ' }}\n' ']\n'.format( pipes.quote(out_of_date_repo.path), out_of_date_repo.original_rev, )) with open(C.CONFIG_FILE, 'w') as f: f.write(config) autoupdate(Runner('.', C.CONFIG_FILE), store, tags_only=False) with open(C.CONFIG_FILE) as f: after = f.read() expected = ('repos:\n' '- repo: {}\n' ' rev: {}\n' ' hooks:\n' ' - id: foo\n').format(out_of_date_repo.path, out_of_date_repo.head_rev) assert after == expected
def test_loses_formatting_when_not_detectable( out_of_date_repo, mock_out_store_directory, in_tmpdir, ): """A best-effort attempt is made at updating sha without rewriting formatting. When the original formatting cannot be detected, this is abandoned. """ config = ( 'repos: [\n' ' {{\n' ' repo: {}, sha: {},\n' ' hooks: [\n' ' # A comment!\n' ' {{id: foo}},\n' ' ],\n' ' }}\n' ']\n'.format( pipes.quote(out_of_date_repo.path), out_of_date_repo.original_sha, ) ) with open(C.CONFIG_FILE, 'w') as f: f.write(config) autoupdate(Runner('.', C.CONFIG_FILE), tags_only=False) after = open(C.CONFIG_FILE).read() expected = ( 'repos:\n' '- repo: {}\n' ' sha: {}\n' ' hooks:\n' ' - id: foo\n' ).format(out_of_date_repo.path, out_of_date_repo.head_sha) assert after == expected
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_does_not_reformat(in_tmpdir, out_of_date_repo, store): fmt = ('repos:\n' '- repo: {}\n' ' rev: {} # definitely the version I want!\n' ' hooks:\n' ' - id: foo\n' ' # These args are because reasons!\n' ' args: [foo, bar, baz]\n') config = fmt.format(out_of_date_repo.path, out_of_date_repo.original_rev) with open(C.CONFIG_FILE, 'w') as f: f.write(config) autoupdate(Runner('.', C.CONFIG_FILE), store, tags_only=False) after = open(C.CONFIG_FILE).read() expected = fmt.format(out_of_date_repo.path, out_of_date_repo.head_rev) assert after == expected
def test_autoupdate_only_one_to_update(up_to_date, out_of_date, tmpdir, store): fmt = ('repos:\n' '- repo: {}\n' ' rev: {}\n' ' hooks:\n' ' - id: foo\n' '- repo: {}\n' ' rev: {}\n' ' hooks:\n' ' - id: foo\n') cfg = tmpdir.join(C.CONFIG_FILE) before = fmt.format( up_to_date, git.head_rev(up_to_date), out_of_date.path, out_of_date.original_rev, ) cfg.write(before) assert autoupdate(str(cfg), store, freeze=False, tags_only=False) == 0 assert cfg.read() == fmt.format( up_to_date, git.head_rev(up_to_date), out_of_date.path, out_of_date.head_rev, )
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_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 test_updates_old_format_to_new_format(tmpdir, capsys, store): cfg = tmpdir.join(C.CONFIG_FILE) cfg.write( '- repo: local\n' ' hooks:\n' ' - id: foo\n' ' name: foo\n' ' entry: ./bin/foo.sh\n' ' language: script\n', ) with tmpdir.as_cwd(): ret = autoupdate(C.CONFIG_FILE, store, tags_only=True) assert ret == 0 contents = cfg.read() assert contents == ( 'repos:\n' '- repo: local\n' ' hooks:\n' ' - id: foo\n' ' name: foo\n' ' entry: ./bin/foo.sh\n' ' language: script\n' ) out, _ = capsys.readouterr() assert out == 'Configuration has been migrated.\n'
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_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_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_loses_formatting_when_not_detectable(out_of_date, store, tmpdir): """A best-effort attempt is made at updating rev without rewriting formatting. When the original formatting cannot be detected, this is abandoned. """ config = ('repos: [\n' ' {{\n' ' repo: {}, rev: {},\n' ' hooks: [\n' ' # A comment!\n' ' {{id: foo}},\n' ' ],\n' ' }}\n' ']\n'.format( shlex.quote(out_of_date.path), out_of_date.original_rev, )) cfg = tmpdir.join(C.CONFIG_FILE) cfg.write(config) assert autoupdate(str(cfg), store, freeze=False, tags_only=False) == 0 expected = (f'repos:\n' f'- repo: {out_of_date.path}\n' f' rev: {out_of_date.head_rev}\n' f' hooks:\n' f' - id: foo\n') assert cfg.read() == expected
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, 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_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_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_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_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_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_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) 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_autoupdate_local_hooks(tempdir_factory, store): 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, store, 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_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_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_does_not_reformat(in_tmpdir, out_of_date_repo, store): fmt = ( 'repos:\n' '- repo: {}\n' ' rev: {} # definitely the version I want!\n' ' hooks:\n' ' - id: foo\n' ' # These args are because reasons!\n' ' args: [foo, bar, baz]\n' ) config = fmt.format(out_of_date_repo.path, out_of_date_repo.original_rev) with open(C.CONFIG_FILE, 'w') as f: f.write(config) autoupdate(C.CONFIG_FILE, store, tags_only=False) with open(C.CONFIG_FILE) as f: after = f.read() expected = fmt.format(out_of_date_repo.path, out_of_date_repo.head_rev) assert after == expected
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_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_does_not_reformat( out_of_date_repo, mock_out_store_directory, in_tmpdir, ): fmt = ( 'repos:\n' '- repo: {}\n' ' sha: {} # definitely the version I want!\n' ' hooks:\n' ' - id: foo\n' ' # These args are because reasons!\n' ' args: [foo, bar, baz]\n' ) config = fmt.format(out_of_date_repo.path, out_of_date_repo.original_sha) with open(C.CONFIG_FILE, 'w') as f: f.write(config) autoupdate(Runner('.', C.CONFIG_FILE), tags_only=False) after = open(C.CONFIG_FILE).read() expected = fmt.format(out_of_date_repo.path, out_of_date_repo.head_sha) assert after == expected
def test_autoupdate_hook_disappearing_repo(hook_disappearing, tmpdir, store): contents = (f'repos:\n' f'- repo: {hook_disappearing.path}\n' f' rev: {hook_disappearing.original_rev}\n' f' hooks:\n' f' - id: foo\n') cfg = tmpdir.join(C.CONFIG_FILE) cfg.write(contents) assert autoupdate(str(cfg), store, freeze=False, tags_only=False) == 1 assert cfg.read() == contents
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_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_autoupdate_up_to_date_repo(up_to_date, tmpdir, store): contents = (f'repos:\n' f'- repo: {up_to_date}\n' f' rev: {git.head_rev(up_to_date)}\n' f' hooks:\n' f' - id: foo\n') cfg = tmpdir.join(C.CONFIG_FILE) cfg.write(contents) assert autoupdate(str(cfg), store, freeze=False, tags_only=False) == 0 assert cfg.read() == contents
def test_autoupdate_meta_hooks(tmpdir, store): cfg = tmpdir.join(C.CONFIG_FILE) cfg.write( 'repos:\n' '- repo: meta\n' ' hooks:\n' ' - id: check-useless-excludes\n', ) assert autoupdate(str(cfg), store, freeze=False, tags_only=True) == 0 assert cfg.read() == ('repos:\n' '- repo: meta\n' ' hooks:\n' ' - id: check-useless-excludes\n')
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_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, 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_meta_hooks(tmpdir, capsys): cfg = tmpdir.join(C.CONFIG_FILE) cfg.write( 'repos:\n' '- repo: meta\n' ' hooks:\n' ' - id: check-useless-excludes\n', ) ret = autoupdate(Runner(tmpdir.strpath, C.CONFIG_FILE), tags_only=True) assert ret == 0 assert cfg.read() == ('repos:\n' '- repo: meta\n' ' hooks:\n' ' - id: check-useless-excludes\n')
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_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_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_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_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_does_not_reformat(tmpdir, out_of_date, store): fmt = ('repos:\n' '- repo: {}\n' ' rev: {} # definitely the version I want!\n' ' hooks:\n' ' - id: foo\n' ' # These args are because reasons!\n' ' args: [foo, bar, baz]\n') cfg = tmpdir.join(C.CONFIG_FILE) cfg.write(fmt.format(out_of_date.path, out_of_date.original_rev)) assert autoupdate(str(cfg), store, freeze=False, tags_only=False) == 0 expected = fmt.format(out_of_date.path, out_of_date.head_rev) assert cfg.read() == expected
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(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_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_meta_hooks(tmpdir, capsys, store): cfg = tmpdir.join(C.CONFIG_FILE) cfg.write( 'repos:\n' '- repo: meta\n' ' hooks:\n' ' - id: check-useless-excludes\n', ) with tmpdir.as_cwd(): ret = autoupdate(C.CONFIG_FILE, store, tags_only=True) assert ret == 0 assert cfg.read() == ( 'repos:\n' '- repo: meta\n' ' hooks:\n' ' - id: check-useless-excludes\n' )
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 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 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 main(argv=None): argv = argv if argv is not None else sys.argv[1:] argv = [five.to_text(arg) for arg in argv] parser = argparse.ArgumentParser() # http://stackoverflow.com/a/8521644/812183 parser.add_argument( '-V', '--version', action='version', version='%(prog)s {}'.format(C.VERSION), ) subparsers = parser.add_subparsers(dest='command') install_parser = subparsers.add_parser( 'install', help='Install the pre-commit script.', ) _add_color_option(install_parser) _add_config_option(install_parser) install_parser.add_argument( '-f', '--overwrite', action='store_true', help='Overwrite existing hooks / remove migration mode.', ) install_parser.add_argument( '--install-hooks', action='store_true', help=( 'Whether to install hook environments for all environments ' 'in the config file.' ), ) _add_hook_type_option(install_parser) install_parser.add_argument( '--allow-missing-config', action='store_true', default=False, help=( 'Whether to allow a missing `pre-commit` configuration file ' 'or exit with a failure code.' ), ) install_hooks_parser = subparsers.add_parser( 'install-hooks', help=( 'Install hook environments for all environments in the config ' 'file. You may find `pre-commit install --install-hooks` more ' 'useful.' ), ) _add_color_option(install_hooks_parser) _add_config_option(install_hooks_parser) uninstall_parser = subparsers.add_parser( 'uninstall', help='Uninstall the pre-commit script.', ) _add_color_option(uninstall_parser) _add_config_option(uninstall_parser) _add_hook_type_option(uninstall_parser) clean_parser = subparsers.add_parser( 'clean', help='Clean out pre-commit files.', ) _add_color_option(clean_parser) _add_config_option(clean_parser) autoupdate_parser = subparsers.add_parser( 'autoupdate', help="Auto-update pre-commit config to the latest repos' versions.", ) _add_color_option(autoupdate_parser) _add_config_option(autoupdate_parser) autoupdate_parser.add_argument( '--tags-only', action='store_true', help='LEGACY: for compatibility', ) autoupdate_parser.add_argument( '--bleeding-edge', action='store_true', help=( 'Update to the bleeding edge of `master` instead of the latest ' 'tagged version (the default behavior).' ), ) migrate_config_parser = subparsers.add_parser( 'migrate-config', help='Migrate list configuration to new map configuration.', ) _add_color_option(migrate_config_parser) _add_config_option(migrate_config_parser) run_parser = subparsers.add_parser('run', help='Run hooks.') _add_color_option(run_parser) _add_config_option(run_parser) run_parser.add_argument('hook', nargs='?', help='A single hook-id to run') 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`.", ) run_parser.add_argument( '--source', '-s', help="The remote branch's commit_id when using `git push`.", ) run_parser.add_argument( '--commit-msg-filename', help='Filename to check when running during `commit-msg`', ) run_parser.add_argument( '--hook-stage', choices=('commit', 'push', 'commit-msg'), default='commit', help='The stage during which the hook is fired e.g. commit or push.', ) run_parser.add_argument( '--show-diff-on-failure', action='store_true', help='When hooks fail, run `git diff` directly afterward.', ) run_mutex_group = run_parser.add_mutually_exclusive_group(required=False) run_mutex_group.add_argument( '--all-files', '-a', action='store_true', default=False, help='Run on all the files in the repo.', ) run_mutex_group.add_argument( '--files', nargs='*', default=[], help='Specific filenames to run hooks on.', ) sample_config_parser = subparsers.add_parser( 'sample-config', help='Produce a sample {} file'.format(C.CONFIG_FILE), ) _add_color_option(sample_config_parser) _add_config_option(sample_config_parser) help = subparsers.add_parser( 'help', help='Show help for a specific command.', ) help.add_argument('help_cmd', nargs='?', help='Command to show help for.') # Argparse doesn't really provide a way to use a `default` subparser if len(argv) == 0: argv = ['run'] args = parser.parse_args(argv) if args.command == 'run': args.files = [ os.path.relpath(os.path.abspath(filename), git.get_root()) for filename in args.files ] if args.command == 'help': if args.help_cmd: parser.parse_args([args.help_cmd, '--help']) else: parser.parse_args(['--help']) with error_handler(): add_logging_handler(args.color) runner = Runner.create(args.config) git.check_for_cygwin_mismatch() if args.command == 'install': return install( runner, overwrite=args.overwrite, hooks=args.install_hooks, hook_type=args.hook_type, skip_on_missing_conf=args.allow_missing_config, ) elif args.command == 'install-hooks': return install_hooks(runner) elif args.command == 'uninstall': return uninstall(runner, hook_type=args.hook_type) elif args.command == 'clean': return clean(runner) elif args.command == 'autoupdate': if args.tags_only: logger.warning('--tags-only is the default') return autoupdate(runner, tags_only=not args.bleeding_edge) elif args.command == 'migrate-config': return migrate_config(runner) elif args.command == 'run': return run(runner, args) elif args.command == 'sample-config': return sample_config() else: raise NotImplementedError( 'Command {} not implemented.'.format(args.command), ) raise AssertionError( 'Command {} failed to exit with a returncode'.format(args.command), )
def main(argv=None): argv = argv if argv is not None else sys.argv[1:] argv = [five.to_text(arg) for arg in argv] parser = argparse.ArgumentParser() # https://stackoverflow.com/a/8521644/812183 parser.add_argument( '-V', '--version', action='version', version='%(prog)s {}'.format(C.VERSION), ) subparsers = parser.add_subparsers(dest='command') install_parser = subparsers.add_parser( 'install', help='Install the pre-commit script.', ) _add_color_option(install_parser) _add_config_option(install_parser) install_parser.add_argument( '-f', '--overwrite', action='store_true', help='Overwrite existing hooks / remove migration mode.', ) install_parser.add_argument( '--install-hooks', action='store_true', help=( 'Whether to install hook environments for all environments ' 'in the config file.' ), ) _add_hook_type_option(install_parser) install_parser.add_argument( '--allow-missing-config', action='store_true', default=False, help=( 'Whether to allow a missing `pre-commit` configuration file ' 'or exit with a failure code.' ), ) install_hooks_parser = subparsers.add_parser( 'install-hooks', help=( 'Install hook environments for all environments in the config ' 'file. You may find `pre-commit install --install-hooks` more ' 'useful.' ), ) _add_color_option(install_hooks_parser) _add_config_option(install_hooks_parser) uninstall_parser = subparsers.add_parser( 'uninstall', help='Uninstall the pre-commit script.', ) _add_color_option(uninstall_parser) _add_config_option(uninstall_parser) _add_hook_type_option(uninstall_parser) clean_parser = subparsers.add_parser( 'clean', help='Clean out pre-commit files.', ) _add_color_option(clean_parser) _add_config_option(clean_parser) gc_parser = subparsers.add_parser('gc', help='Clean unused cached repos.') _add_color_option(gc_parser) _add_config_option(gc_parser) autoupdate_parser = subparsers.add_parser( 'autoupdate', help="Auto-update pre-commit config to the latest repos' versions.", ) _add_color_option(autoupdate_parser) _add_config_option(autoupdate_parser) autoupdate_parser.add_argument( '--tags-only', action='store_true', help='LEGACY: for compatibility', ) autoupdate_parser.add_argument( '--bleeding-edge', action='store_true', help=( 'Update to the bleeding edge of `master` instead of the latest ' 'tagged version (the default behavior).' ), ) autoupdate_parser.add_argument( '--repo', dest='repos', action='append', metavar='REPO', help='Only update this repository -- may be specified multiple times.', ) migrate_config_parser = subparsers.add_parser( 'migrate-config', help='Migrate list configuration to new map configuration.', ) _add_color_option(migrate_config_parser) _add_config_option(migrate_config_parser) run_parser = subparsers.add_parser('run', help='Run hooks.') _add_color_option(run_parser) _add_config_option(run_parser) _add_run_options(run_parser) sample_config_parser = subparsers.add_parser( 'sample-config', help='Produce a sample {} file'.format(C.CONFIG_FILE), ) _add_color_option(sample_config_parser) _add_config_option(sample_config_parser) try_repo_parser = subparsers.add_parser( 'try-repo', help='Try the hooks in a repository, useful for developing new hooks.', ) _add_color_option(try_repo_parser) _add_config_option(try_repo_parser) try_repo_parser.add_argument( 'repo', help='Repository to source hooks from.', ) try_repo_parser.add_argument( '--ref', '--rev', help=( 'Manually select a rev to run against, otherwise the `HEAD` ' 'revision will be used.' ), ) _add_run_options(try_repo_parser) help = subparsers.add_parser( 'help', help='Show help for a specific command.', ) help.add_argument('help_cmd', nargs='?', help='Command to show help for.') # argparse doesn't really provide a way to use a `default` subparser if len(argv) == 0: argv = ['run'] args = parser.parse_args(argv) if args.command == 'help' and args.help_cmd: parser.parse_args([args.help_cmd, '--help']) elif args.command == 'help': parser.parse_args(['--help']) with error_handler(), logging_handler(args.color): if args.command not in {'clean', 'gc', 'sample-config'}: _adjust_args_and_chdir(args) git.check_for_cygwin_mismatch() store = Store() store.mark_config_used(args.config) if args.command == 'install': return install( args.config, store, overwrite=args.overwrite, hooks=args.install_hooks, hook_type=args.hook_type, skip_on_missing_conf=args.allow_missing_config, ) elif args.command == 'install-hooks': return install_hooks(args.config, store) elif args.command == 'uninstall': return uninstall(hook_type=args.hook_type) elif args.command == 'clean': return clean(store) elif args.command == 'gc': return gc(store) elif args.command == 'autoupdate': if args.tags_only: logger.warning('--tags-only is the default') return autoupdate( args.config, store, tags_only=not args.bleeding_edge, repos=args.repos, ) elif args.command == 'migrate-config': return migrate_config(args.config) elif args.command == 'run': return run(args.config, store, args) elif args.command == 'sample-config': return sample_config() elif args.command == 'try-repo': return try_repo(args) else: raise NotImplementedError( 'Command {} not implemented.'.format(args.command), ) raise AssertionError( 'Command {} failed to exit with a returncode'.format(args.command), )
def main(argv=None): argv = argv if argv is not None else sys.argv[1:] argv = [five.to_text(arg) for arg in argv] parser = argparse.ArgumentParser() # http://stackoverflow.com/a/8521644/812183 parser.add_argument( '-V', '--version', action='version', version='%(prog)s {}'.format( pkg_resources.get_distribution('pre-commit').version ) ) subparsers = parser.add_subparsers(dest='command') install_parser = subparsers.add_parser( 'install', help='Install the pre-commit script.', ) _add_color_option(install_parser) _add_config_option(install_parser) install_parser.add_argument( '-f', '--overwrite', action='store_true', help='Overwrite existing hooks / remove migration mode.', ) install_parser.add_argument( '--install-hooks', action='store_true', help=( 'Whether to install hook environments for all environments ' 'in the config file.' ), ) install_parser.add_argument( '-t', '--hook-type', choices=('pre-commit', 'pre-push'), default='pre-commit', ) install_hooks_parser = subparsers.add_parser( 'install-hooks', help=( 'Install hook environemnts for all environemnts in the config ' 'file. You may find `pre-commit install --install-hooks` more ' 'useful.' ), ) _add_color_option(install_hooks_parser) _add_config_option(install_hooks_parser) uninstall_parser = subparsers.add_parser( 'uninstall', help='Uninstall the pre-commit script.', ) _add_color_option(uninstall_parser) _add_config_option(uninstall_parser) uninstall_parser.add_argument( '-t', '--hook-type', choices=('pre-commit', 'pre-push'), default='pre-commit', ) clean_parser = subparsers.add_parser( 'clean', help='Clean out pre-commit files.', ) _add_color_option(clean_parser) _add_config_option(clean_parser) autoupdate_parser = subparsers.add_parser( 'autoupdate', help="Auto-update pre-commit config to the latest repos' versions.", ) _add_color_option(autoupdate_parser) _add_config_option(autoupdate_parser) run_parser = subparsers.add_parser('run', help='Run hooks.') _add_color_option(run_parser) _add_config_option(run_parser) run_parser.add_argument('hook', nargs='?', help='A single hook-id to run') run_parser.add_argument( '--no-stash', default=False, action='store_true', help='Use this option to prevent auto stashing of unstaged files.', ) 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`.", ) run_parser.add_argument( '--source', '-s', help="The remote branch's commit_id when using `git push`.", ) run_parser.add_argument( '--allow-unstaged-config', default=False, action='store_true', 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, help='Run on all the files in the repo. Implies --no-stash.', ) run_mutex_group.add_argument( '--files', nargs='*', default=[], help='Specific filenames to run hooks on.', ) help = subparsers.add_parser( 'help', help='Show help for a specific command.', ) help.add_argument('help_cmd', nargs='?', help='Command to show help for.') # Argparse doesn't really provide a way to use a `default` subparser if len(argv) == 0: argv = ['run'] args = parser.parse_args(argv) if args.command == 'run': args.files = [ os.path.relpath(os.path.abspath(filename), git.get_root()) for filename in args.files ] if args.command == 'help': if args.help_cmd: parser.parse_args([args.help_cmd, '--help']) else: parser.parse_args(['--help']) with error_handler(): add_logging_handler(args.color) runner = Runner.create(args.config) git.check_for_cygwin_mismatch() if args.command == 'install': return install( runner, overwrite=args.overwrite, hooks=args.install_hooks, hook_type=args.hook_type, ) elif args.command == 'install-hooks': return install_hooks(runner) elif args.command == 'uninstall': return uninstall(runner, hook_type=args.hook_type) elif args.command == 'clean': return clean(runner) elif args.command == 'autoupdate': return autoupdate(runner) elif args.command == 'run': return run(runner, args) else: raise NotImplementedError( 'Command {} not implemented.'.format(args.command) ) raise AssertionError( 'Command {} failed to exit with a returncode'.format(args.command) )
def main(argv=None): argv = argv if argv is not None else sys.argv[1:] parser = argparse.ArgumentParser() # http://stackoverflow.com/a/8521644/812183 parser.add_argument( '-V', '--version', action='version', version='%(prog)s {0}'.format( pkg_resources.get_distribution('pre-commit').version ) ) subparsers = parser.add_subparsers(dest='command') install_parser = subparsers.add_parser( 'install', help='Install the pre-commit script.', ) install_parser.add_argument( '-f', '--overwrite', action='store_true', help='Overwrite existing hooks / remove migration mode.', ) install_parser.add_argument( '--install-hooks', action='store_true', help=( 'Whether to install hook environments for all environments ' 'in the config file.' ), ) subparsers.add_parser('uninstall', help='Uninstall the pre-commit script.') subparsers.add_parser('clean', help='Clean out pre-commit files.') subparsers.add_parser( 'autoupdate', help="Auto-update pre-commit config to the latest repos' versions.", ) run_parser = subparsers.add_parser('run', help='Run hooks.') run_parser.add_argument('hook', nargs='?', help='A single hook-id to run') run_parser.add_argument( '--color', default='auto', type=color.use_color, help='Whether to use color in output. Defaults to `auto`', ) run_parser.add_argument( '--no-stash', default=False, action='store_true', help='Use this option to prevent auto stashing of unstaged files.', ) run_parser.add_argument( '--verbose', '-v', action='store_true', default=False, ) run_mutex_group = run_parser.add_mutually_exclusive_group(required=False) run_mutex_group.add_argument( '--all-files', '-a', action='store_true', default=False, help='Run on all the files in the repo. Implies --no-stash.', ) run_mutex_group.add_argument( '--files', nargs='*', help='Specific filenames to run hooks on.', ) help = subparsers.add_parser( 'help', help='Show help for a specific command.' ) help.add_argument('help_cmd', nargs='?', help='Command to show help for.') # Argparse doesn't really provide a way to use a `default` subparser if len(argv) == 0: argv = ['run'] args = parser.parse_args(argv) if args.command == 'help': if args.help_cmd: parser.parse_args([args.help_cmd, '--help']) else: parser.parse_args(['--help']) with error_handler(): runner = Runner.create() if args.command == 'install': return install( runner, overwrite=args.overwrite, hooks=args.install_hooks, ) elif args.command == 'uninstall': return uninstall(runner) elif args.command == 'clean': return clean(runner) elif args.command == 'autoupdate': return autoupdate(runner) elif args.command == 'run': return run(runner, args) else: raise NotImplementedError( 'Command {0} not implemented.'.format(args.command) ) raise AssertionError( 'Command {0} failed to exit with a returncode'.format(args.command) )