1 |
commit: fe3be8a3e51540f85d0fbee2c9abb18f7848f598 |
2 |
Author: Brian Dolbec <brian.dolbec <AT> gmail <DOT> com> |
3 |
AuthorDate: Wed Feb 23 09:09:52 2011 +0000 |
4 |
Commit: Brian Dolbec <brian.dolbec <AT> gmail <DOT> com> |
5 |
CommitDate: Wed Feb 23 09:09:52 2011 +0000 |
6 |
URL: http://git.overlays.gentoo.org/gitweb/?p=proj/gentoolkit.git;a=commit;h=fe3be8a3 |
7 |
|
8 |
code the rebuild keywords module. |
9 |
Add date and time info to the header generated. |
10 |
add -s, --slot option. |
11 |
|
12 |
--- |
13 |
pym/gentoolkit/analyse/output.py | 54 +++++++++++--- |
14 |
pym/gentoolkit/analyse/rebuild.py | 155 ++++++++++++++++++++++++++++++++---- |
15 |
2 files changed, 181 insertions(+), 28 deletions(-) |
16 |
|
17 |
diff --git a/pym/gentoolkit/analyse/output.py b/pym/gentoolkit/analyse/output.py |
18 |
index 90db064..a67e8c6 100644 |
19 |
--- a/pym/gentoolkit/analyse/output.py |
20 |
+++ b/pym/gentoolkit/analyse/output.py |
21 |
@@ -10,12 +10,13 @@ both screen and file output |
22 |
|
23 |
from __future__ import print_function |
24 |
|
25 |
+import time |
26 |
+ |
27 |
import gentoolkit |
28 |
from gentoolkit import pprinter as pp |
29 |
from gentoolkit.formatters import CpvValueWrapper |
30 |
from gentoolkit.cpv import split_cpv |
31 |
|
32 |
- |
33 |
def nl(lines=1): |
34 |
"""small utility function to print blank lines |
35 |
|
36 |
@@ -165,7 +166,7 @@ class AnalysisPrinter(CpvValueWrapper): |
37 |
_flags.append(pp.useflag(('-' + flag), False)) |
38 |
for flag in unset: |
39 |
_flags.append(pp.globaloption('-' + flag)) |
40 |
- |
41 |
+ |
42 |
print(self._format_values(cpv, ", ".join(_flags))) |
43 |
|
44 |
|
45 |
@@ -180,13 +181,14 @@ class AnalysisPrinter(CpvValueWrapper): |
46 |
_flags.append(pp.useflag(('-'+flag), False)) |
47 |
for flag in unset: |
48 |
_flags.append(pp.globaloption('-' + flag)) |
49 |
- |
50 |
+ |
51 |
print(self._format_values(cpv, ", ".join(_flags))) |
52 |
|
53 |
|
54 |
class RebuildPrinter(CpvValueWrapper): |
55 |
"""Output functions""" |
56 |
- def __init__(self, target, pretend=True, exact=False, key_width=1, width=None): |
57 |
+ def __init__(self, target, pretend=True, exact=False, |
58 |
+ slot=False, key_width=1, width=None): |
59 |
"""@param references: list of accepted keywords or |
60 |
the system use flags |
61 |
""" |
62 |
@@ -200,21 +202,25 @@ class RebuildPrinter(CpvValueWrapper): |
63 |
else: |
64 |
self.spacer = '' |
65 |
self.exact = exact |
66 |
+ self.slot = slot |
67 |
self.data = {} |
68 |
|
69 |
|
70 |
def set_target(self, target): |
71 |
if target in ["use"]: |
72 |
self.print_fn = self.print_use |
73 |
- self.use_lines = [self.header()] |
74 |
elif target in ["keywords"]: |
75 |
self.print_fn = self.print_keyword |
76 |
elif target in ["unmask"]: |
77 |
self.print_fn = self.print_mask |
78 |
+ self.lines = [self.header()] |
79 |
|
80 |
|
81 |
def __call__(self, key, values): |
82 |
- self._format_key(key, values) |
83 |
+ if self.target in ["keywords"]: |
84 |
+ self._format_atoms(key, values) |
85 |
+ else: |
86 |
+ self._format_key(key, values) |
87 |
|
88 |
|
89 |
def _format_key(self, key, values): |
90 |
@@ -240,11 +246,38 @@ class RebuildPrinter(CpvValueWrapper): |
91 |
print(self._format_values(self.spacer+key, ' '.join(flags))) |
92 |
else: |
93 |
line = ' '.join([key, ' '.join(values)]) |
94 |
- self.use_lines.append(line) |
95 |
- |
96 |
+ self.lines.append(line) |
97 |
|
98 |
- def print_keyword(self): |
99 |
- pass |
100 |
+ def _format_atoms(self, key, atoms): |
101 |
+ """Determines if there are more than one atom in the values and |
102 |
+ calls the predetermined print function for each atom. |
103 |
+ """ |
104 |
+ #print("_format_atoms(),", key, atoms) |
105 |
+ if self.exact: |
106 |
+ for atom in atoms: |
107 |
+ self.print_fn(str(atom), atom.keyword) |
108 |
+ return |
109 |
+ many = False |
110 |
+ if len(atoms) >1: |
111 |
+ many = True |
112 |
+ if self.slot or many: |
113 |
+ for atom in atoms: |
114 |
+ _key = str(atom.cp) + ":" + atom.slot |
115 |
+ self.print_fn(_key, atom.keyword) |
116 |
+ else: |
117 |
+ for atom in atoms: |
118 |
+ _key = str(atom.cp) |
119 |
+ self.print_fn(_key, atom.keyword) |
120 |
+ return |
121 |
+ |
122 |
+ def print_keyword(self, key, keyword): |
123 |
+ """prints a pkg key and a keyword""" |
124 |
+ #print("print_keyword(),", key, keyword) |
125 |
+ if self.pretend: |
126 |
+ print(self._format_values(key, keyword)) |
127 |
+ else: |
128 |
+ line = ' '.join([key, keyword]) |
129 |
+ self.lines.append(line) |
130 |
|
131 |
|
132 |
def print_unmask(self): |
133 |
@@ -257,5 +290,6 @@ class RebuildPrinter(CpvValueWrapper): |
134 |
h=("# This package.%s file was generated by " |
135 |
%self.target + |
136 |
"gentoolkit's 'analyse rebuild' module\n" |
137 |
+ "# Date: " + time.asctime() + "\n" |
138 |
) |
139 |
return h |
140 |
|
141 |
diff --git a/pym/gentoolkit/analyse/rebuild.py b/pym/gentoolkit/analyse/rebuild.py |
142 |
index cce8864..0c1ce6e 100644 |
143 |
--- a/pym/gentoolkit/analyse/rebuild.py |
144 |
+++ b/pym/gentoolkit/analyse/rebuild.py |
145 |
@@ -20,9 +20,12 @@ import gentoolkit |
146 |
from gentoolkit.dbapi import PORTDB, VARDB |
147 |
from gentoolkit.analyse.base import ModuleBase |
148 |
from gentoolkit import pprinter as pp |
149 |
-from gentoolkit.analyse.lib import get_installed_use, get_flags, FlagAnalyzer |
150 |
+from gentoolkit.analyse.lib import (get_installed_use, get_flags, FlagAnalyzer, |
151 |
+ KeywordAnalyser) |
152 |
from gentoolkit.flag import reduce_flags |
153 |
from gentoolkit.analyse.output import RebuildPrinter |
154 |
+from gentoolkit.atom import Atom |
155 |
+ |
156 |
|
157 |
import portage |
158 |
|
159 |
@@ -71,6 +74,55 @@ def cpv_all_diff_use( |
160 |
return data |
161 |
|
162 |
|
163 |
+def cpv_all_diff_keywords( |
164 |
+ cpvs=None, |
165 |
+ system_keywords=None, |
166 |
+ use_portage=False, |
167 |
+ # override-able for testing |
168 |
+ keywords=portage.settings["ACCEPT_KEYWORDS"], |
169 |
+ analyser = None |
170 |
+ ): |
171 |
+ """Analyse the installed pkgs 'keywords' for difference from ACCEPT_KEYWORDS |
172 |
+ |
173 |
+ @param cpvs: optional list of [cat/pkg-ver,...] to analyse or |
174 |
+ defaults to entire installed pkg db |
175 |
+ @param system_keywords: list of the system keywords |
176 |
+ @param keywords: user defined list of keywords to check and report on |
177 |
+ or reports on all relevant keywords found to have been used. |
178 |
+ @param _get_kwds: overridable function for testing |
179 |
+ @param _get_used: overridable function for testing |
180 |
+ @rtype dict. {keyword:{"stable":[cat/pkg-ver,...], |
181 |
+ "testing":[cat/pkg-ver,...]} |
182 |
+ """ |
183 |
+ if cpvs is None: |
184 |
+ cpvs = VARDB.cpv_all() |
185 |
+ keyword_users = {} |
186 |
+ for cpv in cpvs: |
187 |
+ if cpv.startswith("virtual"): |
188 |
+ continue |
189 |
+ if use_portage: |
190 |
+ keyword = analyser.get_inst_keyword_cpv(cpv) |
191 |
+ else: |
192 |
+ pkg = Package(cpv) |
193 |
+ keyword = analyser.get_inst_keyword_pkg(pkg) |
194 |
+ #print "returned keyword =", cpv, keyword, keyword[0] |
195 |
+ key = keyword[0] |
196 |
+ if key in ["~", "-"] and keyword not in system_keywords: |
197 |
+ atom = Atom("="+cpv) |
198 |
+ if atom.cp not in keyword_users: |
199 |
+ keyword_users[atom.cp] = [] |
200 |
+ if key in ["~"]: |
201 |
+ atom.keyword = keyword |
202 |
+ atom.slot = VARDB.aux_get(atom.cpv, ["SLOT"])[0] |
203 |
+ keyword_users[atom.cp].append(atom) |
204 |
+ elif key in ["-"]: |
205 |
+ #print "adding cpv to missing:", cpv |
206 |
+ atom.keyword = "**" |
207 |
+ atom.slot = VARDB.aux_get(atom.cpv, ["SLOT"])[0] |
208 |
+ keyword_users[atom.cp].append(atom) |
209 |
+ return keyword_users |
210 |
+ |
211 |
+ |
212 |
class Rebuild(ModuleBase): |
213 |
"""Installed db analysis tool to query the installed databse |
214 |
and produce/output stats for USE flags or keywords/mask. |
215 |
@@ -90,6 +142,9 @@ class Rebuild(ModuleBase): |
216 |
"quiet": False, |
217 |
"exact": False, |
218 |
"pretend": False, |
219 |
+ "prefix": False, |
220 |
+ "portage": True, |
221 |
+ "slot": False |
222 |
#"unset": False |
223 |
} |
224 |
self.module_opts = { |
225 |
@@ -97,6 +152,8 @@ class Rebuild(ModuleBase): |
226 |
"--pretend": ("pretend", "boolean", True), |
227 |
"-e": ("exact", "boolean", True), |
228 |
"--exact": ("exact", "boolean", True), |
229 |
+ "-s": ("slot", "boolean", True), |
230 |
+ "--slot": ("slot", "boolean", True), |
231 |
"-v": ("verbose", "boolean", True), |
232 |
"--verbose": ("verbose", "boolean", True), |
233 |
} |
234 |
@@ -105,7 +162,9 @@ class Rebuild(ModuleBase): |
235 |
(" -p, --pretend", "Does not actually create the files."), |
236 |
(" ", "It directs the outputs to the screen"), |
237 |
(" -e, --exact", "will atomize the package with a"), |
238 |
- (" ", "leading '=' and include the version") |
239 |
+ (" ", "leading '=' and include the version"), |
240 |
+ (" -s, --slot", "will atomize the package with a"), |
241 |
+ (" ", "leading '=' and include the slot") |
242 |
] |
243 |
self.formatted_args = [ |
244 |
(" use", |
245 |
@@ -116,8 +175,8 @@ class Rebuild(ModuleBase): |
246 |
"causes the action to analyse the installed packages " + \ |
247 |
"current mask status") |
248 |
] |
249 |
- self.short_opts = "hepv" |
250 |
- self.long_opts = ("help", "exact", "pretend", "verbose") |
251 |
+ self.short_opts = "hepsv" |
252 |
+ self.long_opts = ("help", "exact", "pretend", "slot", "verbose") |
253 |
self.need_queries = True |
254 |
self.arg_spec = "TargetSpec" |
255 |
self.arg_options = ['use', 'keywords', 'unmask'] |
256 |
@@ -153,7 +212,8 @@ class Rebuild(ModuleBase): |
257 |
print(" -- Scanning installed packages for USE flag settings that") |
258 |
print(" do not match the default settings") |
259 |
system_use = portage.settings["USE"].split() |
260 |
- output = RebuildPrinter("use", self.options["pretend"], self.options["exact"]) |
261 |
+ output = RebuildPrinter( |
262 |
+ "use", self.options["pretend"], self.options["exact"]) |
263 |
pkgs = cpv_all_diff_use(system_flags=system_use) |
264 |
pkg_count = len(pkgs) |
265 |
if self.options["verbose"]: |
266 |
@@ -167,26 +227,17 @@ class Rebuild(ModuleBase): |
267 |
if self.options["pretend"] and not self.options["quiet"]: |
268 |
print() |
269 |
print(pp.globaloption( |
270 |
- " -- These are the installed packages & flags " + |
271 |
+ " -- These are the installed packages & keywords " + |
272 |
"that were detected")) |
273 |
- print(pp.globaloption(" to need flag settings other " + |
274 |
+ print(pp.globaloption(" to need keyword settings other " + |
275 |
"than the defaults.")) |
276 |
print() |
277 |
elif not self.options["quiet"]: |
278 |
print(" -- preparing pkgs for file entries") |
279 |
- flag_count = 0 |
280 |
- unique_flags = set() |
281 |
for pkg in pkg_keys: |
282 |
- if self.options['verbose']: |
283 |
- flag_count += len(pkgs[pkg]) |
284 |
- unique_flags.update(reduce_flags(pkgs[pkg])) |
285 |
output(pkg, pkgs[pkg]) |
286 |
if self.options['verbose']: |
287 |
message = (pp.emph(" ") + |
288 |
- pp.number(str(len(unique_flags))) + |
289 |
- pp.emph(" unique flags\n") + " " + |
290 |
- pp.number(str(flag_count))+ |
291 |
- pp.emph(" flag entries\n") + " " + |
292 |
pp.number(str(pkg_count)) + |
293 |
pp.emph(" different packages")) |
294 |
print() |
295 |
@@ -197,12 +248,80 @@ class Rebuild(ModuleBase): |
296 |
#unique.sort() |
297 |
#print unique |
298 |
if not self.options["pretend"]: |
299 |
- filepath = os.path.expanduser('~/package.use.test') |
300 |
- self.save_file(filepath, output.use_lines) |
301 |
+ filepath = os.path.expanduser('~/package.keywords.test') |
302 |
+ self.save_file(filepath, output.lines) |
303 |
|
304 |
def rebuild_keywords(self): |
305 |
print("Module action not yet available") |
306 |
print() |
307 |
+ """This will scan the installed packages db and analyse the |
308 |
+ keywords used for installation and produce a report on them. |
309 |
+ """ |
310 |
+ system_keywords = portage.settings["ACCEPT_KEYWORDS"].split() |
311 |
+ output = RebuildPrinter( |
312 |
+ "keywords", self.options["pretend"], self.options["exact"], |
313 |
+ self.options['slot']) |
314 |
+ arch = portage.settings["ARCH"] |
315 |
+ if self.options["prefix"]: |
316 |
+ # build a new keyword for testing |
317 |
+ system_keywords = "~" + arch + "-linux" |
318 |
+ if self.options["verbose"] or self.options["prefix"]: |
319 |
+ print("Current system ARCH =", arch) |
320 |
+ print("Current system ACCEPT_KEYWORDS =", system_keywords) |
321 |
+ self.analyser = KeywordAnalyser( arch, system_keywords, VARDB) |
322 |
+ #self.analyser.set_order(portage.settings["USE"].split()) |
323 |
+ # only for testing |
324 |
+ test_use = portage.settings["USE"].split() |
325 |
+ if self.options['prefix'] and 'prefix' not in test_use: |
326 |
+ print("REBUILD_KEYWORDS() 'prefix' flag not found in system", |
327 |
+ "USE flags!!! appending for testing") |
328 |
+ print() |
329 |
+ test_use.append('prefix') |
330 |
+ self.analyser.set_order(test_use) |
331 |
+ # /end testing |
332 |
+ |
333 |
+ cpvs = VARDB.cpv_all() |
334 |
+ #print "Total number of installed ebuilds =", len(cpvs) |
335 |
+ pkgs = cpv_all_diff_keywords( |
336 |
+ cpvs=cpvs, |
337 |
+ system_keywords=system_keywords, |
338 |
+ use_portage=self.options['portage'], |
339 |
+ analyser = self.analyser |
340 |
+ ) |
341 |
+ #print([pkgs[p][0].cpv for p in pkgs]) |
342 |
+ if pkgs: |
343 |
+ pkg_keys = sorted(pkgs) |
344 |
+ #print(len(pkgs)) |
345 |
+ if self.options["pretend"] and not self.options["quiet"]: |
346 |
+ print() |
347 |
+ print(pp.globaloption( |
348 |
+ " -- These are the installed packages & keywords " + |
349 |
+ "that were detected")) |
350 |
+ print(pp.globaloption(" to need keyword settings other " + |
351 |
+ "than the defaults.")) |
352 |
+ print() |
353 |
+ elif not self.options["quiet"]: |
354 |
+ print(" -- preparing pkgs for file entries") |
355 |
+ for pkg in pkg_keys: |
356 |
+ output(pkg, pkgs[pkg]) |
357 |
+ if not self.options['quiet']: |
358 |
+ if self.analyser.mismatched: |
359 |
+ print("_________________________________________________") |
360 |
+ print(("The following packages were found to have a \n" + |
361 |
+ "different recorded ARCH than the current system ARCH")) |
362 |
+ for cpv in self.analyser.mismatched: |
363 |
+ print("\t", pp.cpv(cpv)) |
364 |
+ print("===================================================") |
365 |
+ print("Total number of entries in report =", |
366 |
+ pp.output.red(str(len(pkg_keys)))) |
367 |
+ if self.options["verbose"]: |
368 |
+ print("Total number of installed ebuilds =", |
369 |
+ pp.output.red(str(len(cpvs)))) |
370 |
+ print() |
371 |
+ if not self.options["pretend"]: |
372 |
+ filepath = os.path.expanduser('~/package.keywords.test') |
373 |
+ self.save_file(filepath, output.lines) |
374 |
+ |
375 |
|
376 |
def rebuild_unmask(self): |
377 |
print("Module action not yet available") |