File: generate_docs.py

package info (click to toggle)
ansible-lint 4.1.0%2Bdfsg.1-1
  • links: PTS, VCS
  • area: main
  • in suites: buster
  • size: 1,096 kB
  • sloc: python: 3,373; sh: 4; makefile: 2
file content (106 lines) | stat: -rw-r--r-- 3,132 bytes parent folder | download
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
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
'''Script to generate rule table .rst documentation.'''

import os
import importlib
from inspect import getmembers, ismodule, isclass
import rules
from ansiblelint import AnsibleLintRule
from functools import reduce

DOC_HEADER = """
.. _lint_default_rules:

Default Rules
=============

.. contents:: Topics

The table below shows the the default rules used by Ansible Lint to evaluate playbooks and roles:

"""


def main():
    id_link = ('`E{} <https://github.com/ansible/ansible-lint/blob/'
               'master/lib/ansiblelint/rules/{}.py>`_')

    import_all_rules()
    all_rules = get_serialized_rules()

    grid = [['ID', 'Version Added', 'Sample Message', 'Description']]
    for d in all_rules:
        if d['id'].endswith('01'):
            if not d['id'].endswith('101'):
                grid.append(['', '', '', ''])
            grid.append([
                '**E{}xx - {}**'.format(d['id'][-3:-2], d['first_tag']),
                '',
                '',
                # '**{}**'.format(d['first_tag']),
                '',
            ])
        id_text = id_link.format(d['id'], d['classname'])
        grid.append([id_text, d['version_added'], d['shortdesc'], d['description']])

    filename = '../../docs/docsite/rst/rules/default_rules.rst'
    with open(filename, 'w') as file:
        file.write(make_table(grid))
        print('{} file written'.format(filename))


def import_all_rules():
    for module in list(os.walk('rules'))[0][2]:
        if module == '__init__.py' or module[-3:] != '.py':
            continue
        module = 'rules.{}'.format(module[:-3])
        importlib.import_module(module)


def get_serialized_rules():
    mod_list = [m[1] for m in getmembers(rules) if ismodule(m[1])]
    class_list = []
    for mod in mod_list:
        class_temp = [m[1] for m in getmembers(mod) if isclass(m[1])]
        class_temp = [c for c in class_temp if c is not AnsibleLintRule]
        class_list.extend(class_temp)

    all_rules = []
    for c in class_list:
        d = {
            'id': c.id,
            'shortdesc': c.shortdesc,
            'description': c.description,
            'first_tag': c.tags[0],
            'classname': c.__name__,
            'version_added': c.version_added,
        }
        all_rules.append(d)
    all_rules = sorted(all_rules, key=lambda k: k['id'])
    return all_rules


def make_table(grid):
    cell_width = 2 + max(reduce(lambda x, y: x+y,
                                [[len(item) for item in row] for row in grid], []))
    num_cols = len(grid[0])
    block = DOC_HEADER
    header = True
    for row in grid:
        if header:
            block = block + num_cols*((cell_width)*'=' + ' ') + '\n'

        block = block + ''.join([normalize_cell(x, cell_width+1)
                                 for x in row]) + '\n'
        if header:
            block = block + num_cols*((cell_width)*'=' + ' ') + '\n'
        header = False
    block = block + num_cols*((cell_width)*'=' + ' ') + '\n'
    return block


def normalize_cell(string, length):
    return string + ((length - len(string)) * ' ')


if __name__ == '__main__':
    main()