replace all use of dbapi's PORTDB, VARDB, BINDB assigned variables with the actuall...
[gentoolkit.git] / pym / gentoolkit / enalyze / output.py
1 #!/usr/bin/python
2 #
3 # Copyright(c) 2010, Gentoo Foundation
4 # Distributed under the terms of the GNU General Public License v2
5 #
6
7 """Provides various output classes and functions for
8 both screen and file output
9 """
10
11 from __future__ import print_function
12
13 import time
14
15 import gentoolkit
16 from gentoolkit import pprinter as pp
17 from gentoolkit.formatters import CpvValueWrapper
18 from gentoolkit.cpv import split_cpv
19
20 def nl(lines=1):
21         """small utility function to print blank lines
22
23         @type lines: integer
24         @param lines: optional number of blank lines to print
25                 default = 1
26                 """
27         print(('\n' * lines))
28
29 class AnalysisPrinter(CpvValueWrapper):
30         """Printing functions"""
31         def __init__(self, target, verbose=True, references=None, key_width=1, width=None):
32                 """@param references: list of accepted keywords or
33                                 the system use flags
34                                 """
35                 self.references = references
36                 self.key_width = key_width
37                 self.width = width
38                 CpvValueWrapper.__init__(self, cpv_width=key_width, width=width)
39                 self.set_target(target, verbose)
40
41         def set_target(self, target, verbose=True):
42                 if target in ["use"]:
43                         if verbose:
44                                 self.print_fn = self.print_use_verbose
45                         else:
46                                 self.print_fn = self.print_use_quiet
47                         self._format_key = self._format_use_keyword
48                 elif target in ["keywords"]:
49                         if verbose:
50                                 self.print_fn = self.print_keyword_verbose
51                         else:
52                                 self.print_fn = self.print_keyword_quiet
53                         self._format_key = self._format_use_keyword
54                 elif target in ["packages"]:
55                         if verbose:
56                                 self.print_fn = self.print_pkg_verbose
57                         else:
58                                 self.print_fn = self.print_pkg_quiet
59                         self._format_key = self._format_pkg
60
61         def __call__(self, key, active, data):
62                 self._format_key(key, active, data)
63
64         def _format_use_keyword(self, key, active, pkgs):
65                 """Determines the stats for key, formats it and
66                 calls the pre-determined print function
67                 """
68                 occurred = str(len(pkgs))
69                 if active in ["-", "~"]:
70                         _key = active + key
71                 else:
72                         _key = key
73                 if _key in self.references:
74                         default = "default"
75                 else:
76                         default = "......."
77                 count = ' '*(5-len(occurred)) + occurred
78                 pkgs.sort()
79                 self.print_fn(key, active, default, count, pkgs)
80
81         @staticmethod
82         def print_use_verbose(key, active, default, count, pkgs):
83                 """Verbosely prints a set of use flag info. including the pkgs
84                 using them.
85                 """
86                 _pkgs = pkgs[:]
87                 if active in ["+", "-"]:
88                         _key = pp.useflag((active+key), active=="+")
89                 else:
90                         _key = (" " + key)
91                 cpv = _pkgs.pop(0)
92                 print(_key,'.'*(35-len(key)), default, pp.number(count), pp.cpv(cpv))
93                 while _pkgs:
94                         cpv = _pkgs.pop(0)
95                         print(' '*52 + pp.cpv(cpv))
96
97         # W0613: *Unused argument %r*
98         # pylint: disable-msg=W0613
99         @staticmethod
100         def print_use_quiet(key, active, default, count, pkgs):
101                 """Quietly prints a subset set of USE flag info..
102                 """
103                 if active in ["+", "-"]:
104                         _key = pp.useflag((active+key), active=="+")
105                 else:
106                         _key = (" " + key)
107                 print(_key,'.'*(35-len(key)), default, pp.number(count))
108
109         @staticmethod
110         def print_keyword_verbose(key, stability, default, count, pkgs):
111                 """Verbosely prints a set of keywords info. including the pkgs
112                 using them.
113                 """
114                 _pkgs = pkgs[:]
115                 _key = (pp.keyword((stability+key),stable=(stability==" "),
116                         hard_masked=stability=="-"))
117                 cpv = _pkgs.pop(0)
118                 print(_key,'.'*(20-len(key)), default, pp.number(count), pp.cpv(cpv))
119                 while _pkgs:
120                         cpv = _pkgs.pop(0)
121                         print(' '*37 + pp.cpv(cpv))
122
123         # W0613: *Unused argument %r*
124         # pylint: disable-msg=W0613
125         @staticmethod
126         def print_keyword_quiet(key, stability, default, count, pkgs):
127                 """Quietly prints a subset set of USE flag info..
128                 """
129                 _key = (pp.keyword((stability+key), stable=(stability==" "),
130                         hard_masked=stability=="-"))
131                 print(_key,'.'*(20-len(key)), default, pp.number(count))
132
133         # W0613: *Unused argument %r*
134         # pylint: disable-msg=W0613
135         def _format_pkg(self, key, active, flags):
136                 """Determines the stats for key, formats it and
137                 calls the pre-determined print function
138                 """
139                 (plus, minus, cleaned) = flags
140                 _plus = []
141                 _minus = []
142                 _cleaned = []
143                 for flag in plus:
144                         _flag = flag.strip()
145                         if _flag:
146                                 _plus.append(_flag)
147                 for flag in minus:
148                         _flag = flag.strip()
149                         if _flag:
150                                 _minus.append(_flag)
151                 for flag in cleaned:
152                         _flag = flag.strip()
153                         if _flag:
154                                 _cleaned.append(_flag)
155                 #print("cpv=", key, "_plus=", _plus, "_minus=", _minus)
156                 self.print_fn(key, (plus, minus, cleaned))
157
158         def print_pkg_verbose(self, cpv, flags):
159                 """Verbosely prints the pkg's use flag info.
160                 """
161                 (plus, minus, unset) = flags
162                 _flags = []
163                 for flag in plus:
164                         _flags.append(pp.useflag((flag), True))
165                 for flag in minus:
166                         _flags.append(pp.useflag(('-' + flag), False))
167                 for flag in unset:
168                         _flags.append(pp.globaloption('-' + flag))
169
170                 print(self._format_values(cpv, ", ".join(_flags)))
171
172
173         def print_pkg_quiet(self, cpv, flags):
174                 """Verbosely prints the pkg's use flag info.
175                 """
176                 (plus, minus, unset) = flags
177                 _flags = []
178                 for flag in plus:
179                         _flags.append(pp.useflag((flag), True))
180                 for flag in minus:
181                         _flags.append(pp.useflag(('-'+flag), False))
182                 for flag in unset:
183                         _flags.append(pp.globaloption('-' + flag))
184
185                 print(self._format_values(cpv, ", ".join(_flags)))
186
187
188 class RebuildPrinter(CpvValueWrapper):
189         """Output functions"""
190         def __init__(self, target, pretend=True, exact=False,
191                 slot=False, key_width=1, width=None):
192                 """@param references: list of accepted keywords or
193                                 the system use flags
194                 """
195                 self.target = target
196                 self.set_target(target)
197                 self.pretend = pretend
198                 CpvValueWrapper.__init__(self, cpv_width=key_width, width=width)
199                 if pretend:
200                         self.spacer = '  '
201                         self.init_indent = len(self.spacer)
202                 else:
203                         self.spacer = ''
204                 self.exact = exact
205                 self.slot = slot
206                 self.data = {}
207
208
209         def set_target(self, target):
210                 if target in ["use"]:
211                         self.print_fn = self.print_use
212                 elif target in ["keywords"]:
213                         self.print_fn = self.print_keyword
214                 elif target in ["unmask"]:
215                         self.print_fn = self.print_mask
216                 self.lines = [self.header()]
217
218
219         def __call__(self, key, values, cp_count):
220                 if self.target in ["keywords", "use"]:
221                         self._format_atoms(key, values, cp_count)
222                 else:
223                         self._format_key(key, values)
224
225
226         def _format_key(self, key, values):
227                 """Determines the stats for key, formats it and
228                 calls the pre-determined print function
229                 """
230                 if self.exact:
231                         _key = "=" + key
232                 else:
233                         parts = split_cpv(key)
234                         _key = '/'.join(parts[:2])
235                 values.sort()
236                 self.data[_key] = values
237                 self.print_fn( _key, values)
238
239         def print_use(self, key, atom=None, values=None):
240                 """Prints a USE flag string.
241                 """
242                 if atom and not values:
243                         values = atom.use
244                 if self.pretend:
245                         flags = []
246                         for flag in values:
247                                 flags.append(pp.useflag(flag, (flag[0] != '-')))
248                         print(self._format_values(self.spacer+key, ' '.join(flags)))
249                 else:
250                         line = ' '.join([key, ' '.join(values)])
251                         self.lines.append(line)
252
253         def _format_atoms(self, key, atoms, count):
254                 """Determines if there are more than one atom in the values and
255                 calls the predetermined print function for each atom.
256                 """
257                 #print("_format_atoms(),", key, atoms)
258                 if self.exact:
259                         for atom in atoms:
260                                 self.print_fn(str(atom), atom=atom)
261                         return
262                 #print("_format_atoms(), count =", count)
263                 if self.slot or count > 1:
264                         for atom in atoms:
265                                 _key = str(atom.cp) + ":" + atom.slot
266                                 self.print_fn(_key, atom=atom)
267                 else:
268                         for atom in atoms:
269                                 _key = str(atom.cp)
270                                 self.print_fn(_key, atom=atom)
271                 return
272
273         def print_keyword(self, key, atom=None, keyword=None):
274                 """prints a pkg key and a keyword"""
275                 #print("print_keyword(),", key, keyword)
276                 if atom and not keyword:
277                         keyword = atom.keyword
278                 if self.pretend:
279                         print(self._format_values(key, keyword))
280                 else:
281                         line = ' '.join([key, keyword])
282                         self.lines.append(line)
283
284
285         def print_unmask(self):
286                 pass
287
288         def header(self):
289                 """Generates a file header
290                 """
291
292                 h=("# This package.%s file was generated by "
293                         %self.target +
294                         "gentoolkit's 'enalyze rebuild' module\n"
295                         "# Date: " + time.asctime() + "\n"
296                 )
297                 return h