]> git.proxmox.com Git - ceph.git/blame - ceph/src/ceph-volume/ceph_volume/terminal.py
update sources to v12.2.3
[ceph.git] / ceph / src / ceph-volume / ceph_volume / terminal.py
CommitLineData
b32b8144 1import logging
d2e6a577
FG
2import sys
3
4
5class colorize(str):
6 """
7 Pretty simple to use::
8
9 colorize.make('foo').bold
10 colorize.make('foo').green
11 colorize.make('foo').yellow
12 colorize.make('foo').red
13 colorize.make('foo').blue
14
15 Otherwise you could go the long way (for example if you are
16 testing this class)::
17
18 string = colorize('foo')
19 string._set_attributes()
20 string.red
21
22 """
23
24 def __init__(self, string):
25 self.stdout = sys.__stdout__
26 self.appends = ''
27 self.prepends = ''
28 self.isatty = self.stdout.isatty()
29
30 def _set_attributes(self):
31 """
32 Sets the attributes here because the str class does not
33 allow to pass in anything other than a string to the constructor
34 so we can't really mess with the other attributes.
35 """
36 for k, v in self.__colors__.items():
37 setattr(self, k, self.make_color(v))
38
39 def make_color(self, color):
40 if not self.isatty:
41 return self
42 return color + self + '\033[0m' + self.appends
43
44 @property
45 def __colors__(self):
46 return dict(
47 blue='\033[34m',
48 green='\033[92m',
49 yellow='\033[33m',
50 red='\033[91m',
51 bold='\033[1m',
52 ends='\033[0m'
53 )
54
55 @classmethod
56 def make(cls, string):
57 """
58 A helper method to return itself and workaround the fact that
59 the str object doesn't allow extra arguments passed in to the
60 constructor
61 """
62 obj = cls(string)
63 obj._set_attributes()
64 return obj
65
66#
67# Common string manipulations
68#
69yellow = lambda x: colorize.make(x).yellow # noqa
70blue = lambda x: colorize.make(x).blue # noqa
71green = lambda x: colorize.make(x).green # noqa
72red = lambda x: colorize.make(x).red # noqa
73bold = lambda x: colorize.make(x).bold # noqa
74red_arrow = red('--> ')
75blue_arrow = blue('--> ')
76green_arrow = green('--> ')
77yellow_arrow = yellow('--> ')
78
79
80class _Write(object):
81
82 def __init__(self, _writer=None, prefix='', suffix='', flush=False):
83 self._writer = _writer or sys.stdout
84 self.suffix = suffix
85 self.prefix = prefix
86 self.flush = flush
87
88 def bold(self, string):
89 self.write(bold(string))
90
91 def raw(self, string):
92 if not string.endswith('\n'):
93 string = '%s\n' % string
94 self.write(string)
95
96 def write(self, line):
97 self._writer.write(self.prefix + line + self.suffix)
98 if self.flush:
99 self._writer.flush()
100
101
102def stdout(msg):
103 return _Write(prefix=blue(' stdout: ')).raw(msg)
104
105
106def stderr(msg):
107 return _Write(prefix=yellow(' stderr: ')).raw(msg)
108
109
110def write(msg):
111 return _Write().raw(msg)
112
113
114def error(msg):
115 return _Write(prefix=red_arrow).raw(msg)
116
117
b32b8144
FG
118def info(msg):
119 return _Write(prefix=blue_arrow).raw(msg)
120
121
122def debug(msg):
123 return _Write(prefix=blue_arrow).raw(msg)
124
125
d2e6a577
FG
126def warning(msg):
127 return _Write(prefix=yellow_arrow).raw(msg)
128
129
130def success(msg):
131 return _Write(prefix=green_arrow).raw(msg)
132
133
b32b8144
FG
134class MultiLogger(object):
135 """
136 Proxy class to be able to report on both logger instances and terminal
137 messages avoiding the issue of having to call them both separately
138
139 Initialize it in the same way a logger object::
140
141 logger = terminal.MultiLogger(__name__)
142 """
143
144 def __init__(self, name):
145 self.logger = logging.getLogger(name)
146
147 def _make_record(self, msg, *args):
148 if len(str(args)):
149 try:
150 return msg % args
151 except TypeError:
152 self.logger.exception('unable to produce log record: %s' % msg)
153 return msg
154
155 def warning(self, msg, *args):
156 record = self._make_record(msg, *args)
157 warning(record)
158 self.logger.warning(record)
159
160 def debug(self, msg, *args):
161 record = self._make_record(msg, *args)
162 debug(record)
163 self.logger.debug(record)
164
165 def info(self, msg, *args):
166 record = self._make_record(msg, *args)
167 info(record)
168 self.logger.info(record)
169
170 def error(self, msg, *args):
171 record = self._make_record(msg, *args)
172 error(record)
173 self.logger.error(record)
174
175
d2e6a577
FG
176def dispatch(mapper, argv=None):
177 argv = argv or sys.argv
178 for count, arg in enumerate(argv, 1):
179 if arg in mapper.keys():
180 instance = mapper.get(arg)(argv[count:])
181 if hasattr(instance, 'main'):
182 instance.main()
183 raise SystemExit(0)
184
185
186def subhelp(mapper):
187 """
188 Look at every value of every key in the mapper and will output any
189 ``class.help`` possible to return it as a string that will be sent to
190 stdout.
191 """
192 help_text_lines = []
193 for key, value in mapper.items():
194 try:
195 help_text = value.help
196 except AttributeError:
197 continue
198 help_text_lines.append("%-24s %s" % (key, help_text))
199
200 if help_text_lines:
201 return "Available subcommands:\n\n%s" % '\n'.join(help_text_lines)
202 return ''