summaryrefslogtreecommitdiff
path: root/docs/bin/generate_man.py
blob: f3615f63a08be529ab0db32f606f7549e1726e82 (plain)
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
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
#!/usr/bin/env python

import os
import sys

from jinja2 import Environment, FileSystemLoader

from ansible.module_utils._text import to_bytes


def get_options(optlist):
    ''' get actual options '''

    opts = []
    for opt in optlist:
        res = {
            'desc': opt.help,
            'options': opt._short_opts + opt._long_opts
        }
        if opt.action == 'store':
            res['arg'] = opt.dest.upper()
        opts.append(res)

    return opts


def opt_doc_list(cli):
    ''' iterate over options lists '''

    results = []
    for optg in cli.parser.option_groups:
        results.extend(get_options(optg.option_list))

    results.extend(get_options(cli.parser.option_list))

    return results


def opts_docs(cli, name):
    ''' generate doc structure from options '''

    # cli name
    if '-' in name:
        name = name.split('-')[1]
    else:
        name = 'adhoc'

    # cli info
    docs = {
        'cli': name,
        'usage': cli.parser.usage,
        'short_desc': cli.parser.description,
        'long_desc': cli.__doc__,
    }

    # force populate parser with per action options
    if cli.VALID_ACTIONS:
        docs['actions'] = {}
        # avoid dupe errors
        cli.parser.set_conflict_handler('resolve')
        for action in cli.VALID_ACTIONS:
            cli.args.append(action)
            cli.set_action()
            docs['actions'][action] = getattr(cli, 'execute_%s' % action).__doc__

    docs['options'] = opt_doc_list(cli)

    return docs

if __name__ == '__main__':

    template_file = 'man.j2'

    # need to be in right dir
    os.chdir(os.path.dirname(__file__))

    allvars = {}
    output = {}
    cli_list = []
    for binary in os.listdir('../../lib/ansible/cli'):

        if not binary.endswith('.py'):
            continue
        elif binary == '__init__.py':
            continue

        libname = os.path.splitext(binary)[0]
        print("Found CLI %s" % libname)

        if libname == 'adhoc':
            myclass = 'AdHocCLI'
            output[libname] = 'ansible.1.asciidoc.in'
        else:
            myclass = "%sCLI" % libname.capitalize()
            output[libname] = 'ansible-%s.1.asciidoc.in' % libname

        # instanciate each cli and ask its options
        mycli = getattr(__import__("ansible.cli.%s" % libname, fromlist=[myclass]), myclass)
        cli_object = mycli([])
        try:
            cli_object.parse()
        except:
            # no options passed, we expect errors
            pass

        allvars[libname] = opts_docs(cli_object, libname)

        for extras in ('ARGUMENTS'):
            if hasattr(cli_object, extras):
                allvars[libname][extras.lower()] = getattr(cli_object, extras)

    cli_list = allvars.keys()
    for libname in cli_list:

        # template it!
        env = Environment(loader=FileSystemLoader('../templates'))
        template = env.get_template('man.j2')

        # add rest to vars
        tvars = allvars[libname]
        tvars['cli_list'] = cli_list
        tvars['cli'] = libname
        if '-i' in tvars['options']:
            print('uses inventory')

        manpage = template.render(tvars)
        filename = '../man/man1/%s' % output[libname]
        with open(filename, 'wb') as f:
            f.write(to_bytes(manpage))
            print("Wrote man docs to %s" % filename)