Skip to content
This repository was archived by the owner on Jan 29, 2026. It is now read-only.

Commit cab6915

Browse files
committed
build: meson doctest autoglob
1 parent 842d903 commit cab6915

File tree

5 files changed

+82
-54
lines changed

5 files changed

+82
-54
lines changed

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,9 @@
22
build/
33
Testing/
44

5+
# Python bytecode cache
6+
__pycache__/
7+
58
# Meson subprojects
69
/subprojects/*
710
!/subprojects/*.wrap

docs/meson.build

Lines changed: 29 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -7,27 +7,38 @@ maybe_fmt_dep = dependency(
77
disabler: true,
88
)
99

10-
# glob **.md
10+
autogen_glob = custom_target(
11+
command: [autogen_doctest_exe, meson.current_source_dir()],
12+
output: 'autogen.stamp',
13+
build_by_default: true,
14+
)
15+
16+
#pragma autogen push
1117
docs = [
12-
'README.md',
13-
'faq.md',
14-
'modules_support.md',
1518
'spec/PRO_DEF_FREE_AS_MEM_DISPATCH.md',
1619
'spec/PRO_DEF_FREE_DISPATCH.md',
1720
'spec/PRO_DEF_MEM_DISPATCH.md',
18-
'spec/ProAccessible.md',
19-
'spec/ProBasicConvention.md',
20-
'spec/ProBasicFacade.md',
21-
'spec/ProBasicReflection.md',
22-
'spec/ProConvention.md',
23-
'spec/ProDispatch.md',
24-
'spec/ProFacade.md',
25-
'spec/ProOverload.md',
26-
'spec/ProReflection.md',
27-
'spec/README.md',
2821
'spec/allocate_proxy.md',
2922
'spec/allocate_proxy_shared.md',
30-
'spec/bad_proxy_cast.md',
23+
'spec/facade_aware_overload_t.md',
24+
'spec/inplace_proxiable_target.md',
25+
'spec/is_bitwise_trivially_relocatable.md',
26+
'spec/make_proxy.md',
27+
'spec/make_proxy_inplace.md',
28+
'spec/make_proxy_shared.md',
29+
'spec/make_proxy_view.md',
30+
'spec/msft_lib_proxy.md',
31+
'spec/proxiable.md',
32+
'spec/proxiable_target.md',
33+
'spec/proxy_invoke.md',
34+
'spec/proxy_reflect.md',
35+
'spec/proxy_view.md',
36+
'spec/skills_as_view.md',
37+
'spec/skills_as_weak.md',
38+
'spec/skills_fmt_format.md',
39+
'spec/skills_format.md',
40+
'spec/skills_slim.md',
41+
'spec/weak_proxy.md',
3142
'spec/basic_facade_builder/README.md',
3243
'spec/basic_facade_builder/add_convention.md',
3344
'spec/basic_facade_builder/add_facade.md',
@@ -38,30 +49,10 @@ docs = [
3849
'spec/basic_facade_builder/support_copy.md',
3950
'spec/basic_facade_builder/support_destruction.md',
4051
'spec/basic_facade_builder/support_relocation.md',
41-
'spec/constraint_level.md',
4252
'spec/explicit_conversion_dispatch/README.md',
43-
'spec/explicit_conversion_dispatch/accessor.md',
44-
'spec/explicit_conversion_dispatch/operator_call.md',
45-
'spec/facade.md',
46-
'spec/facade_aware_overload_t.md',
4753
'spec/implicit_conversion_dispatch/README.md',
48-
'spec/implicit_conversion_dispatch/accessor.md',
49-
'spec/implicit_conversion_dispatch/operator_call.md',
50-
'spec/inplace_proxiable_target.md',
51-
'spec/is_bitwise_trivially_relocatable.md',
52-
'spec/make_proxy.md',
53-
'spec/make_proxy_inplace.md',
54-
'spec/make_proxy_shared.md',
55-
'spec/make_proxy_view.md',
56-
'spec/msft_lib_proxy.md',
57-
'spec/not_implemented.md',
5854
'spec/operator_dispatch/README.md',
59-
'spec/operator_dispatch/accessor.md',
60-
'spec/operator_dispatch/operator_call.md',
61-
'spec/proxiable.md',
62-
'spec/proxiable_target.md',
6355
'spec/proxy/README.md',
64-
'spec/proxy/assignment.md',
6556
'spec/proxy/constructor.md',
6657
'spec/proxy/destructor.md',
6758
'spec/proxy/emplace.md',
@@ -70,26 +61,13 @@ docs = [
7061
'spec/proxy/indirection.md',
7162
'spec/proxy/operator_bool.md',
7263
'spec/proxy/reset.md',
73-
'spec/proxy/swap.md',
74-
'spec/proxy_indirect_accessor.md',
75-
'spec/proxy_invoke.md',
76-
'spec/proxy_reflect.md',
77-
'spec/proxy_view.md',
78-
'spec/skills_as_view.md',
79-
'spec/skills_as_weak.md',
80-
'spec/skills_fmt_format.md',
81-
'spec/skills_format.md',
8264
'spec/skills_rtti/README.md',
8365
'spec/skills_rtti/proxy_cast.md',
8466
'spec/skills_rtti/proxy_typeid.md',
85-
'spec/skills_slim.md',
8667
'spec/substitution_dispatch/README.md',
87-
'spec/substitution_dispatch/accessor.md',
88-
'spec/substitution_dispatch/operator_call.md',
8968
'spec/weak_dispatch/README.md',
90-
'spec/weak_dispatch/operator_call.md',
91-
'spec/weak_proxy.md',
9269
]
70+
#pragma autogen pop
9371

9472
docdir = get_option('docdir')
9573
if docdir == ''
@@ -160,6 +138,7 @@ foreach doc : docs
160138
input: 'example.cpp.in',
161139
output: f'example_@name@.cpp',
162140
),
141+
extra_files: doc,
163142
implicit_include_directories: false,
164143
dependencies: deps,
165144
build_by_default: false,
@@ -169,6 +148,7 @@ foreach doc : docs
169148
name,
170149
example_exe,
171150
suite: 'ProxyExamples',
151+
depends: autogen_glob,
172152
)
173153
endif
174154
endforeach

tools/extract_example_code_from_docs.py

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,13 @@
22
# pyright: strict
33

44
import re
5+
import typing as T
56
from pathlib import Path
67

78
EXAMPLE_PATTERN = re.compile(r"## Example\r?\n\r?\n```cpp\r?\n(.*?)\r?\n```", re.DOTALL)
89

910

10-
def extract_cpp_code(md_path: Path, cpp_path: Path) -> None:
11+
def extract_cpp_code(md_path: Path) -> T.Optional[str]:
1112
with open(md_path, "r", encoding="utf-8") as f:
1213
content = f.read()
1314

@@ -26,9 +27,7 @@ def extract_cpp_code(md_path: Path, cpp_path: Path) -> None:
2627
2728
""".lstrip()
2829

29-
with open(cpp_path, "w", encoding="utf-8") as out:
30-
_ = out.write(header)
31-
_ = out.write(cpp_code)
30+
return header + cpp_code
3231

3332

3433
def main() -> None:
@@ -56,7 +55,11 @@ class Args:
5655
rel_path = md_path.relative_to(input_dir)
5756
rel_base = "_".join([*rel_path.parent.parts, rel_path.stem])
5857
cpp_path = output_dir / f"example_{rel_base}.cpp"
59-
extract_cpp_code(md_path, cpp_path)
58+
cpp_code = extract_cpp_code(md_path)
59+
if cpp_code is None:
60+
continue
61+
with open(cpp_path, "w", encoding="utf-8") as f:
62+
_ = f.write(cpp_code)
6063

6164

6265
if __name__ == "__main__":

tools/meson.build

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,2 @@
11
autogen_tests_exe = find_program('./meson_autogen_tests.py')
2+
autogen_doctest_exe = find_program('./meson_autogen_doctest.py')

tools/meson_autogen_doctest.py

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
#!/usr/bin/env python3
2+
# pyright: strict
3+
4+
import sys
5+
from pathlib import Path
6+
7+
from mesonbuild import mformat
8+
9+
from extract_example_code_from_docs import extract_cpp_code
10+
11+
directory = Path(sys.argv[1])
12+
mesonfile = directory / "meson.build"
13+
14+
with mesonfile.open(encoding="utf-8") as f:
15+
build = f.readlines()
16+
17+
begin = -1
18+
end = -1
19+
20+
for i, line in enumerate(build):
21+
if begin == -1 and line.strip() == "#pragma autogen push":
22+
begin = i + 1
23+
elif end == -1 and line.strip() == "#pragma autogen pop":
24+
end = i
25+
26+
if begin == -1 or end == -1:
27+
raise ValueError
28+
29+
docs = [str(path.relative_to(directory)) for path in directory.glob("**/*.md") if extract_cpp_code(path) is not None]
30+
31+
config = mformat.get_meson_format([mesonfile])
32+
formatter = mformat.Formatter(config, False, False)
33+
pretty = formatter.format(f"{docs = }", mesonfile)
34+
35+
if pretty == "".join(build[begin:end]):
36+
exit()
37+
38+
with mesonfile.open("w", encoding="utf-8") as f:
39+
f.writelines(build[:begin])
40+
_ = f.write(pretty)
41+
f.writelines(build[end:])

0 commit comments

Comments
 (0)