From 52cd42316c4744cdc7c9bf9a5b13375bb7899d62 Mon Sep 17 00:00:00 2001 From: Anthony Sottile Date: Wed, 25 Jan 2017 21:02:50 -0800 Subject: [PATCH] Add a --tags-only option to autoupdate --- pre_commit/commands/autoupdate.py | 15 ++++++----- pre_commit/main.py | 5 +++- tests/commands/autoupdate_test.py | 44 ++++++++++++++++++++++--------- 3 files changed, 44 insertions(+), 20 deletions(-) diff --git a/pre_commit/commands/autoupdate.py b/pre_commit/commands/autoupdate.py index 621f7156..5614a1cd 100644 --- a/pre_commit/commands/autoupdate.py +++ b/pre_commit/commands/autoupdate.py @@ -21,7 +21,7 @@ class RepositoryCannotBeUpdatedError(RuntimeError): pass -def _update_repository(repo_config, runner): +def _update_repo(repo_config, runner, tags_only): """Updates a repository to the tip of `master`. If the repository cannot be updated because a hook that is configured does not exist in `master`, this raises a RepositoryCannotBeUpdatedError @@ -33,10 +33,13 @@ def _update_repository(repo_config, runner): with cwd(repo.repo_path_getter.repo_path): cmd_output('git', 'fetch') + tag_cmd = ('git', 'describe', 'origin/master', '--tags') + if tags_only: + tag_cmd += ('--abbrev=0',) + else: + tag_cmd += ('--exact',) try: - rev = cmd_output( - 'git', 'describe', 'origin/master', '--tags', '--exact', - )[1].strip() + rev = cmd_output(*tag_cmd)[1].strip() except CalledProcessError: rev = cmd_output('git', 'rev-parse', 'origin/master')[1].strip() @@ -61,7 +64,7 @@ def _update_repository(repo_config, runner): return new_config -def autoupdate(runner): +def autoupdate(runner, tags_only): """Auto-update the pre-commit config to the latest versions of repos.""" retv = 0 output_configs = [] @@ -78,7 +81,7 @@ def autoupdate(runner): continue output.write('Updating {}...'.format(repo_config['repo'])) try: - new_repo_config = _update_repository(repo_config, runner) + new_repo_config = _update_repo(repo_config, runner, tags_only) except RepositoryCannotBeUpdatedError as error: output.write_line(error.args[0]) output_configs.append(repo_config) diff --git a/pre_commit/main.py b/pre_commit/main.py index 3631197c..4108843f 100644 --- a/pre_commit/main.py +++ b/pre_commit/main.py @@ -111,6 +111,9 @@ def main(argv=None): ) _add_color_option(autoupdate_parser) _add_config_option(autoupdate_parser) + autoupdate_parser.add_argument( + '--tags-only', action='store_true', help='Update to tags only.', + ) run_parser = subparsers.add_parser('run', help='Run hooks.') _add_color_option(run_parser) @@ -190,7 +193,7 @@ def main(argv=None): elif args.command == 'clean': return clean(runner) elif args.command == 'autoupdate': - return autoupdate(runner) + return autoupdate(runner, args.tags_only) elif args.command == 'run': return run(runner, args) else: diff --git a/tests/commands/autoupdate_test.py b/tests/commands/autoupdate_test.py index 8924fb84..29e617d9 100644 --- a/tests/commands/autoupdate_test.py +++ b/tests/commands/autoupdate_test.py @@ -6,7 +6,7 @@ import pytest import pre_commit.constants as C from pre_commit.clientlib.validate_config import load_config -from pre_commit.commands.autoupdate import _update_repository +from pre_commit.commands.autoupdate import _update_repo from pre_commit.commands.autoupdate import autoupdate from pre_commit.commands.autoupdate import RepositoryCannotBeUpdatedError from pre_commit.ordereddict import OrderedDict @@ -32,7 +32,7 @@ def up_to_date_repo(tempdir_factory): def test_up_to_date_repo(up_to_date_repo, runner_with_mocked_store): config = make_config_from_repo(up_to_date_repo) input_sha = config['sha'] - ret = _update_repository(config, runner_with_mocked_store) + ret = _update_repo(config, runner_with_mocked_store, tags_only=False) assert ret['sha'] == input_sha @@ -45,8 +45,7 @@ def test_autoupdate_up_to_date_repo( before = open(C.CONFIG_FILE).read() assert '^$' not in before - runner = Runner('.', C.CONFIG_FILE) - ret = autoupdate(runner) + ret = autoupdate(Runner('.', C.CONFIG_FILE), tags_only=False) after = open(C.CONFIG_FILE).read() assert ret == 0 assert before == after @@ -71,7 +70,7 @@ def test_out_of_date_repo(out_of_date_repo, runner_with_mocked_store): config = make_config_from_repo( out_of_date_repo.path, sha=out_of_date_repo.original_sha, ) - ret = _update_repository(config, runner_with_mocked_store) + ret = _update_repo(config, runner_with_mocked_store, tags_only=False) assert ret['sha'] != out_of_date_repo.original_sha assert ret['sha'] == out_of_date_repo.head_sha @@ -86,8 +85,7 @@ def test_autoupdate_out_of_date_repo( write_config('.', config) before = open(C.CONFIG_FILE).read() - runner = Runner('.', C.CONFIG_FILE) - ret = autoupdate(runner) + ret = autoupdate(Runner('.', C.CONFIG_FILE), tags_only=False) after = open(C.CONFIG_FILE).read() assert ret == 0 assert before != after @@ -111,7 +109,28 @@ def test_autoupdate_tagged_repo( ) write_config('.', config) - ret = autoupdate(Runner('.', C.CONFIG_FILE)) + ret = autoupdate(Runner('.', C.CONFIG_FILE), tags_only=False) + assert ret == 0 + assert 'v1.2.3' in open(C.CONFIG_FILE).read() + + +@pytest.yield_fixture +def tagged_repo_with_more_commits(tagged_repo): + with cwd(tagged_repo.path): + cmd_output('git', 'commit', '--allow-empty', '-m', 'commit!') + yield tagged_repo + + +def test_autoupdate_tags_only( + tagged_repo_with_more_commits, in_tmpdir, mock_out_store_directory, +): + config = make_config_from_repo( + tagged_repo_with_more_commits.path, + sha=tagged_repo_with_more_commits.original_sha, + ) + write_config('.', config) + + ret = autoupdate(Runner('.', C.CONFIG_FILE), tags_only=True) assert ret == 0 assert 'v1.2.3' in open(C.CONFIG_FILE).read() @@ -141,7 +160,7 @@ def test_hook_disppearing_repo_raises( hooks=[OrderedDict((('id', 'foo'),))], ) with pytest.raises(RepositoryCannotBeUpdatedError): - _update_repository(config, runner_with_mocked_store) + _update_repo(config, runner_with_mocked_store, tags_only=False) def test_autoupdate_hook_disappearing_repo( @@ -156,8 +175,7 @@ def test_autoupdate_hook_disappearing_repo( write_config('.', config) before = open(C.CONFIG_FILE).read() - runner = Runner('.', C.CONFIG_FILE) - ret = autoupdate(runner) + ret = autoupdate(Runner('.', C.CONFIG_FILE), tags_only=False) after = open(C.CONFIG_FILE).read() assert ret == 1 assert before == after @@ -168,7 +186,7 @@ def test_autoupdate_local_hooks(tempdir_factory): config = config_with_local_hooks() path = add_config_to_repo(git_path, config) runner = Runner(path, C.CONFIG_FILE) - assert autoupdate(runner) == 0 + assert autoupdate(runner, tags_only=False) == 0 new_config_writen = load_config(runner.config_file_path) assert len(new_config_writen) == 1 assert new_config_writen[0] == config @@ -184,7 +202,7 @@ def test_autoupdate_local_hooks_with_out_of_date_repo( config = [local_config, stale_config] write_config('.', config) runner = Runner('.', C.CONFIG_FILE) - assert autoupdate(runner) == 0 + assert autoupdate(runner, tags_only=False) == 0 new_config_writen = load_config(runner.config_file_path) assert len(new_config_writen) == 2 assert new_config_writen[0] == local_config