move logic for gc back to commands.gc · MichaelRWolf/pre-commit@66278a9 · GitHub
Skip to content

Commit 66278a9

Browse files
author
Anthony Sottile
committed
move logic for gc back to commands.gc
1 parent 1b32c50 commit 66278a9

4 files changed

Lines changed: 100 additions & 92 deletions

File tree

pre_commit/commands/gc.py

Lines changed: 90 additions & 1 deletion

pre_commit/store.py

Lines changed: 0 additions & 80 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@
88
from collections.abc import Callable
99
from collections.abc import Generator
1010
from collections.abc import Sequence
11-
from typing import Any
1211

1312
import pre_commit.constants as C
1413
from pre_commit import clientlib
@@ -18,7 +17,6 @@
1817
from pre_commit.util import clean_path_on_failure
1918
from pre_commit.util import cmd_output_b
2019
from pre_commit.util import resource_text
21-
from pre_commit.util import rmtree
2220

2321

2422
logger = logging.getLogger('pre_commit')
@@ -235,81 +233,3 @@ def mark_config_used(self, path: str) -> None:
235233
# TODO: eventually remove this and only create in _create
236234
self._create_configs_table(db)
237235
db.execute('INSERT OR IGNORE INTO configs VALUES (?)', (path,))
238-
239-
def _mark_used_repos(
240-
self,
241-
all_repos: dict[tuple[str, str], str],
242-
unused_repos: set[tuple[str, str]],
243-
repo: dict[str, Any],
244-
) -> None:
245-
if repo['repo'] == clientlib.META:
246-
return
247-
elif repo['repo'] == clientlib.LOCAL:
248-
for hook in repo['hooks']:
249-
deps = hook.get('additional_dependencies')
250-
unused_repos.discard((
251-
self.db_repo_name(repo['repo'], deps),
252-
C.LOCAL_REPO_VERSION,
253-
))
254-
else:
255-
key = (repo['repo'], repo['rev'])
256-
path = all_repos.get(key)
257-
# can't inspect manifest if it isn't cloned
258-
if path is None:
259-
return
260-
261-
try:
262-
manifest = clientlib.load_manifest(
263-
os.path.join(path, C.MANIFEST_FILE),
264-
)
265-
except clientlib.InvalidManifestError:
266-
return
267-
else:
268-
unused_repos.discard(key)
269-
by_id = {hook['id']: hook for hook in manifest}
270-
271-
for hook in repo['hooks']:
272-
if hook['id'] not in by_id:
273-
continue
274-
275-
deps = hook.get(
276-
'additional_dependencies',
277-
by_id[hook['id']]['additional_dependencies'],
278-
)
279-
unused_repos.discard((
280-
self.db_repo_name(repo['repo'], deps), repo['rev'],
281-
))
282-
283-
def gc(self) -> int:
284-
with self.exclusive_lock(), self.connect() as db:
285-
self._create_configs_table(db)
286-
287-
repos = db.execute('SELECT repo, ref, path FROM repos').fetchall()
288-
all_repos = {(repo, ref): path for repo, ref, path in repos}
289-
unused_repos = set(all_repos)
290-
291-
configs_rows = db.execute('SELECT path FROM configs').fetchall()
292-
configs = [path for path, in configs_rows]
293-
294-
dead_configs = []
295-
for config_path in configs:
296-
try:
297-
config = clientlib.load_config(config_path)
298-
except clientlib.InvalidConfigError:
299-
dead_configs.append(config_path)
300-
continue
301-
else:
302-
for repo in config['repos']:
303-
self._mark_used_repos(all_repos, unused_repos, repo)
304-
305-
paths = [(path,) for path in dead_configs]
306-
db.executemany('DELETE FROM configs WHERE path = ?', paths)
307-
308-
db.executemany(
309-
'DELETE FROM repos WHERE repo = ? and ref = ?',
310-
sorted(unused_repos),
311-
)
312-
for k in unused_repos:
313-
rmtree(all_repos[k])
314-
315-
return len(unused_repos)

tests/commands/gc_test.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -165,3 +165,11 @@ def test_invalid_manifest_gcd(tempdir_factory, store, in_git_dir, cap_out):
165165
assert _config_count(store) == 1
166166
assert _repo_count(store) == 0
167167
assert cap_out.get().splitlines()[-1] == '1 repo(s) removed.'
168+
169+
170+
def test_gc_pre_1_14_roll_forward(store, cap_out):
171+
with store.connect() as db: # simulate pre-1.14.0
172+
db.executescript('DROP TABLE configs')
173+
174+
assert not gc(store)
175+
assert cap_out.get() == '0 repo(s) removed.\n'

tests/store_test.py

Lines changed: 2 additions & 11 deletions

0 commit comments

Comments
 (0)