diff --git a/documentation/ref-manual/variables.rst b/documentation/ref-manual/variables.rst index e4d5a9c97a..6c2344950b 100644 --- a/documentation/ref-manual/variables.rst +++ b/documentation/ref-manual/variables.rst @@ -7,6 +7,9 @@ Variables Glossary This chapter lists common variables used in the OpenEmbedded build system and gives an overview of their function and contents. +.. + check_glossary_begin + :term:`A ` :term:`B` :term:`C ` :term:`D` :term:`E ` :term:`F ` :term:`G ` :term:`H ` :term:`I ` @@ -16,6 +19,9 @@ system and gives an overview of their function and contents. :term:`U ` :term:`V ` :term:`W ` :term:`X ` :term:`Z ` +.. + check_glossary_end + .. glossary:: :sorted: diff --git a/documentation/tools/check-glossaries b/documentation/tools/check-glossaries new file mode 100755 index 0000000000..b5dfe834e5 --- /dev/null +++ b/documentation/tools/check-glossaries @@ -0,0 +1,90 @@ +#!/usr/bin/env python3 + +import argparse +import difflib +import os +import re + +from pathlib import Path + + +def parse_arguments() -> argparse.Namespace: + parser = argparse.ArgumentParser(description="Print supported distributions") + + parser.add_argument("-d", "--docs-dir", + type=Path, + default=Path(os.path.dirname(os.path.realpath(__file__))) / "documentation", + help="Path to documentation/ directory in yocto-docs") + + return parser.parse_args() + + +glossaries = ( + 'ref-manual/variables.rst', + 'ref-manual/terms.rst', +) + + +def main(): + + args = parse_arguments() + in_glossary = False + # Pattern to match: + # :term:`A ` :term:`B` :term:`C ` + glossary_re = re.compile(r":term:`(?P[A-Z]{1})( <(?P[A-Z_]+)>)?`") + entry_re = re.compile(r"^ :term:`(?P.+)`\s*$") + + for rst in glossaries: + + glossary = {} + rst_path = Path(args.docs_dir) / rst + + with open(rst_path, "r") as f: + for line in f.readlines(): + if "check_glossary_begin" in line: + in_glossary = True + continue + if in_glossary: + for m in re.finditer(glossary_re, line.strip()): + letter = m.group("letter") + varname = m.group("varname") + if varname is None: + varname = letter + glossary[letter] = varname + if "check_glossary_end" in line: + in_glossary = False + break + + entries = [] + + with open(rst_path, "r") as f: + for line in f.readlines(): + m = re.match(entry_re, line) + if m: + entries.append(m.group("entry")) + + # We lower here because underscore (_) come before lowercase letters + # (the natural way) but after uppercase letters (which is not natural) + sorted_entries = sorted(entries, key=lambda t: t.lower()) + diffs = list(difflib.unified_diff(entries, + sorted_entries, + fromfile="original_list", + tofile="sorted_list")) + + if diffs: + print(f"WARNING: {rst}: entries are not properly sorted:") + print('\n'.join(diffs)) + + for letter in glossary: + try: + index = entries.index(glossary[letter]) + except ValueError: + print(f"WARNING: {rst}: variable " + f"{glossary[letter]} in glossary does not exist") + if index > 0 and entries[index - 1].startswith(letter[0]): + print(f"WARNING: {rst}: The variable {glossary[letter]} shouldn't be in " + "the glossary.") + + +if __name__ == "__main__": + main()