From fe3be8a3e51540f85d0fbee2c9abb18f7848f598 Mon Sep 17 00:00:00 2001 From: Brian Dolbec Date: Wed, 23 Feb 2011 01:09:52 -0800 Subject: [PATCH] code the rebuild keywords module. Add date and time info to the header generated. add -s, --slot option. --- pym/gentoolkit/analyse/output.py | 54 +++++++++-- pym/gentoolkit/analyse/rebuild.py | 155 ++++++++++++++++++++++++++---- 2 files changed, 181 insertions(+), 28 deletions(-) diff --git a/pym/gentoolkit/analyse/output.py b/pym/gentoolkit/analyse/output.py index 90db064..a67e8c6 100644 --- a/pym/gentoolkit/analyse/output.py +++ b/pym/gentoolkit/analyse/output.py @@ -10,12 +10,13 @@ both screen and file output from __future__ import print_function +import time + import gentoolkit from gentoolkit import pprinter as pp from gentoolkit.formatters import CpvValueWrapper from gentoolkit.cpv import split_cpv - def nl(lines=1): """small utility function to print blank lines @@ -165,7 +166,7 @@ class AnalysisPrinter(CpvValueWrapper): _flags.append(pp.useflag(('-' + flag), False)) for flag in unset: _flags.append(pp.globaloption('-' + flag)) - + print(self._format_values(cpv, ", ".join(_flags))) @@ -180,13 +181,14 @@ class AnalysisPrinter(CpvValueWrapper): _flags.append(pp.useflag(('-'+flag), False)) for flag in unset: _flags.append(pp.globaloption('-' + flag)) - + print(self._format_values(cpv, ", ".join(_flags))) class RebuildPrinter(CpvValueWrapper): """Output functions""" - def __init__(self, target, pretend=True, exact=False, key_width=1, width=None): + def __init__(self, target, pretend=True, exact=False, + slot=False, key_width=1, width=None): """@param references: list of accepted keywords or the system use flags """ @@ -200,21 +202,25 @@ class RebuildPrinter(CpvValueWrapper): else: self.spacer = '' self.exact = exact + self.slot = slot self.data = {} def set_target(self, target): if target in ["use"]: self.print_fn = self.print_use - self.use_lines = [self.header()] elif target in ["keywords"]: self.print_fn = self.print_keyword elif target in ["unmask"]: self.print_fn = self.print_mask + self.lines = [self.header()] def __call__(self, key, values): - self._format_key(key, values) + if self.target in ["keywords"]: + self._format_atoms(key, values) + else: + self._format_key(key, values) def _format_key(self, key, values): @@ -240,11 +246,38 @@ class RebuildPrinter(CpvValueWrapper): print(self._format_values(self.spacer+key, ' '.join(flags))) else: line = ' '.join([key, ' '.join(values)]) - self.use_lines.append(line) - + self.lines.append(line) - def print_keyword(self): - pass + def _format_atoms(self, key, atoms): + """Determines if there are more than one atom in the values and + calls the predetermined print function for each atom. + """ + #print("_format_atoms(),", key, atoms) + if self.exact: + for atom in atoms: + self.print_fn(str(atom), atom.keyword) + return + many = False + if len(atoms) >1: + many = True + if self.slot or many: + for atom in atoms: + _key = str(atom.cp) + ":" + atom.slot + self.print_fn(_key, atom.keyword) + else: + for atom in atoms: + _key = str(atom.cp) + self.print_fn(_key, atom.keyword) + return + + def print_keyword(self, key, keyword): + """prints a pkg key and a keyword""" + #print("print_keyword(),", key, keyword) + if self.pretend: + print(self._format_values(key, keyword)) + else: + line = ' '.join([key, keyword]) + self.lines.append(line) def print_unmask(self): @@ -257,5 +290,6 @@ class RebuildPrinter(CpvValueWrapper): h=("# This package.%s file was generated by " %self.target + "gentoolkit's 'analyse rebuild' module\n" + "# Date: " + time.asctime() + "\n" ) return h diff --git a/pym/gentoolkit/analyse/rebuild.py b/pym/gentoolkit/analyse/rebuild.py index cce8864..0c1ce6e 100644 --- a/pym/gentoolkit/analyse/rebuild.py +++ b/pym/gentoolkit/analyse/rebuild.py @@ -20,9 +20,12 @@ import gentoolkit from gentoolkit.dbapi import PORTDB, VARDB from gentoolkit.analyse.base import ModuleBase from gentoolkit import pprinter as pp -from gentoolkit.analyse.lib import get_installed_use, get_flags, FlagAnalyzer +from gentoolkit.analyse.lib import (get_installed_use, get_flags, FlagAnalyzer, + KeywordAnalyser) from gentoolkit.flag import reduce_flags from gentoolkit.analyse.output import RebuildPrinter +from gentoolkit.atom import Atom + import portage @@ -71,6 +74,55 @@ def cpv_all_diff_use( return data +def cpv_all_diff_keywords( + cpvs=None, + system_keywords=None, + use_portage=False, + # override-able for testing + keywords=portage.settings["ACCEPT_KEYWORDS"], + analyser = None + ): + """Analyse the installed pkgs 'keywords' for difference from ACCEPT_KEYWORDS + + @param cpvs: optional list of [cat/pkg-ver,...] to analyse or + defaults to entire installed pkg db + @param system_keywords: list of the system keywords + @param keywords: user defined list of keywords to check and report on + or reports on all relevant keywords found to have been used. + @param _get_kwds: overridable function for testing + @param _get_used: overridable function for testing + @rtype dict. {keyword:{"stable":[cat/pkg-ver,...], + "testing":[cat/pkg-ver,...]} + """ + if cpvs is None: + cpvs = VARDB.cpv_all() + keyword_users = {} + for cpv in cpvs: + if cpv.startswith("virtual"): + continue + if use_portage: + keyword = analyser.get_inst_keyword_cpv(cpv) + else: + pkg = Package(cpv) + keyword = analyser.get_inst_keyword_pkg(pkg) + #print "returned keyword =", cpv, keyword, keyword[0] + key = keyword[0] + if key in ["~", "-"] and keyword not in system_keywords: + atom = Atom("="+cpv) + if atom.cp not in keyword_users: + keyword_users[atom.cp] = [] + if key in ["~"]: + atom.keyword = keyword + atom.slot = VARDB.aux_get(atom.cpv, ["SLOT"])[0] + keyword_users[atom.cp].append(atom) + elif key in ["-"]: + #print "adding cpv to missing:", cpv + atom.keyword = "**" + atom.slot = VARDB.aux_get(atom.cpv, ["SLOT"])[0] + keyword_users[atom.cp].append(atom) + return keyword_users + + class Rebuild(ModuleBase): """Installed db analysis tool to query the installed databse and produce/output stats for USE flags or keywords/mask. @@ -90,6 +142,9 @@ class Rebuild(ModuleBase): "quiet": False, "exact": False, "pretend": False, + "prefix": False, + "portage": True, + "slot": False #"unset": False } self.module_opts = { @@ -97,6 +152,8 @@ class Rebuild(ModuleBase): "--pretend": ("pretend", "boolean", True), "-e": ("exact", "boolean", True), "--exact": ("exact", "boolean", True), + "-s": ("slot", "boolean", True), + "--slot": ("slot", "boolean", True), "-v": ("verbose", "boolean", True), "--verbose": ("verbose", "boolean", True), } @@ -105,7 +162,9 @@ class Rebuild(ModuleBase): (" -p, --pretend", "Does not actually create the files."), (" ", "It directs the outputs to the screen"), (" -e, --exact", "will atomize the package with a"), - (" ", "leading '=' and include the version") + (" ", "leading '=' and include the version"), + (" -s, --slot", "will atomize the package with a"), + (" ", "leading '=' and include the slot") ] self.formatted_args = [ (" use", @@ -116,8 +175,8 @@ class Rebuild(ModuleBase): "causes the action to analyse the installed packages " + \ "current mask status") ] - self.short_opts = "hepv" - self.long_opts = ("help", "exact", "pretend", "verbose") + self.short_opts = "hepsv" + self.long_opts = ("help", "exact", "pretend", "slot", "verbose") self.need_queries = True self.arg_spec = "TargetSpec" self.arg_options = ['use', 'keywords', 'unmask'] @@ -153,7 +212,8 @@ class Rebuild(ModuleBase): print(" -- Scanning installed packages for USE flag settings that") print(" do not match the default settings") system_use = portage.settings["USE"].split() - output = RebuildPrinter("use", self.options["pretend"], self.options["exact"]) + output = RebuildPrinter( + "use", self.options["pretend"], self.options["exact"]) pkgs = cpv_all_diff_use(system_flags=system_use) pkg_count = len(pkgs) if self.options["verbose"]: @@ -167,26 +227,17 @@ class Rebuild(ModuleBase): if self.options["pretend"] and not self.options["quiet"]: print() print(pp.globaloption( - " -- These are the installed packages & flags " + + " -- These are the installed packages & keywords " + "that were detected")) - print(pp.globaloption(" to need flag settings other " + + print(pp.globaloption(" to need keyword settings other " + "than the defaults.")) print() elif not self.options["quiet"]: print(" -- preparing pkgs for file entries") - flag_count = 0 - unique_flags = set() for pkg in pkg_keys: - if self.options['verbose']: - flag_count += len(pkgs[pkg]) - unique_flags.update(reduce_flags(pkgs[pkg])) output(pkg, pkgs[pkg]) if self.options['verbose']: message = (pp.emph(" ") + - pp.number(str(len(unique_flags))) + - pp.emph(" unique flags\n") + " " + - pp.number(str(flag_count))+ - pp.emph(" flag entries\n") + " " + pp.number(str(pkg_count)) + pp.emph(" different packages")) print() @@ -197,12 +248,80 @@ class Rebuild(ModuleBase): #unique.sort() #print unique if not self.options["pretend"]: - filepath = os.path.expanduser('~/package.use.test') - self.save_file(filepath, output.use_lines) + filepath = os.path.expanduser('~/package.keywords.test') + self.save_file(filepath, output.lines) def rebuild_keywords(self): print("Module action not yet available") print() + """This will scan the installed packages db and analyse the + keywords used for installation and produce a report on them. + """ + system_keywords = portage.settings["ACCEPT_KEYWORDS"].split() + output = RebuildPrinter( + "keywords", self.options["pretend"], self.options["exact"], + self.options['slot']) + arch = portage.settings["ARCH"] + if self.options["prefix"]: + # build a new keyword for testing + system_keywords = "~" + arch + "-linux" + if self.options["verbose"] or self.options["prefix"]: + print("Current system ARCH =", arch) + print("Current system ACCEPT_KEYWORDS =", system_keywords) + self.analyser = KeywordAnalyser( arch, system_keywords, VARDB) + #self.analyser.set_order(portage.settings["USE"].split()) + # only for testing + test_use = portage.settings["USE"].split() + if self.options['prefix'] and 'prefix' not in test_use: + print("REBUILD_KEYWORDS() 'prefix' flag not found in system", + "USE flags!!! appending for testing") + print() + test_use.append('prefix') + self.analyser.set_order(test_use) + # /end testing + + cpvs = VARDB.cpv_all() + #print "Total number of installed ebuilds =", len(cpvs) + pkgs = cpv_all_diff_keywords( + cpvs=cpvs, + system_keywords=system_keywords, + use_portage=self.options['portage'], + analyser = self.analyser + ) + #print([pkgs[p][0].cpv for p in pkgs]) + if pkgs: + pkg_keys = sorted(pkgs) + #print(len(pkgs)) + if self.options["pretend"] and not self.options["quiet"]: + print() + print(pp.globaloption( + " -- These are the installed packages & keywords " + + "that were detected")) + print(pp.globaloption(" to need keyword settings other " + + "than the defaults.")) + print() + elif not self.options["quiet"]: + print(" -- preparing pkgs for file entries") + for pkg in pkg_keys: + output(pkg, pkgs[pkg]) + if not self.options['quiet']: + if self.analyser.mismatched: + print("_________________________________________________") + print(("The following packages were found to have a \n" + + "different recorded ARCH than the current system ARCH")) + for cpv in self.analyser.mismatched: + print("\t", pp.cpv(cpv)) + print("===================================================") + print("Total number of entries in report =", + pp.output.red(str(len(pkg_keys)))) + if self.options["verbose"]: + print("Total number of installed ebuilds =", + pp.output.red(str(len(cpvs)))) + print() + if not self.options["pretend"]: + filepath = os.path.expanduser('~/package.keywords.test') + self.save_file(filepath, output.lines) + def rebuild_unmask(self): print("Module action not yet available") -- 2.26.2