diff --git a/pre_commit/commands/autoupdate.py b/pre_commit/commands/autoupdate.py index 27b8d98d..293c81fc 100644 --- a/pre_commit/commands/autoupdate.py +++ b/pre_commit/commands/autoupdate.py @@ -54,7 +54,7 @@ def _update_repo(repo_config, runner, tags_only): new_repo = Repository.create(new_config, runner.store) # See if any of our hooks were deleted with the new commits - hooks = {hook_id for hook_id, _ in repo.hooks} + hooks = {hook['id'] for hook in repo.repo_config['hooks']} hooks_missing = hooks - (hooks & set(new_repo.manifest.hooks)) if hooks_missing: raise RepositoryCannotBeUpdatedError( diff --git a/pre_commit/manifest.py b/pre_commit/manifest.py index 8827eccc..55f7c1ae 100644 --- a/pre_commit/manifest.py +++ b/pre_commit/manifest.py @@ -22,9 +22,7 @@ class Manifest(object): repo_path = self.repo_path_getter.repo_path default_path = os.path.join(repo_path, C.MANIFEST_FILE) legacy_path = os.path.join(repo_path, C.MANIFEST_FILE_LEGACY) - if os.path.exists(default_path): - return load_manifest(default_path) - else: + if os.path.exists(legacy_path) and not os.path.exists(default_path): logger.warning( '{} uses legacy {} to provide hooks.\n' 'In newer versions, this file is called {}\n' @@ -36,6 +34,8 @@ class Manifest(object): ) ) return load_manifest(legacy_path) + else: + return load_manifest(default_path) @cached_property def hooks(self): diff --git a/tests/commands/autoupdate_test.py b/tests/commands/autoupdate_test.py index 29bc087b..b5858ff0 100644 --- a/tests/commands/autoupdate_test.py +++ b/tests/commands/autoupdate_test.py @@ -51,6 +51,35 @@ def test_autoupdate_up_to_date_repo( assert before == 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 = 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 + + @pytest.yield_fixture def out_of_date_repo(tempdir_factory): path = make_repo(tempdir_factory, 'python_hooks_repo')