1 # Copyright(c) 2009, Gentoo Foundation
3 # Licensed under the GNU General Public License, v2
7 """Display USE flags for a given package"""
9 from __future__ import print_function
11 __docformat__ = 'epytext'
19 from functools import partial
20 from getopt import gnu_getopt, GetoptError
23 from portage import settings
25 import gentoolkit.pprinter as pp
26 from gentoolkit import errors
27 from gentoolkit.equery import format_options, mod_usage, CONFIG
28 from gentoolkit.helpers import uniqify
29 from gentoolkit.textwrap_ import TextWrapper
30 from gentoolkit.query import Query
36 QUERY_OPTS = {"all_versions" : False}
42 def print_help(with_description=True):
43 """Print description, usage and a detailed help message.
45 @type with_description: bool
46 @param with_description: if true, print module's __doc__ string
50 print(__doc__.strip())
52 print(mod_usage(mod_name=__name__.split('.')[-1]))
54 print(pp.command("options"))
55 print(format_options((
56 (" -h, --help", "display this help message"),
57 (" -a, --all", "include all package versions")
61 def display_useflags(output):
62 """Print USE flag descriptions and statuses.
65 @param output: [(inuse, inused, flag, desc, restrict), ...]
66 inuse (int) = 0 or 1; if 1, flag is set in make.conf
67 inused (int) = 0 or 1; if 1, package is installed with flag enabled
68 flag (str) = the name of the USE flag
69 desc (str) = the flag's description
70 restrict (str) = corresponds to the text of restrict in metadata
73 maxflag_len = len(max([t[2] for t in output], key=len))
76 twrap.width = CONFIG['termWidth']
77 twrap.subsequent_indent = " " * (maxflag_len + 8)
81 partial(pp.useflag, enabled=False), partial(pp.useflag, enabled=True)
83 for in_makeconf, in_installed, flag, desc, restrict in output:
86 if in_makeconf != in_installed:
87 flag_name += pp.emph(" %s %s" %
88 (markers[in_makeconf], markers[in_installed]))
90 flag_name += (" %s %s" %
91 (markers[in_makeconf], markers[in_installed]))
93 flag_name += " " + color[in_makeconf](flag.ljust(maxflag_len))
98 restrict = "(%s %s)" % (pp.emph("Restricted to"),
100 twrap.initial_indent = flag_name
101 pp.uprint(twrap.fill(restrict))
103 twrap.initial_indent = twrap.subsequent_indent
104 pp.uprint(twrap.fill(desc))
106 print(" : <unknown>")
109 twrap.initial_indent = flag_name
110 desc = twrap.fill(desc)
113 twrap.initial_indent = flag_name
114 print(twrap.fill("<unknown>"))
116 pp.uprint(markers[in_makeconf] + flag)
119 def get_global_useflags():
120 """Get global and expanded USE flag variables from
121 PORTDIR/profiles/use.desc and PORTDIR/profiles/desc/*.desc respectively.
124 @return: {'flag_name': 'flag description', ...}
128 # Get global USE flag descriptions
130 path = os.path.join(settings["PORTDIR"], 'profiles', 'use.desc')
131 with open(path) as open_file:
132 for line in open_file:
133 if line.startswith('#'):
135 # Ex. of fields: ['syslog', 'Enables support for syslog\n']
136 fields = line.split(" - ", 1)
138 global_usedesc[fields[0]] = fields[1].rstrip()
142 "Could not load USE flag descriptions from %s" % pp.path(path)
147 # Add USE_EXPANDED variables to usedesc hash -- Bug #238005
148 for path in glob(os.path.join(settings["PORTDIR"],
149 'profiles', 'desc', '*.desc')):
151 with open(path) as open_file:
152 for line in open_file:
153 if line.startswith('#'):
155 fields = [field.strip() for field in line.split(" - ", 1)]
157 expanded_useflag = "%s_%s" % \
158 (path.split("/")[-1][0:-5], fields[0])
159 global_usedesc[expanded_useflag] = fields[1]
162 pp.warn("Could not load USE flag descriptions from %s" % path)
165 return global_usedesc
168 def get_output_descriptions(pkg, global_usedesc):
169 """Prepare descriptions and usage information for each USE flag."""
171 if pkg.metadata is None:
174 local_usedesc = pkg.metadata.use()
175 iuse = pkg.environment("IUSE")
178 usevar = uniqify([x.lstrip('+-') for x in iuse.split()])
183 if pkg.is_installed():
184 used_flags = pkg.use().split()
186 used_flags = settings["USE"].split()
188 # store (inuse, inused, flag, desc, restrict)
195 for use in local_usedesc:
201 desc = local_use.description
202 except AttributeError:
204 desc = global_usedesc[flag]
209 restrict = local_use.restrict
210 restrict = restrict if restrict is not None else ""
211 except AttributeError:
214 if flag in pkg.settings("USE").split():
216 if flag in used_flags:
219 output.append((inuse, inused, flag, desc, restrict))
224 def parse_module_options(module_opts):
225 """Parse module options and update QUERY_OPTS"""
227 opts = (x[0] for x in module_opts)
229 if opt in ('-h', '--help'):
232 elif opt in ('-a', '--all'):
233 QUERY_OPTS['all_versions'] = True
237 """Print a legend to explain the output format."""
239 print("[ Legend : %s - flag is set in make.conf ]" % pp.emph("U"))
240 print("[ : %s - package is installed with flag ]" % pp.emph("I"))
241 print("[ Colors : %s, %s ]" % (
242 pp.useflag("set", enabled=True), pp.useflag("unset", enabled=False)))
245 def main(input_args):
246 """Parse input and run the program"""
249 long_opts = ('help', 'all')
252 module_opts, queries = gnu_getopt(input_args, short_opts, long_opts)
253 except GetoptError as err:
254 sys.stderr.write(pp.error("Module %s" % err))
256 print_help(with_description=False)
259 parse_module_options(module_opts)
270 legend_printed = False
271 for query in (Query(x) for x in queries):
275 if QUERY_OPTS["all_versions"]:
276 matches = query.find(include_masked=True)
278 matches = [query.find_best()]
281 raise errors.GentoolkitNoMatches(query)
285 global_usedesc = get_global_useflags()
288 output = get_output_descriptions(pkg, global_usedesc)
290 if CONFIG['verbose']:
291 if not legend_printed:
293 legend_printed = True
294 print((" * Found these USE flags for %s:" %
295 pp.cpv(str(pkg.cpv))))
296 print(pp.emph(" U I"))
297 display_useflags(output)
299 if CONFIG['verbose']:
301 pp.warn("No USE flags found for %s" % pp.cpv(pkg.cpv))
306 # vim: set ts=4 sw=4 tw=79: