Skip to content

Commit 9bea890

Browse files
committed
support cache clear
1 parent 70db6d0 commit 9bea890

4 files changed

Lines changed: 142 additions & 2 deletions

File tree

autotest/test_models.py

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -494,6 +494,35 @@ def test_cli_list_with_cache(self, capsys):
494494
assert f"{TEST_SOURCE_NAME}@{TEST_REF}" in captured.out
495495
assert "Models:" in captured.out
496496

497+
def test_cli_clear(self, capsys):
498+
"""Test 'clear' command."""
499+
# Sync a registry first
500+
_DEFAULT_CACHE.clear(source=TEST_SOURCE_NAME, ref=TEST_REF)
501+
source = ModelSourceRepo(
502+
repo=TEST_REPO,
503+
name=TEST_SOURCE_NAME,
504+
refs=[TEST_REF],
505+
)
506+
result = source.sync(ref=TEST_REF)
507+
assert len(result.synced) == 1
508+
509+
# Verify it's cached
510+
assert _DEFAULT_CACHE.has(TEST_SOURCE_NAME, TEST_REF)
511+
512+
# Clear with force flag
513+
import argparse
514+
515+
from modflow_devtools.models.__main__ import cmd_clear
516+
517+
args = argparse.Namespace(source=TEST_SOURCE_NAME, ref=TEST_REF, force=True)
518+
cmd_clear(args)
519+
520+
# Verify it was cleared
521+
assert not _DEFAULT_CACHE.has(TEST_SOURCE_NAME, TEST_REF)
522+
523+
captured = capsys.readouterr()
524+
assert "Cleared 1 cached registry" in captured.out
525+
497526

498527
@pytest.mark.xdist_group("registry_cache")
499528
class TestIntegration:

docs/md/dev/models.md

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -707,6 +707,22 @@ $ mf models list --ref registry
707707
$ mf models list --source mf6/test --ref registry --verbose
708708
```
709709

710+
#### Clear Cached Registries
711+
712+
```bash
713+
# Clear all cached registries (with confirmation)
714+
$ mf models clear
715+
716+
# Clear specific source
717+
$ mf models clear --source mf6/test
718+
719+
# Clear specific source and ref
720+
$ mf models clear --source mf6/test --ref develop
721+
722+
# Skip confirmation prompt
723+
$ mf models clear --force
724+
```
725+
710726
### Registry Creation Tool
711727

712728
The `make_registry` tool uses a mode-based interface with **remote-first operation** by default:

docs/md/models.md

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -266,8 +266,29 @@ for source, ref in cached:
266266
# Check specific cache
267267
is_cached = _DEFAULT_CACHE.has("mf6/test", "develop")
268268

269-
# Clear cache (if needed)
270-
_DEFAULT_CACHE.clear()
269+
# Clear cache programmatically
270+
_DEFAULT_CACHE.clear() # Clear all
271+
_DEFAULT_CACHE.clear(source="mf6/test") # Clear specific source
272+
_DEFAULT_CACHE.clear(source="mf6/test", ref="develop") # Clear specific source@ref
273+
```
274+
275+
Or via CLI:
276+
277+
```bash
278+
# List cached registries
279+
mf models list
280+
281+
# Clear all cached registries (with confirmation prompt)
282+
mf models clear
283+
284+
# Clear specific source
285+
mf models clear --source mf6/test
286+
287+
# Clear specific source and ref
288+
mf models clear --source mf6/test --ref develop
289+
290+
# Skip confirmation prompt
291+
mf models clear --force
271292
```
272293

273294
## Automatic Synchronization

modflow_devtools/models/__main__.py

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
python -m modflow_devtools.models sync
66
python -m modflow_devtools.models info
77
python -m modflow_devtools.models list
8+
python -m modflow_devtools.models clear
89
"""
910

1011
import argparse
@@ -227,6 +228,58 @@ def cmd_list(args):
227228
print()
228229

229230

231+
def cmd_clear(args):
232+
"""Clear command handler."""
233+
cached = _DEFAULT_CACHE.list()
234+
235+
# Determine what will be cleared
236+
if args.source and args.ref:
237+
items_to_clear = [(args.source, args.ref)]
238+
desc = f"{args.source}@{args.ref}"
239+
elif args.source:
240+
items_to_clear = [(source, ref) for source, ref in cached if source == args.source]
241+
desc = f"all refs for source '{args.source}'"
242+
else:
243+
items_to_clear = cached
244+
desc = "all cached registries"
245+
246+
if not items_to_clear:
247+
if args.source or args.ref:
248+
filter_desc = []
249+
if args.source:
250+
filter_desc.append(f"source={args.source}")
251+
if args.ref:
252+
filter_desc.append(f"ref={args.ref}")
253+
print(f"No cached registries matching filters: {', '.join(filter_desc)}")
254+
else:
255+
print("No cached registries to clear")
256+
return
257+
258+
# Show what will be cleared
259+
print(f"Will clear {desc}:")
260+
for source, ref in sorted(items_to_clear):
261+
print(f" {source}@{ref}")
262+
263+
# Confirm unless --force
264+
if not args.force:
265+
try:
266+
response = input("\nProceed? [y/N] ").strip().lower()
267+
if response not in ["y", "yes"]:
268+
print("Cancelled")
269+
return
270+
except (KeyboardInterrupt, EOFError):
271+
print("\nCancelled")
272+
return
273+
274+
# Clear the cache
275+
_DEFAULT_CACHE.clear(source=args.source, ref=args.ref)
276+
277+
print(
278+
f"\nCleared {len(items_to_clear)} cached registr"
279+
f"{'y' if len(items_to_clear) == 1 else 'ies'}"
280+
)
281+
282+
230283
def main():
231284
"""Main CLI entry point."""
232285
parser = argparse.ArgumentParser(
@@ -280,6 +333,25 @@ def main():
280333
help="Show all model names (not truncated)",
281334
)
282335

336+
# Clear command
337+
clear_parser = subparsers.add_parser("clear", help="Clear cached registries")
338+
clear_parser.add_argument(
339+
"--source",
340+
"-s",
341+
help="Clear specific source (default: all sources)",
342+
)
343+
clear_parser.add_argument(
344+
"--ref",
345+
"-r",
346+
help="Clear specific ref (requires --source)",
347+
)
348+
clear_parser.add_argument(
349+
"--force",
350+
"-f",
351+
action="store_true",
352+
help="Skip confirmation prompt",
353+
)
354+
283355
args = parser.parse_args()
284356

285357
if not args.command:
@@ -293,6 +365,8 @@ def main():
293365
cmd_info(args)
294366
elif args.command == "list":
295367
cmd_list(args)
368+
elif args.command == "clear":
369+
cmd_clear(args)
296370
except Exception as e:
297371
print(f"Error: {e}", file=sys.stderr)
298372
sys.exit(1)

0 commit comments

Comments
 (0)