perform autoupdate without Store contention

This commit is contained in:
Anthony Sottile 2023-04-29 15:19:20 -04:00
parent 27d77fc8bc
commit 4f045cbc21
4 changed files with 71 additions and 66 deletions

View file

@ -16,7 +16,6 @@ from pre_commit.clientlib import load_manifest
from pre_commit.clientlib import LOCAL from pre_commit.clientlib import LOCAL
from pre_commit.clientlib import META from pre_commit.clientlib import META
from pre_commit.commands.migrate_config import migrate_config from pre_commit.commands.migrate_config import migrate_config
from pre_commit.store import Store
from pre_commit.util import CalledProcessError from pre_commit.util import CalledProcessError
from pre_commit.util import cmd_output from pre_commit.util import cmd_output
from pre_commit.util import cmd_output_b from pre_commit.util import cmd_output_b
@ -27,11 +26,12 @@ from pre_commit.yaml import yaml_load
class RevInfo(NamedTuple): class RevInfo(NamedTuple):
repo: str repo: str
rev: str rev: str
frozen: str | None frozen: str | None = None
hook_ids: frozenset[str] = frozenset()
@classmethod @classmethod
def from_config(cls, config: dict[str, Any]) -> RevInfo: def from_config(cls, config: dict[str, Any]) -> RevInfo:
return cls(config['repo'], config['rev'], None) return cls(config['repo'], config['rev'])
def update(self, tags_only: bool, freeze: bool) -> RevInfo: def update(self, tags_only: bool, freeze: bool) -> RevInfo:
with tempfile.TemporaryDirectory() as tmp: with tempfile.TemporaryDirectory() as tmp:
@ -63,7 +63,19 @@ class RevInfo(NamedTuple):
exact = cmd_output(*_git, 'rev-parse', rev)[1].strip() exact = cmd_output(*_git, 'rev-parse', rev)[1].strip()
if exact != rev: if exact != rev:
rev, frozen = exact, rev rev, frozen = exact, rev
return self._replace(rev=rev, frozen=frozen)
try:
cmd_output(*_git, 'checkout', rev, '--', C.MANIFEST_FILE)
except CalledProcessError:
pass # this will be caught by manifest validating code
try:
manifest = load_manifest(os.path.join(tmp, C.MANIFEST_FILE))
except InvalidManifestError as e:
raise RepositoryCannotBeUpdatedError(str(e))
else:
hook_ids = frozenset(hook['id'] for hook in manifest)
return self._replace(rev=rev, frozen=frozen, hook_ids=hook_ids)
class RepositoryCannotBeUpdatedError(RuntimeError): class RepositoryCannotBeUpdatedError(RuntimeError):
@ -73,17 +85,10 @@ class RepositoryCannotBeUpdatedError(RuntimeError):
def _check_hooks_still_exist_at_rev( def _check_hooks_still_exist_at_rev(
repo_config: dict[str, Any], repo_config: dict[str, Any],
info: RevInfo, info: RevInfo,
store: Store,
) -> None: ) -> None:
try:
path = store.clone(repo_config['repo'], info.rev)
manifest = load_manifest(os.path.join(path, C.MANIFEST_FILE))
except InvalidManifestError as e:
raise RepositoryCannotBeUpdatedError(str(e))
# See if any of our hooks were deleted with the new commits # See if any of our hooks were deleted with the new commits
hooks = {hook['id'] for hook in repo_config['hooks']} hooks = {hook['id'] for hook in repo_config['hooks']}
hooks_missing = hooks - {hook['id'] for hook in manifest} hooks_missing = hooks - info.hook_ids
if hooks_missing: if hooks_missing:
raise RepositoryCannotBeUpdatedError( raise RepositoryCannotBeUpdatedError(
f'Cannot update because the update target is missing these ' f'Cannot update because the update target is missing these '
@ -139,7 +144,6 @@ def _write_new_config(path: str, rev_infos: list[RevInfo | None]) -> None:
def autoupdate( def autoupdate(
config_file: str, config_file: str,
store: Store,
tags_only: bool, tags_only: bool,
freeze: bool, freeze: bool,
repos: Sequence[str] = (), repos: Sequence[str] = (),
@ -161,9 +165,9 @@ def autoupdate(
continue continue
output.write(f'Updating {info.repo} ... ') output.write(f'Updating {info.repo} ... ')
new_info = info.update(tags_only=tags_only, freeze=freeze)
try: try:
_check_hooks_still_exist_at_rev(repo_config, new_info, store) new_info = info.update(tags_only=tags_only, freeze=freeze)
_check_hooks_still_exist_at_rev(repo_config, new_info)
except RepositoryCannotBeUpdatedError as error: except RepositoryCannotBeUpdatedError as error:
output.write_line(error.args[0]) output.write_line(error.args[0])
rev_infos.append(None) rev_infos.append(None)

View file

@ -368,7 +368,7 @@ def main(argv: Sequence[str] | None = None) -> int:
if args.command == 'autoupdate': if args.command == 'autoupdate':
return autoupdate( return autoupdate(
args.config, store, args.config,
tags_only=not args.bleeding_edge, tags_only=not args.bleeding_edge,
freeze=args.freeze, freeze=args.freeze,
repos=args.repos, repos=args.repos,

View file

@ -67,7 +67,7 @@ def test_rev_info_from_config():
def test_rev_info_update_up_to_date_repo(up_to_date): def test_rev_info_update_up_to_date_repo(up_to_date):
config = make_config_from_repo(up_to_date) config = make_config_from_repo(up_to_date)
info = RevInfo.from_config(config) info = RevInfo.from_config(config)._replace(hook_ids=frozenset(('foo',)))
new_info = info.update(tags_only=False, freeze=False) new_info = info.update(tags_only=False, freeze=False)
assert info == new_info assert info == new_info
@ -139,7 +139,7 @@ def test_rev_info_update_does_not_freeze_if_already_sha(out_of_date):
assert new_info.frozen is None assert new_info.frozen is None
def test_autoupdate_up_to_date_repo(up_to_date, tmpdir, store): def test_autoupdate_up_to_date_repo(up_to_date, tmpdir):
contents = ( contents = (
f'repos:\n' f'repos:\n'
f'- repo: {up_to_date}\n' f'- repo: {up_to_date}\n'
@ -150,11 +150,11 @@ def test_autoupdate_up_to_date_repo(up_to_date, tmpdir, store):
cfg = tmpdir.join(C.CONFIG_FILE) cfg = tmpdir.join(C.CONFIG_FILE)
cfg.write(contents) cfg.write(contents)
assert autoupdate(str(cfg), store, freeze=False, tags_only=False) == 0 assert autoupdate(str(cfg), freeze=False, tags_only=False) == 0
assert cfg.read() == contents assert cfg.read() == contents
def test_autoupdate_old_revision_broken(tempdir_factory, in_tmpdir, store): def test_autoupdate_old_revision_broken(tempdir_factory, in_tmpdir):
"""In $FUTURE_VERSION, hooks.yaml will no longer be supported. This """In $FUTURE_VERSION, hooks.yaml will no longer be supported. This
asserts that when that day comes, pre-commit will be able to autoupdate asserts that when that day comes, pre-commit will be able to autoupdate
despite not being able to read hooks.yaml in that repository. despite not being able to read hooks.yaml in that repository.
@ -174,14 +174,14 @@ def test_autoupdate_old_revision_broken(tempdir_factory, in_tmpdir, store):
write_config('.', config) write_config('.', config)
with open(C.CONFIG_FILE) as f: with open(C.CONFIG_FILE) as f:
before = f.read() before = f.read()
assert autoupdate(C.CONFIG_FILE, store, freeze=False, tags_only=False) == 0 assert autoupdate(C.CONFIG_FILE, freeze=False, tags_only=False) == 0
with open(C.CONFIG_FILE) as f: with open(C.CONFIG_FILE) as f:
after = f.read() after = f.read()
assert before != after assert before != after
assert update_rev in after assert update_rev in after
def test_autoupdate_out_of_date_repo(out_of_date, tmpdir, store): def test_autoupdate_out_of_date_repo(out_of_date, tmpdir):
fmt = ( fmt = (
'repos:\n' 'repos:\n'
'- repo: {}\n' '- repo: {}\n'
@ -192,24 +192,24 @@ def test_autoupdate_out_of_date_repo(out_of_date, tmpdir, store):
cfg = tmpdir.join(C.CONFIG_FILE) cfg = tmpdir.join(C.CONFIG_FILE)
cfg.write(fmt.format(out_of_date.path, out_of_date.original_rev)) cfg.write(fmt.format(out_of_date.path, out_of_date.original_rev))
assert autoupdate(str(cfg), store, freeze=False, tags_only=False) == 0 assert autoupdate(str(cfg), freeze=False, tags_only=False) == 0
assert cfg.read() == fmt.format(out_of_date.path, out_of_date.head_rev) assert cfg.read() == fmt.format(out_of_date.path, out_of_date.head_rev)
def test_autoupdate_with_core_useBuiltinFSMonitor(out_of_date, tmpdir, store): def test_autoupdate_with_core_useBuiltinFSMonitor(out_of_date, tmpdir):
# force the setting on "globally" for git # force the setting on "globally" for git
home = tmpdir.join('fakehome').ensure_dir() home = tmpdir.join('fakehome').ensure_dir()
home.join('.gitconfig').write('[core]\nuseBuiltinFSMonitor = true\n') home.join('.gitconfig').write('[core]\nuseBuiltinFSMonitor = true\n')
with envcontext.envcontext((('HOME', str(home)),)): with envcontext.envcontext((('HOME', str(home)),)):
test_autoupdate_out_of_date_repo(out_of_date, tmpdir, store) test_autoupdate_out_of_date_repo(out_of_date, tmpdir)
def test_autoupdate_pure_yaml(out_of_date, tmpdir, store): def test_autoupdate_pure_yaml(out_of_date, tmpdir):
with mock.patch.object(yaml, 'Dumper', yaml.yaml.SafeDumper): with mock.patch.object(yaml, 'Dumper', yaml.yaml.SafeDumper):
test_autoupdate_out_of_date_repo(out_of_date, tmpdir, store) test_autoupdate_out_of_date_repo(out_of_date, tmpdir)
def test_autoupdate_only_one_to_update(up_to_date, out_of_date, tmpdir, store): def test_autoupdate_only_one_to_update(up_to_date, out_of_date, tmpdir):
fmt = ( fmt = (
'repos:\n' 'repos:\n'
'- repo: {}\n' '- repo: {}\n'
@ -228,7 +228,7 @@ def test_autoupdate_only_one_to_update(up_to_date, out_of_date, tmpdir, store):
) )
cfg.write(before) cfg.write(before)
assert autoupdate(str(cfg), store, freeze=False, tags_only=False) == 0 assert autoupdate(str(cfg), freeze=False, tags_only=False) == 0
assert cfg.read() == fmt.format( assert cfg.read() == fmt.format(
up_to_date, git.head_rev(up_to_date), up_to_date, git.head_rev(up_to_date),
out_of_date.path, out_of_date.head_rev, out_of_date.path, out_of_date.head_rev,
@ -236,7 +236,7 @@ def test_autoupdate_only_one_to_update(up_to_date, out_of_date, tmpdir, store):
def test_autoupdate_out_of_date_repo_with_correct_repo_name( def test_autoupdate_out_of_date_repo_with_correct_repo_name(
out_of_date, in_tmpdir, store, out_of_date, in_tmpdir,
): ):
stale_config = make_config_from_repo( stale_config = make_config_from_repo(
out_of_date.path, rev=out_of_date.original_rev, check=False, out_of_date.path, rev=out_of_date.original_rev, check=False,
@ -249,7 +249,7 @@ def test_autoupdate_out_of_date_repo_with_correct_repo_name(
before = f.read() before = f.read()
repo_name = f'file://{out_of_date.path}' repo_name = f'file://{out_of_date.path}'
ret = autoupdate( ret = autoupdate(
C.CONFIG_FILE, store, freeze=False, tags_only=False, C.CONFIG_FILE, freeze=False, tags_only=False,
repos=(repo_name,), repos=(repo_name,),
) )
with open(C.CONFIG_FILE) as f: with open(C.CONFIG_FILE) as f:
@ -261,7 +261,7 @@ def test_autoupdate_out_of_date_repo_with_correct_repo_name(
def test_autoupdate_out_of_date_repo_with_wrong_repo_name( def test_autoupdate_out_of_date_repo_with_wrong_repo_name(
out_of_date, in_tmpdir, store, out_of_date, in_tmpdir,
): ):
config = make_config_from_repo( config = make_config_from_repo(
out_of_date.path, rev=out_of_date.original_rev, check=False, out_of_date.path, rev=out_of_date.original_rev, check=False,
@ -272,7 +272,7 @@ def test_autoupdate_out_of_date_repo_with_wrong_repo_name(
before = f.read() before = f.read()
# It will not update it, because the name doesn't match # It will not update it, because the name doesn't match
ret = autoupdate( ret = autoupdate(
C.CONFIG_FILE, store, freeze=False, tags_only=False, C.CONFIG_FILE, freeze=False, tags_only=False,
repos=('dne',), repos=('dne',),
) )
with open(C.CONFIG_FILE) as f: with open(C.CONFIG_FILE) as f:
@ -281,7 +281,7 @@ def test_autoupdate_out_of_date_repo_with_wrong_repo_name(
assert before == after assert before == after
def test_does_not_reformat(tmpdir, out_of_date, store): def test_does_not_reformat(tmpdir, out_of_date):
fmt = ( fmt = (
'repos:\n' 'repos:\n'
'- repo: {}\n' '- repo: {}\n'
@ -294,12 +294,12 @@ def test_does_not_reformat(tmpdir, out_of_date, store):
cfg = tmpdir.join(C.CONFIG_FILE) cfg = tmpdir.join(C.CONFIG_FILE)
cfg.write(fmt.format(out_of_date.path, out_of_date.original_rev)) cfg.write(fmt.format(out_of_date.path, out_of_date.original_rev))
assert autoupdate(str(cfg), store, freeze=False, tags_only=False) == 0 assert autoupdate(str(cfg), freeze=False, tags_only=False) == 0
expected = fmt.format(out_of_date.path, out_of_date.head_rev) expected = fmt.format(out_of_date.path, out_of_date.head_rev)
assert cfg.read() == expected assert cfg.read() == expected
def test_does_not_change_mixed_endlines_read(up_to_date, tmpdir, store): def test_does_not_change_mixed_endlines_read(up_to_date, tmpdir):
fmt = ( fmt = (
'repos:\n' 'repos:\n'
'- repo: {}\n' '- repo: {}\n'
@ -314,11 +314,11 @@ def test_does_not_change_mixed_endlines_read(up_to_date, tmpdir, store):
expected = fmt.format(up_to_date, git.head_rev(up_to_date)).encode() expected = fmt.format(up_to_date, git.head_rev(up_to_date)).encode()
cfg.write_binary(expected) cfg.write_binary(expected)
assert autoupdate(str(cfg), store, freeze=False, tags_only=False) == 0 assert autoupdate(str(cfg), freeze=False, tags_only=False) == 0
assert cfg.read_binary() == expected assert cfg.read_binary() == expected
def test_does_not_change_mixed_endlines_write(tmpdir, out_of_date, store): def test_does_not_change_mixed_endlines_write(tmpdir, out_of_date):
fmt = ( fmt = (
'repos:\n' 'repos:\n'
'- repo: {}\n' '- repo: {}\n'
@ -333,12 +333,12 @@ def test_does_not_change_mixed_endlines_write(tmpdir, out_of_date, store):
fmt.format(out_of_date.path, out_of_date.original_rev).encode(), fmt.format(out_of_date.path, out_of_date.original_rev).encode(),
) )
assert autoupdate(str(cfg), store, freeze=False, tags_only=False) == 0 assert autoupdate(str(cfg), freeze=False, tags_only=False) == 0
expected = fmt.format(out_of_date.path, out_of_date.head_rev).encode() expected = fmt.format(out_of_date.path, out_of_date.head_rev).encode()
assert cfg.read_binary() == expected assert cfg.read_binary() == expected
def test_loses_formatting_when_not_detectable(out_of_date, store, tmpdir): def test_loses_formatting_when_not_detectable(out_of_date, tmpdir):
"""A best-effort attempt is made at updating rev without rewriting """A best-effort attempt is made at updating rev without rewriting
formatting. When the original formatting cannot be detected, this formatting. When the original formatting cannot be detected, this
is abandoned. is abandoned.
@ -359,7 +359,7 @@ def test_loses_formatting_when_not_detectable(out_of_date, store, tmpdir):
cfg = tmpdir.join(C.CONFIG_FILE) cfg = tmpdir.join(C.CONFIG_FILE)
cfg.write(config) cfg.write(config)
assert autoupdate(str(cfg), store, freeze=False, tags_only=False) == 0 assert autoupdate(str(cfg), freeze=False, tags_only=False) == 0
expected = ( expected = (
f'repos:\n' f'repos:\n'
f'- repo: {out_of_date.path}\n' f'- repo: {out_of_date.path}\n'
@ -370,43 +370,43 @@ def test_loses_formatting_when_not_detectable(out_of_date, store, tmpdir):
assert cfg.read() == expected assert cfg.read() == expected
def test_autoupdate_tagged_repo(tagged, in_tmpdir, store): def test_autoupdate_tagged_repo(tagged, in_tmpdir):
config = make_config_from_repo(tagged.path, rev=tagged.original_rev) config = make_config_from_repo(tagged.path, rev=tagged.original_rev)
write_config('.', config) write_config('.', config)
assert autoupdate(C.CONFIG_FILE, store, freeze=False, tags_only=False) == 0 assert autoupdate(C.CONFIG_FILE, freeze=False, tags_only=False) == 0
with open(C.CONFIG_FILE) as f: with open(C.CONFIG_FILE) as f:
assert 'v1.2.3' in f.read() assert 'v1.2.3' in f.read()
def test_autoupdate_freeze(tagged, in_tmpdir, store): def test_autoupdate_freeze(tagged, in_tmpdir):
config = make_config_from_repo(tagged.path, rev=tagged.original_rev) config = make_config_from_repo(tagged.path, rev=tagged.original_rev)
write_config('.', config) write_config('.', config)
assert autoupdate(C.CONFIG_FILE, store, freeze=True, tags_only=False) == 0 assert autoupdate(C.CONFIG_FILE, freeze=True, tags_only=False) == 0
with open(C.CONFIG_FILE) as f: with open(C.CONFIG_FILE) as f:
expected = f'rev: {tagged.head_rev} # frozen: v1.2.3' expected = f'rev: {tagged.head_rev} # frozen: v1.2.3'
assert expected in f.read() assert expected in f.read()
# if we un-freeze it should remove the frozen comment # if we un-freeze it should remove the frozen comment
assert autoupdate(C.CONFIG_FILE, store, freeze=False, tags_only=False) == 0 assert autoupdate(C.CONFIG_FILE, freeze=False, tags_only=False) == 0
with open(C.CONFIG_FILE) as f: with open(C.CONFIG_FILE) as f:
assert 'rev: v1.2.3\n' in f.read() assert 'rev: v1.2.3\n' in f.read()
def test_autoupdate_tags_only(tagged, in_tmpdir, store): def test_autoupdate_tags_only(tagged, in_tmpdir):
# add some commits after the tag # add some commits after the tag
git_commit(cwd=tagged.path) git_commit(cwd=tagged.path)
config = make_config_from_repo(tagged.path, rev=tagged.original_rev) config = make_config_from_repo(tagged.path, rev=tagged.original_rev)
write_config('.', config) write_config('.', config)
assert autoupdate(C.CONFIG_FILE, store, freeze=False, tags_only=True) == 0 assert autoupdate(C.CONFIG_FILE, freeze=False, tags_only=True) == 0
with open(C.CONFIG_FILE) as f: with open(C.CONFIG_FILE) as f:
assert 'v1.2.3' in f.read() assert 'v1.2.3' in f.read()
def test_autoupdate_latest_no_config(out_of_date, in_tmpdir, store): def test_autoupdate_latest_no_config(out_of_date, in_tmpdir):
config = make_config_from_repo( config = make_config_from_repo(
out_of_date.path, rev=out_of_date.original_rev, out_of_date.path, rev=out_of_date.original_rev,
) )
@ -415,12 +415,12 @@ def test_autoupdate_latest_no_config(out_of_date, in_tmpdir, store):
cmd_output('git', 'rm', '-r', ':/', cwd=out_of_date.path) cmd_output('git', 'rm', '-r', ':/', cwd=out_of_date.path)
git_commit(cwd=out_of_date.path) git_commit(cwd=out_of_date.path)
assert autoupdate(C.CONFIG_FILE, store, freeze=False, tags_only=False) == 1 assert autoupdate(C.CONFIG_FILE, freeze=False, tags_only=False) == 1
with open(C.CONFIG_FILE) as f: with open(C.CONFIG_FILE) as f:
assert out_of_date.original_rev in f.read() assert out_of_date.original_rev in f.read()
def test_hook_disppearing_repo_raises(hook_disappearing, store): def test_hook_disppearing_repo_raises(hook_disappearing):
config = make_config_from_repo( config = make_config_from_repo(
hook_disappearing.path, hook_disappearing.path,
rev=hook_disappearing.original_rev, rev=hook_disappearing.original_rev,
@ -428,10 +428,10 @@ def test_hook_disppearing_repo_raises(hook_disappearing, store):
) )
info = RevInfo.from_config(config).update(tags_only=False, freeze=False) info = RevInfo.from_config(config).update(tags_only=False, freeze=False)
with pytest.raises(RepositoryCannotBeUpdatedError): with pytest.raises(RepositoryCannotBeUpdatedError):
_check_hooks_still_exist_at_rev(config, info, store) _check_hooks_still_exist_at_rev(config, info)
def test_autoupdate_hook_disappearing_repo(hook_disappearing, tmpdir, store): def test_autoupdate_hook_disappearing_repo(hook_disappearing, tmpdir):
contents = ( contents = (
f'repos:\n' f'repos:\n'
f'- repo: {hook_disappearing.path}\n' f'- repo: {hook_disappearing.path}\n'
@ -442,21 +442,21 @@ def test_autoupdate_hook_disappearing_repo(hook_disappearing, tmpdir, store):
cfg = tmpdir.join(C.CONFIG_FILE) cfg = tmpdir.join(C.CONFIG_FILE)
cfg.write(contents) cfg.write(contents)
assert autoupdate(str(cfg), store, freeze=False, tags_only=False) == 1 assert autoupdate(str(cfg), freeze=False, tags_only=False) == 1
assert cfg.read() == contents assert cfg.read() == contents
def test_autoupdate_local_hooks(in_git_dir, store): def test_autoupdate_local_hooks(in_git_dir):
config = sample_local_config() config = sample_local_config()
add_config_to_repo('.', config) add_config_to_repo('.', config)
assert autoupdate(C.CONFIG_FILE, store, freeze=False, tags_only=False) == 0 assert autoupdate(C.CONFIG_FILE, freeze=False, tags_only=False) == 0
new_config_written = read_config('.') new_config_written = read_config('.')
assert len(new_config_written['repos']) == 1 assert len(new_config_written['repos']) == 1
assert new_config_written['repos'][0] == config assert new_config_written['repos'][0] == config
def test_autoupdate_local_hooks_with_out_of_date_repo( def test_autoupdate_local_hooks_with_out_of_date_repo(
out_of_date, in_tmpdir, store, out_of_date, in_tmpdir,
): ):
stale_config = make_config_from_repo( stale_config = make_config_from_repo(
out_of_date.path, rev=out_of_date.original_rev, check=False, out_of_date.path, rev=out_of_date.original_rev, check=False,
@ -464,13 +464,13 @@ def test_autoupdate_local_hooks_with_out_of_date_repo(
local_config = sample_local_config() local_config = sample_local_config()
config = {'repos': [local_config, stale_config]} config = {'repos': [local_config, stale_config]}
write_config('.', config) write_config('.', config)
assert autoupdate(C.CONFIG_FILE, store, freeze=False, tags_only=False) == 0 assert autoupdate(C.CONFIG_FILE, freeze=False, tags_only=False) == 0
new_config_written = read_config('.') new_config_written = read_config('.')
assert len(new_config_written['repos']) == 2 assert len(new_config_written['repos']) == 2
assert new_config_written['repos'][0] == local_config assert new_config_written['repos'][0] == local_config
def test_autoupdate_meta_hooks(tmpdir, store): def test_autoupdate_meta_hooks(tmpdir):
cfg = tmpdir.join(C.CONFIG_FILE) cfg = tmpdir.join(C.CONFIG_FILE)
cfg.write( cfg.write(
'repos:\n' 'repos:\n'
@ -478,7 +478,7 @@ def test_autoupdate_meta_hooks(tmpdir, store):
' hooks:\n' ' hooks:\n'
' - id: check-useless-excludes\n', ' - id: check-useless-excludes\n',
) )
assert autoupdate(str(cfg), store, freeze=False, tags_only=True) == 0 assert autoupdate(str(cfg), freeze=False, tags_only=True) == 0
assert cfg.read() == ( assert cfg.read() == (
'repos:\n' 'repos:\n'
'- repo: meta\n' '- repo: meta\n'
@ -487,7 +487,7 @@ def test_autoupdate_meta_hooks(tmpdir, store):
) )
def test_updates_old_format_to_new_format(tmpdir, capsys, store): def test_updates_old_format_to_new_format(tmpdir, capsys):
cfg = tmpdir.join(C.CONFIG_FILE) cfg = tmpdir.join(C.CONFIG_FILE)
cfg.write( cfg.write(
'- repo: local\n' '- repo: local\n'
@ -497,7 +497,7 @@ def test_updates_old_format_to_new_format(tmpdir, capsys, store):
' entry: ./bin/foo.sh\n' ' entry: ./bin/foo.sh\n'
' language: script\n', ' language: script\n',
) )
assert autoupdate(str(cfg), store, freeze=False, tags_only=True) == 0 assert autoupdate(str(cfg), freeze=False, tags_only=True) == 0
contents = cfg.read() contents = cfg.read()
assert contents == ( assert contents == (
'repos:\n' 'repos:\n'
@ -512,7 +512,7 @@ def test_updates_old_format_to_new_format(tmpdir, capsys, store):
assert out == 'Configuration has been migrated.\n' assert out == 'Configuration has been migrated.\n'
def test_maintains_rev_quoting_style(tmpdir, out_of_date, store): def test_maintains_rev_quoting_style(tmpdir, out_of_date):
fmt = ( fmt = (
'repos:\n' 'repos:\n'
'- repo: {path}\n' '- repo: {path}\n'
@ -527,6 +527,6 @@ def test_maintains_rev_quoting_style(tmpdir, out_of_date, store):
cfg = tmpdir.join(C.CONFIG_FILE) cfg = tmpdir.join(C.CONFIG_FILE)
cfg.write(fmt.format(path=out_of_date.path, rev=out_of_date.original_rev)) cfg.write(fmt.format(path=out_of_date.path, rev=out_of_date.original_rev))
assert autoupdate(str(cfg), store, freeze=False, tags_only=False) == 0 assert autoupdate(str(cfg), freeze=False, tags_only=False) == 0
expected = fmt.format(path=out_of_date.path, rev=out_of_date.head_rev) expected = fmt.format(path=out_of_date.path, rev=out_of_date.head_rev)
assert cfg.read() == expected assert cfg.read() == expected

View file

@ -43,8 +43,9 @@ def test_gc(tempdir_factory, store, in_git_dir, cap_out):
store.mark_config_used(C.CONFIG_FILE) store.mark_config_used(C.CONFIG_FILE)
# update will clone both the old and new repo, making the old one gc-able # update will clone both the old and new repo, making the old one gc-able
install_hooks(C.CONFIG_FILE, store) assert not install_hooks(C.CONFIG_FILE, store)
assert not autoupdate(C.CONFIG_FILE, store, freeze=False, tags_only=False) assert not autoupdate(C.CONFIG_FILE, freeze=False, tags_only=False)
assert not install_hooks(C.CONFIG_FILE, store)
assert _config_count(store) == 1 assert _config_count(store) == 1
assert _repo_count(store) == 2 assert _repo_count(store) == 2