Skip to content

Commit 12cba70

Browse files
committed
tool: Add spec summary command with markdown output
1 parent 6dd623a commit 12cba70

File tree

2 files changed

+95
-0
lines changed

2 files changed

+95
-0
lines changed

spec.py

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,31 @@
2727
from bin.loader import load_content, load_needs
2828

2929

30+
def get_spec_summary_counts():
31+
spec = load_content()
32+
keys = [
33+
("applications", "application"),
34+
("modules", "module"),
35+
("fields", "field"),
36+
("components", "component"),
37+
("codelists", "codelist"),
38+
("datasets", "dataset"),
39+
("specifications", "specification"),
40+
]
41+
return [(label, len(spec.get(table_name, {}) or {})) for label, table_name in keys]
42+
43+
44+
def format_spec_summary(markdown=False):
45+
counts = get_spec_summary_counts()
46+
47+
if markdown:
48+
lines = ["# Specification summary", ""]
49+
lines.extend(f"- **{label.capitalize()}**: {count}" for label, count in counts)
50+
return "\n".join(lines)
51+
52+
return "\n".join(f"{label}: {count}" for label, count in counts)
53+
54+
3055
def print_2025_form_urls(application_type):
3156
forms_path = PROJECT_ROOT / FORMS_2025_FILEPATH
3257
rows = read_csv(str(forms_path), as_dict=True)
@@ -253,6 +278,13 @@ def decision():
253278
pass
254279

255280

281+
@cli.command(name="summary")
282+
@click.option("--markdown", is_flag=True, help="Print the summary in markdown format")
283+
def spec_summary(markdown):
284+
"""Print a summary of loaded specification record counts."""
285+
click.echo(format_spec_summary(markdown=markdown))
286+
287+
256288
@decision.command()
257289
@click.option("--list", "do_list", is_flag=True, help="List covered need ids")
258290
def summary(do_list):

tests/test_spec_cli.py

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,69 @@
33
import spec
44

55

6+
def test_summary_command_prints_loaded_record_counts(monkeypatch):
7+
runner = CliRunner()
8+
9+
monkeypatch.setattr(
10+
spec,
11+
"load_content",
12+
lambda: {
13+
"application": {"a": {}, "b": {}},
14+
"module": {"m1": {}, "m2": {}, "m3": {}},
15+
"field": {"f1": {}},
16+
"component": {"c1": {}, "c2": {}},
17+
"codelist": {"cl1": {}},
18+
"dataset": {"d1": {}, "d2": {}, "d3": {}, "d4": {}},
19+
"specification": {"s1": {}},
20+
},
21+
)
22+
23+
result = runner.invoke(spec.cli, ["summary"])
24+
25+
assert result.exit_code == 0
26+
assert result.output == (
27+
"applications: 2\n"
28+
"modules: 3\n"
29+
"fields: 1\n"
30+
"components: 2\n"
31+
"codelists: 1\n"
32+
"datasets: 4\n"
33+
"specifications: 1\n"
34+
)
35+
36+
37+
def test_summary_command_supports_markdown_output(monkeypatch):
38+
runner = CliRunner()
39+
40+
monkeypatch.setattr(
41+
spec,
42+
"load_content",
43+
lambda: {
44+
"application": {"a": {}},
45+
"module": {"m1": {}},
46+
"field": {"f1": {}, "f2": {}},
47+
"component": {},
48+
"codelist": {"cl1": {}, "cl2": {}},
49+
"dataset": {"d1": {}},
50+
"specification": {"s1": {}, "s2": {}},
51+
},
52+
)
53+
54+
result = runner.invoke(spec.cli, ["summary", "--markdown"])
55+
56+
assert result.exit_code == 0
57+
assert result.output == (
58+
"# Specification summary\n\n"
59+
"- **Applications**: 1\n"
60+
"- **Modules**: 1\n"
61+
"- **Fields**: 2\n"
62+
"- **Components**: 0\n"
63+
"- **Codelists**: 2\n"
64+
"- **Datasets**: 1\n"
65+
"- **Specifications**: 2\n"
66+
)
67+
68+
669
def test_forms_command_lists_matching_2025_forms(monkeypatch):
770
runner = CliRunner()
871

0 commit comments

Comments
 (0)