Test Failed
Pull Request — master (#2)
by Heiko 'riot'
06:45
created

isomer.tool.misc.version()   A

Complexity

Conditions 1

Size

Total Lines 5
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 3
nop 0
dl 0
loc 5
rs 10
c 0
b 0
f 0
1
#!/usr/bin/env python
2
# -*- coding: UTF-8 -*-
3
4
# Isomer - The distributed application framework
5
# ==============================================
6
# Copyright (C) 2011-2020 Heiko 'riot' Weinen <[email protected]> and others.
7
#
8
# This program is free software: you can redistribute it and/or modify
9
# it under the terms of the GNU Affero General Public License as published by
10
# the Free Software Foundation, either version 3 of the License, or
11
# (at your option) any later version.
12
#
13
# This program is distributed in the hope that it will be useful,
14
# but WITHOUT ANY WARRANTY; without even the implied warranty of
15
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
# GNU Affero General Public License for more details.
17
#
18
# You should have received a copy of the GNU Affero General Public License
19
# along with this program.  If not, see <http://www.gnu.org/licenses/>.
20
21
"""
22
23
Module: Misc
24
============
25
26
Miscellaneous functionality for the management tool.
27
28
"""
29
30
import click
31
from click_repl import repl
32
from prompt_toolkit.history import FileHistory
33
from prompt_toolkit.styles import Style
34
35
from isomer.tool import run_process
36
from isomer.tool.cli import cli
37
from isomer.version import version_info
38
39
40
@cli.command(short_help="Start interactive management shell")
41
def shell():
42
    """Open an shell to work with the manage tool interactively."""
43
44
    print(
45
        """Isomer - Management Tool Interactive Prompt
46
47
    Type -h for help, tab completion is available, hit Ctrl-D to quit."""
48
    )
49
50
    style = Style.from_dict(
51
        {
52
            # User input (default text).
53
            "": "ansiwhite",
54
            "space": "ansigreen nounderline",
55
            "prompt": "ansicyan underline",
56
            "bottom-toolbar": "ansiblue",
57
            "bottom-toolbar-name": "bg:ansicyan",
58
        }
59
    )
60
61
    completer_styles = {
62
        "command": "ansicyan",
63
        "option": "ansigreen",
64
        "argument": "ansiyellow",
65
    }
66
67
    message = [("class:prompt", ">>"), ("class:space", " ")]
68
69
    def bottom_toolbar():
70
        """Returns a nice isomeric toolbar with the current version displayed"""
71
        return [
72
            ("class:bottom-toolbar-name", " Isomer "),
73
            ("class:bottom-toolbar", "maintenance tool (%s)" % version_info),
74
        ]
75
76
    prompt_kwargs = {
77
        "history": FileHistory("/tmp/.isomer-manage.history"),
78
        "message": message,
79
        "style": style,
80
        "bottom_toolbar": bottom_toolbar,
81
    }
82
83
    repl(
84
        click.get_current_context(),
85
        prompt_kwargs=prompt_kwargs,
86
        styles=completer_styles,
87
    )
88
89
90
@cli.command(short_help="View command map graph")
91
@click.option(
92
    "--xdot", help="Use xdot for nicer displaying", is_flag=True, default=False
93
)
94
def cmdmap(xdot):
95
    """Generates a command map"""
96
    # TODO: Integrate the output into documentation
97
98
    from copy import copy
99
100
    def generate_command_graph(command, map_output, groups=None, depth=0):
101
        """Generate a strict digraph (as indented representation) of all known
102
        subgroups and commands"""
103
104
        if groups is None:
105
            groups = []
106
        if "commands" in command.__dict__:
107
            if len(groups) > 0:
108
                if xdot:
109
                    line = '    "%s" -> "%s" [weight=1.0];\n' % (
110
                        groups[-1],
111
                        command.name,
112
                    )
113
                else:
114
                    line = "    " * (depth - 1) + "%s %s\n" % (groups[-1], command.name)
115
                map_output.append(line)
116
117
            for item in command.commands.values():
118
                subgroups = copy(groups)
119
                subgroups.append(command.name)
120
                generate_command_graph(item, map_output, subgroups, depth + 1)
121
        else:
122
            if xdot:
123
                line = '    "%s" -> "%s" [weight=%1.1f];\n' % (
124
                    groups[-1],
125
                    command.name,
126
                    len(groups),
127
                )
128
            else:
129
                line = "    " * (len(groups) - 3 + depth) + "%s %s\n" % (
130
                    groups[-1],
131
                    command.name,
132
                )
133
            map_output.append(line)
134
135
    output = []
136
    generate_command_graph(cli, output)
137
138
    output = [line.replace("cli", "isomer") for line in output]
139
140
    if xdot:
141
        with open("iso-tool.dot", "w") as f:
142
            f.write("strict digraph {\n")
143
            f.writelines(sorted(output))
144
            f.write("}")
145
146
        run_process(".", ["xdot", "iso-tool.dot"])
147
    else:
148
        print("".join(output))
149