File: docs.py

package info (click to toggle)
boost1.83 1.83.0-5
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 545,632 kB
  • sloc: cpp: 3,857,086; xml: 125,552; ansic: 34,414; python: 25,887; asm: 5,276; sh: 4,799; ada: 1,681; makefile: 1,629; perl: 1,212; pascal: 1,139; sql: 810; yacc: 478; ruby: 102; lisp: 24; csh: 6
file content (74 lines) | stat: -rw-r--r-- 2,225 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
#!/usr/bin/env python3

# Copyright 2023 Nikita Kniazev
# Distributed under the Boost Software License, Version 1.0.
# (See accompanying file LICENSE.txt or copy at
# https://www.bfgroup.xyz/b2/LICENSE.txt)

import re
import sys
from collections import defaultdict
from pathlib import Path


def read_text(path, root):
    try:
        return path.read_text('utf-8')
    except UnicodeDecodeError as e:
        data = path.read_bytes()
        i = data.rfind(b'\n', 0, e.start) + 1
        j = data.find(b'\n', e.end)
        e.reason += f'\nOn line: {data[i:j]}\nIn file {path.relative_to(root)}'
        raise


def main():
    for path in Path(__file__).absolute().parents:
        if (path / 'Jamroot.jam').is_file():
            root = path
            break
    else:
        print("Could not locate Jamroot.jam")
        exit(1)

    already_included = defaultdict(set)
    for doc in (root / 'doc/src').rglob('*.adoc'):
        if not doc.is_file():
            continue
        for match in re.finditer(r'include::([^\[]+)\[tag=([^\]]+)', read_text(doc, root)):
            path = (doc.parent / match.group(1)).resolve().relative_to(root).as_posix()
            already_included[str(path)].add(match.group(2))

    if '-v' in sys.argv:
        for incl, tags in sorted(already_included.items()):
            print(f'* {incl}: {tags}')

    fail = False
    #for path in (root / 'src').rglob('*.[jch]*'):
    for path in (root / 'src').rglob('*.jam'):
        if not path.is_file():
            continue

        tags = set(re.findall(r'tag::([^\[]+)', read_text(path, root)))
        if not tags:
            continue

        path = path.relative_to(root).as_posix()
        already_included_tags = already_included.get(str(path))
        if already_included_tags is None:
            print(f'{path} has documentation but is not included anywhere, uses tags: {", ".join(tags)}')
            fail = True
            continue

        tags -= already_included_tags
        if tags:
            print(f'{path} has unused in documentation tags: {", ".join(tags)}')
            fail = True

    if not fail and __name__ == '__main__':
        print('Everything seems to be OK', file=sys.stderr)

    exit(fail)


main()