13
13
import argparse
14
14
import json
15
15
import re
16
- from contextlib import suppress
17
16
from pathlib import Path
18
17
from typing import Dict , Iterator , Tuple
19
18
20
19
21
20
def parse (s : str ) -> Iterator [Tuple [str , str ]]:
22
21
"""Parse an AWS docs page in Markdown format, yielding each property."""
23
22
# Prevent from parsing return values accidentally
24
- with suppress (ValueError ):
25
- s = s [: s .index ("# Return Value" )]
26
- with suppress (ValueError ):
27
- s = s [: s .index ("# Return value" )]
23
+ s = stringbetween (s , "#\s+Properties" , "#\s+Return values" )
24
+ if not s :
25
+ return
28
26
parts = s .split ("\n \n " )
29
27
for part in parts :
30
28
match = re .match (r"^\s*`(\w+)`\s+<a" , part )
@@ -59,7 +57,18 @@ def convert_to_full_path(description: str, prefix: str) -> str:
59
57
60
58
61
59
def stringbetween (s : str , sep1 : str , sep2 : str ) -> str :
62
- return s .split (sep1 , 1 )[1 ].split (sep2 , 1 )[0 ]
60
+ """
61
+ Return string between regexes. Case-insensitive. If sep2 doesn't match,
62
+ returns to end of string.
63
+ """
64
+ start = re .search (sep1 , s , re .IGNORECASE )
65
+ if not start :
66
+ return ""
67
+ s = s [start .end () :]
68
+ end = re .search (sep2 , s , re .IGNORECASE )
69
+ if not end :
70
+ return s
71
+ return s [: end .start ()]
63
72
64
73
65
74
def main () -> None :
@@ -71,7 +80,14 @@ def main() -> None:
71
80
props : Dict [str , Dict [str , str ]] = {}
72
81
for path in args .dir .glob ("*.md" ):
73
82
text = path .read_text ()
74
- title = stringbetween (text , "# " , "<a" )
83
+ title = stringbetween (text , r"#\s+" , r"<a" )
84
+ if not title :
85
+ raise Exception (f"{ path } has no title" )
86
+ # In CFN docs, always expect either `AWS::Foo::Bar`, or `AWS::Foo::Bar SomeProperty`,
87
+ # which maps to the definition names in GoFormation schema
88
+ # Tangentially related: https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/cfn-resource-specification-format.html
89
+ if args .cfn and not re .match (r"^\w+::\w+::\w+( \w+)?$" , title ):
90
+ continue
75
91
page = title if args .cfn else path .stem
76
92
for name , description in parse (text ):
77
93
if page not in props :
0 commit comments