3 # Copyright 2010 Brian Dolbec <brian.dolbec@gmail.com>
4 # Copyright(c) 2010, Gentoo Foundation
5 # Distributed under the terms of the GNU General Public License v2
9 """Provides a rebuild file of USE flags or keywords used and by
10 what packages according to the Installed package database"""
12 from __future__ import print_function
15 # Move to Imports section after Python 2.6 is stable
20 from portage import os
23 from gentoolkit.dbapi import PORTDB, VARDB
24 from gentoolkit.analyse.base import ModuleBase
25 from gentoolkit import pprinter as pp
26 from gentoolkit.analyse.lib import (get_installed_use, get_flags,
27 abs_flag, abs_list, FlagAnalyzer)
28 from gentoolkit.analyse.output import RebuildPrinter
36 # override-able for testing
38 _get_used=get_installed_use
41 cpvs = VARDB.cpv_all()
44 # pass them in to override for tests
45 flags = FlagAnalyzer(system_flags,
46 _get_flags=_get_flags,
47 _get_used=get_installed_use
50 plus, minus, unset = flags.analyse_cpv(cpv)
54 data[cpv] = list(plus)
58 class Rebuild(ModuleBase):
59 """Installed db analysis tool to query the installed databse
60 and produce/output stats for USE flags or keywords/mask.
61 The 'rebuild' action output is in the form suitable for file type output
62 to create a new package.use, package.keywords, package.unmask
63 type files in the event of needing to rebuild the
64 /etc/portage/* user configs
67 ModuleBase.__init__(self)
68 self.module_name = "rebuild"
80 "-p": ("pretend", "boolean", True),
81 "--pretend": ("pretend", "boolean", True),
82 "-e": ("exact", "boolean", True),
83 "--exact": ("exact", "boolean", True),
84 "-v": ("verbose", "boolean", True),
85 "--verbose": ("verbose", "boolean", True),
87 self.formatted_options = [
88 (" -h, --help", "Outputs this useage message"),
89 (" -p, --pretend", "Does not actually create the files."),
90 (" ", "It directs the outputs to the screen"),
91 (" -e, --exact", "will atomize the package with a"),
92 (" ", "leading '=' and include the version")
94 self.formatted_args = [
96 "causes the action to analyse the installed packages USE flags"),
98 "causes the action to analyse the installed packages keywords"),
100 "causes the action to analyse the installed packages " + \
101 "current mask status")
103 self.short_opts = "hepv"
104 self.long_opts = ("help", "exact", "pretend", "verbose")
105 self.need_queries = True
106 self.arg_spec = "TargetSpec"
107 self.arg_options = ['use', 'keywords', 'unmask']
108 self.arg_option = False
112 def run(self, input_args, quiet=False):
115 @param input_args: input arguments to be parsed
117 self.options['quiet'] = quiet
118 query = self.main_setup(input_args)
119 query = self.validate_query(query)
122 elif query in ["keywords"]:
123 self.rebuild_keywords()
124 elif query in ["mask"]:
128 def rebuild_use(self):
129 if not self.options["quiet"]:
131 print(" -- Scanning installed packages for USE flag settings that")
132 print(" do not match the default settings")
133 system_use = portage.settings["USE"].split()
134 output = RebuildPrinter("use", self.options["pretend"], self.options["exact"])
135 pkgs = cpv_all_diff_use(system_flags=system_use)
136 pkg_count = len(pkgs)
137 if self.options["verbose"]:
139 print((pp.emph(" -- Found ") + pp.number(str(pkg_count)) +
140 pp.emph(" packages that need entries")))
141 #print pp.emph(" package.use to maintain their current setting")
143 pkg_keys = list(pkgs.keys())
146 if self.options["pretend"] and not self.options["quiet"]:
148 print(pp.globaloption(
149 " -- These are the installed packages & flags " +
150 "that were detected"))
151 print(pp.globaloption(" to need flag settings other " +
152 "than the defaults."))
154 elif not self.options["quiet"]:
155 print(" -- preparing pkgs for file entries")
159 if self.options['verbose']:
160 flag_count += len(pkgs[pkg])
161 unique_flags.update(abs_list(pkgs[pkg]))
162 output(pkg, pkgs[pkg])
163 if self.options['verbose']:
164 message = (pp.emph(" ") +
165 pp.number(str(len(unique_flags))) +
166 pp.emph(" unique flags\n") + " " +
167 pp.number(str(flag_count))+
168 pp.emph(" flag entries\n") + " " +
169 pp.number(str(pkg_count)) +
170 pp.emph(" different packages"))
172 print(pp.globaloption(" -- Totals"))
175 #unique = list(unique_flags)
178 if not self.options["pretend"]:
179 filepath = os.path.expanduser('~/package.use.test')
180 self.save_file(filepath, output.use_lines)
182 def rebuild_keywords(self):
183 print("Module action not yet available")
186 def rebuild_mask(self):
187 print("Module action not yet available")
191 def save_file(self, filepath, data):
192 """Writes the data to the file determined by filepath
194 @param filepath: string. eg. '/path/to/filename'
195 @param data: list of lines to write to filepath
197 if not self.options["quiet"]:
198 print(' - Saving file: %s' %filepath)
199 #print "Just kidding :) I haven't codded it yet"
200 with open(filepath, "w") as output:
201 output.write('\n'.join(data))
205 def main(input_args):
206 """Common starting method by the analyse master
207 unless all modules are converted to this class method.
209 @param input_args: input args as supplied by equery master module.
211 query_module = Rebuild()
212 query_module.run(input_args, gentoolkit.CONFIG['quiet'])
214 # vim: set ts=4 sw=4 tw=79: