diff options
Diffstat (limited to 'pym/gentoolkit/analyse')
-rw-r--r-- | pym/gentoolkit/analyse/__init__.py | 6 | ||||
-rw-r--r-- | pym/gentoolkit/analyse/analyse.py | 77 | ||||
-rw-r--r-- | pym/gentoolkit/analyse/base.py | 8 | ||||
-rw-r--r-- | pym/gentoolkit/analyse/lib.py | 57 | ||||
-rw-r--r-- | pym/gentoolkit/analyse/rebuild.py | 56 |
5 files changed, 128 insertions, 76 deletions
diff --git a/pym/gentoolkit/analyse/__init__.py b/pym/gentoolkit/analyse/__init__.py index 7a5fbec..82625b6 100644 --- a/pym/gentoolkit/analyse/__init__.py +++ b/pym/gentoolkit/analyse/__init__.py @@ -19,7 +19,7 @@ __version__ = "svn" __productname__ = "analyse" __authors__ = ( 'Brian Dolbec, <brian.dolbec@gmail.com>' - + ) # make an exportable copy of the info for help output @@ -29,7 +29,7 @@ MODULE_INFO = { "__version__": __version__, "__productname__": __productname__, "__authors__": __authors__ - + } import errno @@ -54,7 +54,7 @@ NAME_MAP = { } FORMATTED_OPTIONS = ( - (" (a)nalyse", + (" (a)nalyse", "analyses the installed PKG database USE flag or keyword useage"), (" (r)ebuild", "analyses the Installed PKG database and generates files suitable"), diff --git a/pym/gentoolkit/analyse/analyse.py b/pym/gentoolkit/analyse/analyse.py index 6797510..2162324 100644 --- a/pym/gentoolkit/analyse/analyse.py +++ b/pym/gentoolkit/analyse/analyse.py @@ -20,6 +20,7 @@ from gentoolkit.analyse.lib import (get_installed_use, get_iuse, abs_flag, abs_list, get_all_cpv_use, get_flags, FlagAnalyzer, KeywordAnalyser) from gentoolkit.analyse.output import nl, AnalysisPrinter from gentoolkit.package import Package +from gentoolkit.helpers import get_installed_cpvs import portage @@ -35,15 +36,31 @@ def gather_flags_info( _get_used=get_installed_use ): """Analyse the installed pkgs USE flags for frequency of use - + + @type cpvs: list @param cpvs: optional list of [cat/pkg-ver,...] to analyse or defaults to entire installed pkg db + @type: system_flags: list + @param system_flags: the current default USE flags as defined + by portage.settings["USE"].split() + @type include_unset: bool + @param include_unset: controls the inclusion of unset USE flags in the report. + @type target: string + @param target: the environment variable being analysed + one of ["USE", "PKGUSE"] + @type _get_flags: function + @param _get_flags: ovride-able for testing, + defaults to gentoolkit.analyse.lib.get_flags + @param _get_used: ovride-able for testing, + defaults to gentoolkit.analyse.lib.get_installed_use @rtype dict. {flag:{"+":[cat/pkg-ver,...], "-":[cat/pkg-ver,...], "unset":[]} """ if cpvs is None: cpvs = VARDB.cpv_all() # pass them in to override for tests flags = FlagAnalyzer(system_flags, + filter_defaults=False, + target=target, _get_flags=_get_flags, _get_used=get_installed_use ) @@ -87,7 +104,7 @@ def gather_keywords_info( analyser = None ): """Analyse the installed pkgs 'keywords' for frequency of use - + @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 @@ -139,7 +156,7 @@ class Analyse(ModuleBase): """Installed db analysis tool to query the installed databse and produce/output stats for USE flags or keywords/mask. The 'rebuild' action output is in the form suitable for file type output - to create a new package.use, package.keywords, package.unmask + to create a new package.use, package.keywords, package.unmask type files in the event of needing to rebuild the /etc/portage/* user configs """ @@ -153,7 +170,7 @@ class Analyse(ModuleBase): "verbose": False, "quiet": False, 'prefix': False, - 'portage': False + 'portage': True } self.module_opts = { "-f": ("flags", "boolean", True), @@ -166,8 +183,8 @@ class Analyse(ModuleBase): "--verbose": ("verbose", "boolean", True), "-p": ("prefix", "boolean", True), "--prefix": ("prefix", "boolean", True), - "-G": ("portage", "boolean", True), - "--portage": ("portage", "boolean", True), + "-G": ("portage", "boolean", False), + "--portage": ("portage", "boolean", False), } self.formatted_options = [ (" -h, --help", "Outputs this useage message"), @@ -177,17 +194,17 @@ class Analyse(ModuleBase): (" -u, --unset", "Additionally include any unset USE flags and the packages"), ("", "that could use them"), - (" -v, --verbose", + (" -v, --verbose", "Used in the analyse action to output more detailed information"), - (" -p, --prefix", + (" -p, --prefix", "Used for testing purposes only, runs report using " + "a prefix keyword and 'prefix' USE flag"), - (" -G, --portage", - "Use portage directly instead of gentoolkit's Package " + - "object for some operations. Usually a little faster."), + #(" -G, --portage", + #"Use portage directly instead of gentoolkit's Package " + + #"object for some operations. Usually a little faster."), ] self.formatted_args = [ - (" use", + (" use", "causes the action to analyse the installed packages USE flags"), (" pkguse", "causes the action to analyse the installed packages PKGUSE flags"), @@ -197,15 +214,21 @@ class Analyse(ModuleBase): "causes the action to analyse the installed packages keywords"), ] self.short_opts = "huvpG" - self.long_opts = ("help", "unset", "verbose", "prefix", "portage") + self.long_opts = ("help", "unset", "verbose", "prefix") #, "portage") self.need_queries = True self.arg_spec = "Target" self.arg_options = ['use', 'pkguse','keywords'] self.arg_option = False + self.warning = ( + " CAUTION", + "This is beta software and some features/options are incomplete,", + "some features may change in future releases includig its name.", + "Feedback will be appreciated, http://bugs.gentoo.org") + def run(self, input_args, quiet=False): """runs the module - + @param input_args: input arguments to be parsed """ query = self.main_setup(input_args) @@ -216,10 +239,10 @@ class Analyse(ModuleBase): self.analyse_keywords() def analyse_flags(self, target): - """This will scan the installed packages db and analyse the + """This will scan the installed packages db and analyse the USE flags used for installation and produce a report on how they were used. - + @type target: string @param target: the target to be analysed, one of ["use", "pkguse"] """ @@ -227,17 +250,18 @@ class Analyse(ModuleBase): self.printer = AnalysisPrinter("use", self.options["verbose"], system_use) if self.options["verbose"]: cpvs = VARDB.cpv_all() + #cpvs = get_installed_cpvs() #print "Total number of installed ebuilds =", len(cpvs) flag_users = gather_flags_info(cpvs, system_use, self.options["unset"], target=target.upper(), use_portage=self.options['portage']) else: - flag_users = gather_flags_info(system_flags=system_use, + cpvs = get_installed_cpvs() + flag_users = gather_flags_info(cpvs, system_flags=system_use, include_unset=self.options["unset"], target=target.upper(), use_portage=self.options['portage']) #print flag_users - flag_keys = list(flag_users.keys()) - flag_keys.sort() + flag_keys = sorted(flag_users) if self.options["verbose"]: print(" Flag System #pkgs cat/pkg-ver") blankline = nl @@ -261,12 +285,12 @@ class Analyse(ModuleBase): print("===================================================") print("Total number of flags in report =", pp.output.red(str(len(flag_keys)))) if self.options["verbose"]: - print("Total number of installed ebuilds =", pp.output.red(str(len(cpvs)))) + print("Total number of installed ebuilds =", pp.output.red(str(len([x for x in cpvs])))) print() def analyse_keywords(self, keywords=None): - """This will scan the installed packages db and analyse the + """This will scan the installed packages db and analyse the keywords used for installation and produce a report on them. """ print() @@ -295,7 +319,7 @@ class Analyse(ModuleBase): cpvs = VARDB.cpv_all() #print "Total number of installed ebuilds =", len(cpvs) keyword_users = gather_keywords_info( - cpvs=cpvs, + cpvs=cpvs, system_keywords=system_keywords, use_portage=self.options['portage'], keywords=keywords, analyser = self.analyser @@ -305,13 +329,12 @@ class Analyse(ModuleBase): keyword_users = gather_keywords_info( system_keywords=system_keywords, use_portage=self.options['portage'], - keywords=keywords, + keywords=keywords, analyser = self.analyser ) blankline = lambda: None #print keyword_users - keyword_keys = list(keyword_users.keys()) - keyword_keys.sort() + keyword_keys = sorted(keyword_users) if self.options["verbose"]: print(" Keyword System #pkgs cat/pkg-ver") elif not self.options['quiet']: @@ -344,9 +367,9 @@ class Analyse(ModuleBase): def main(input_args): - """Common starting method by the analyse master + """Common starting method by the analyse master unless all modules are converted to this class method. - + @param input_args: input args as supplied by equery master module. """ query_module = Analyse() diff --git a/pym/gentoolkit/analyse/base.py b/pym/gentoolkit/analyse/base.py index bb0a8bc..d45ccc6 100644 --- a/pym/gentoolkit/analyse/base.py +++ b/pym/gentoolkit/analyse/base.py @@ -28,7 +28,7 @@ from gentoolkit.base import mod_usage class ModuleBase(object): """Analyse base module class to parse module options print module help, etc..""" - + def __init__(self): self.module_name = None self.options = {} @@ -36,7 +36,7 @@ class ModuleBase(object): self.short_opts = None self.long_opts = None self.module_opts = {} - self.depwarning = None + self.warning = None self.need_queries = True @@ -51,9 +51,9 @@ class ModuleBase(object): print() print(__doc__.strip()) print() - if self.depwarning: + if self.warning: print() - for line in self.depwarning: + for line in self.warning: sys.stderr.write(pp.warn(line)) print() print(mod_usage(mod_name=self.module_name, arg=self.arg_spec, optional=self.arg_option)) diff --git a/pym/gentoolkit/analyse/lib.py b/pym/gentoolkit/analyse/lib.py index 17e2118..a32d13b 100644 --- a/pym/gentoolkit/analyse/lib.py +++ b/pym/gentoolkit/analyse/lib.py @@ -20,7 +20,7 @@ import portage def get_installed_use(cpv, use="USE"): """Gets the installed USE flags from the VARDB - + @type: cpv: string @param cpv: cat/pkg-ver @type use: string @@ -33,7 +33,7 @@ def get_installed_use(cpv, use="USE"): def get_iuse(cpv): """Gets the current IUSE flags from the tree - + @type: cpv: string @param cpv: cat/pkg-ver @rtype list @@ -47,7 +47,7 @@ def get_iuse(cpv): def abs_flag(flag): """Absolute value function for a USE flag - + @type flag: string @param flag: the use flag to absolute. @rtype: string @@ -61,7 +61,7 @@ def abs_flag(flag): def abs_list(the_list): """Absolute value function for a USE flag list - + @type the_list: list @param the_list: the use flags to absolute. @rtype: list @@ -76,7 +76,7 @@ def abs_list(the_list): def filter_flags(use, use_expand_hidden, usemasked, useforced): """Filter function to remove hidden or otherwise not normally visible USE flags from a list. - + @type use: list @param use: the USE flag list to be filtered. @type use_expand_hidden: list @@ -110,7 +110,7 @@ def filter_flags(use, use_expand_hidden, usemasked, useforced): def get_all_cpv_use(cpv): """Uses portage to determine final USE flags and settings for an emerge - + @type cpv: string @param cpv: eg cat/pkg-ver @rtype: lists @@ -137,7 +137,7 @@ def get_all_cpv_use(cpv): def get_flags(cpv, final_setting=False): """Retrieves all information needed to filter out hidded, masked, etc. USE flags for a given package. - + @type cpv: string @param cpv: eg. cat/pkg-ver @type final_setting: boolean @@ -158,7 +158,7 @@ class FlagAnalyzer(object): """Specialty functions for analysing an installed package's USE flags. Can be used for single or mulitple use without needing to be reset unless the system USE flags are changed. - + @type system: list or set @param system: the default system USE flags. @type _get_flags: function @@ -168,17 +168,21 @@ class FlagAnalyzer(object): """ def __init__(self, system, + filter_defaults=False, + target="USE", _get_flags=get_flags, _get_used=get_installed_use ): self.get_flags = _get_flags self.get_used = _get_used + self.filter_defaults = filter_defaults + self.target = target self.reset(system) def reset(self, system): """Resets the internal system USE flags and use_expand variables to the new setting. The use_expand variable is handled internally. - + @type system: list or set @param system: the default system USE flags. """ @@ -189,19 +193,19 @@ class FlagAnalyzer(object): """Gets all relavent USE flag info for a cpv and breaks them down into 3 sets, plus (package.use enabled), minus ( package.use disabled), unset. - + @param cpv: string. 'cat/pkg-ver' @rtype tuple of sets @return (plus, minus, unset) sets of USE flags """ - installed = set(self.get_used(cpv, "USE")) + installed = set(self.get_used(cpv, self.target)) iuse = set(abs_list(self.get_flags(cpv))) return self._analyse(installed, iuse) def _analyse(self, installed, iuse): """Analyses the supplied info and returns the flag settings that differ from the defaults - + @type installed: set @param installed: the installed with use flags @type iuse: set @@ -209,7 +213,10 @@ class FlagAnalyzer(object): """ defaults = self.system.intersection(iuse) usedflags = iuse.intersection(set(installed)) - plus = usedflags.difference(defaults) + if self.filter_defaults: + plus = usedflags.difference(defaults) + else: + plus = usedflags minus = defaults.difference(usedflags) unset = iuse.difference(defaults, plus, minus) cleaned = self.remove_expanding(unset) @@ -219,7 +226,7 @@ class FlagAnalyzer(object): """Gets all relevent USE flag info for a pkg and breaks them down into 3 sets, plus (package.use enabled), minus ( package.use disabled), unset. - + @param pkg: gentoolkit.package.Package object @rtype tuple of sets @return (plus, minus, unset) sets of USE flags @@ -229,7 +236,9 @@ class FlagAnalyzer(object): return self._analyse(installed, iuse) def pkg_used(self, pkg): - return pkg.use().split() + if self.target == "USE": + return pkg.use().split() + return pkg.environment(self.target).split() def pkg_flags(self, pkg): final_use, use_expand_hidden, usemasked, useforced = \ @@ -246,7 +255,7 @@ class FlagAnalyzer(object): def remove_expanding(self, flags): """Remove unwanted USE_EXPAND flags from unset IUSE sets - + @param flags: short list or set of USE flags @rtype set @return USE flags @@ -264,12 +273,12 @@ class FlagAnalyzer(object): class KeywordAnalyser(object): """Specialty functions for analysing the installed package db for keyword useage and the packages that used them. - + Note: should be initialized with the internal set_order() before use. See internal set_order() for more details. This class of functions can be used for single cpv checks or used repeatedly for an entire package db. - + @type arch: string @param arch: the system ARCH setting @type accept_keywords: list @@ -302,9 +311,9 @@ class KeywordAnalyser(object): self.mismatched = [] def determine_keyword(self, keywords, used, cpv): - """Determine the keyword from the installed USE flags and + """Determine the keyword from the installed USE flags and the KEYWORDS that was used to install a package. - + @param keywords: list of keywords available to install a pkg @param used: list of USE flalgs recorded for the installed pkg @rtype: string @@ -396,7 +405,7 @@ class KeywordAnalyser(object): def get_inst_keyword_cpv(self, cpv): """Determines the installed with keyword for cpv - + @type cpv: string @param cpv: an installed CAT/PKG-VER @rtype: string @@ -409,7 +418,7 @@ class KeywordAnalyser(object): def get_inst_keyword_pkg(self, pkg): """Determines the installed with keyword for cpv - + @param pkg: gentoolkit.package.Package object @rtype: string @returns a keyword determined to have been used to install cpv @@ -447,11 +456,11 @@ class KeywordAnalyser(object): def set_order(self, used): """Used to set the parsing order to determine a keyword used for installation. - + This is needed due to the way prefix arch's and keywords work with portage. It looks for the 'prefix' flag. A positive result sets it to the prefix order and keyword. - + @type used: list @param used: a list of pkg USE flags or the system USE flags""" if 'prefix' in used: diff --git a/pym/gentoolkit/analyse/rebuild.py b/pym/gentoolkit/analyse/rebuild.py index 31c00a1..c7cf1e5 100644 --- a/pym/gentoolkit/analyse/rebuild.py +++ b/pym/gentoolkit/analyse/rebuild.py @@ -9,16 +9,12 @@ """Provides a rebuild file of USE flags or keywords used and by what packages according to the Installed package database""" -from __future__ import print_function - -# Move to Imports section after Python 2.6 is stable +from __future__ import print_function import sys -from portage import os - import gentoolkit from gentoolkit.dbapi import PORTDB, VARDB from gentoolkit.analyse.base import ModuleBase @@ -28,6 +24,7 @@ from gentoolkit.analyse.lib import (get_installed_use, get_flags, from gentoolkit.analyse.output import RebuildPrinter import portage +from portage import os def cpv_all_diff_use( @@ -37,12 +34,31 @@ def cpv_all_diff_use( _get_flags=get_flags, _get_used=get_installed_use ): + """Data gathering and analysis function determines + the difference between the current default USE flag settings + and the currently installed pkgs recorded USE flag settings + + @type cpvs: list + @param cpvs: optional list of [cat/pkg-ver,...] to analyse or + defaults to entire installed pkg db + @type: system_flags: list + @param system_flags: the current default USE flags as defined + by portage.settings["USE"].split() + @type _get_flags: function + @param _get_flags: ovride-able for testing, + defaults to gentoolkit.analyse.lib.get_flags + @param _get_used: ovride-able for testing, + defaults to gentoolkit.analyse.lib.get_installed_use + @rtype dict. {cpv:['flag1', '-flag2',...]} + """ if cpvs is None: cpvs = VARDB.cpv_all() cpvs.sort() data = {} # pass them in to override for tests flags = FlagAnalyzer(system_flags, + filter_defaults=True, + target="USE", _get_flags=_get_flags, _get_used=get_installed_use ) @@ -59,7 +75,7 @@ class Rebuild(ModuleBase): """Installed db analysis tool to query the installed databse and produce/output stats for USE flags or keywords/mask. The 'rebuild' action output is in the form suitable for file type output - to create a new package.use, package.keywords, package.unmask + to create a new package.use, package.keywords, package.unmask type files in the event of needing to rebuild the /etc/portage/* user configs """ @@ -92,7 +108,7 @@ class Rebuild(ModuleBase): (" ", "leading '=' and include the version") ] self.formatted_args = [ - (" use", + (" use", "causes the action to analyse the installed packages USE flags"), (" keywords", "causes the action to analyse the installed packages keywords"), @@ -106,12 +122,18 @@ class Rebuild(ModuleBase): self.arg_spec = "TargetSpec" self.arg_options = ['use', 'keywords', 'unmask'] self.arg_option = False + self.warning = ( + " CAUTION", + "This is beta software and some features/options are incomplete,", + "some features may change in future releases includig its name.", + "The file generated is saved in your home directory", + "Feedback will be appreciated, http://bugs.gentoo.org") def run(self, input_args, quiet=False): """runs the module - + @param input_args: input arguments to be parsed """ self.options['quiet'] = quiet @@ -121,8 +143,8 @@ class Rebuild(ModuleBase): self.rebuild_use() elif query in ["keywords"]: self.rebuild_keywords() - elif query in ["mask"]: - self.rebuild_mask() + elif query in ["unmask"]: + self.rebuild_unmask() def rebuild_use(self): @@ -140,11 +162,10 @@ class Rebuild(ModuleBase): pp.emph(" packages that need entries"))) #print pp.emph(" package.use to maintain their current setting") if pkgs: - pkg_keys = list(pkgs.keys()) - pkg_keys.sort() + pkg_keys = sorted(pkgs) #print len(pkgs) if self.options["pretend"] and not self.options["quiet"]: - print() + print() print(pp.globaloption( " -- These are the installed packages & flags " + "that were detected")) @@ -183,29 +204,28 @@ class Rebuild(ModuleBase): print("Module action not yet available") print() - def rebuild_mask(self): + def rebuild_unmask(self): print("Module action not yet available") print() def save_file(self, filepath, data): """Writes the data to the file determined by filepath - + @param filepath: string. eg. '/path/to/filename' @param data: list of lines to write to filepath """ if not self.options["quiet"]: print(' - Saving file: %s' %filepath) - #print "Just kidding :) I haven't codded it yet" with open(filepath, "w") as output: output.write('\n'.join(data)) print(" - Done") def main(input_args): - """Common starting method by the analyse master + """Common starting method by the analyse master unless all modules are converted to this class method. - + @param input_args: input args as supplied by equery master module. """ query_module = Rebuild() |