Coverage for little_loops / package_data.py: 0%

15 statements  

« prev     ^ index     » next       coverage.py v7.12.0, created at 2026-06-26 17:38 -0500

1"""Package data registry — declarative manifest of runtime-read assets. 

2 

3Every file the little_loops package reads at runtime must appear in 

4PACKAGE_DATA_ASSETS. The completeness check (test_package_data_manifest.py) 

5asserts each entry is accessible via importlib.resources.files("little_loops"), 

6so adding a new asset read without registering it here will not be caught — 

7but registering it and omitting it from the package source will fail the test. 

8 

9Usage in the completeness check:: 

10 

11 from little_loops.package_data import PACKAGE_DATA_ASSETS, list_missing_assets 

12 

13 missing = list_missing_assets() 

14 assert not missing, f"Assets not accessible: {missing}" 

15""" 

16 

17from __future__ import annotations 

18 

19import importlib.resources 

20from typing import Final 

21 

22_PACKAGE: Final[str] = "little_loops" 

23 

24# Declarative manifest: each entry is a tuple of path parts relative to 

25# the little_loops package root. Add an entry here whenever new package 

26# data is referenced at runtime. Omitting an entry gives a false-green 

27# completeness result — the check won't catch a missing asset it doesn't know about. 

28PACKAGE_DATA_ASSETS: Final[tuple[tuple[str, ...], ...]] = ( 

29 ("assets", "ll-cli-logo.txt"), 

30 ("hooks", "prompts", "optimize-prompt-hook.md"), 

31 ("hooks", "adapters", "codex", "hooks.json"), 

32 ("templates", "bug-sections.json"), 

33 ("templates", "enh-sections.json"), 

34 ("templates", "feat-sections.json"), 

35 ("templates", "epic-sections.json"), 

36 ("templates", "ll-goals-template.md"), 

37 ("templates", "generic.json"), 

38 ("templates", "python-generic.json"), 

39 ("templates", "javascript.json"), 

40 ("templates", "typescript.json"), 

41 ("templates", "rust.json"), 

42 ("templates", "go.json"), 

43 ("templates", "java-maven.json"), 

44 ("templates", "java-gradle.json"), 

45 ("templates", "dotnet.json"), 

46) 

47 

48 

49def check_asset_accessible(parts: tuple[str, ...]) -> bool: 

50 """Return True if the asset is reachable via importlib.resources.""" 

51 try: 

52 traversable = importlib.resources.files(_PACKAGE) 

53 for part in parts: 

54 traversable = traversable.joinpath(part) 

55 return traversable.is_file() # type: ignore[return-value] 

56 except Exception: 

57 return False 

58 

59 

60def list_missing_assets() -> list[tuple[str, ...]]: 

61 """Return registered assets not accessible in the current installation.""" 

62 return [parts for parts in PACKAGE_DATA_ASSETS if not check_asset_accessible(parts)]