UseManager: make warnings show even with --quiet
[portage.git] / pym / portage / package / ebuild / _config / UseManager.py
1 # Copyright 2010 Gentoo Foundation
2 # Distributed under the terms of the GNU General Public License v2
3
4 __all__ = (
5         'UseManager',
6 )
7
8 from portage import os
9 from portage.dep import ExtendedAtomDict, remove_slot, _get_useflag_re
10 from portage.localization import _
11 from portage.util import grabfile, grabdict_package, read_corresponding_eapi_file, stack_lists, writemsg
12 from portage.versions import cpv_getkey
13
14 from portage.package.ebuild._config.helper import ordered_by_atom_specificity
15
16 class UseManager(object):
17
18         def __init__(self, profiles, abs_user_config, user_config=True):
19                 #       file                            variable
20                 #--------------------------------
21                 #       profiles
22                 #--------------------------------
23                 #       use.mask                        _usemask_list
24                 #       use.force                       _useforce_list
25                 #       package.use.mask                _pusemask_list
26                 #       package.use                     _pkgprofileuse
27                 #       package.use.force               _puseforce_list
28                 #--------------------------------
29                 #       user config
30                 #--------------------------------
31                 #       package.use                     _pusedict       
32
33                 # Dynamic variables tracked by the config class
34                 #--------------------------------
35                 #       profiles
36                 #--------------------------------
37                 #       usemask
38                 #       useforce
39                 #--------------------------------
40                 #       user config
41                 #--------------------------------
42                 #       puse
43
44                 self._usemask_list = self._parse_profile_files_to_tuple("use.mask", profiles)
45                 self._useforce_list = self._parse_profile_files_to_tuple("use.force", profiles)
46                 self._pusemask_list = self._parse_profile_files_to_dict("package.use.mask", profiles)
47                 self._pkgprofileuse = self._parse_profile_files_to_dict("package.use", profiles, juststrings=True)
48                 self._puseforce_list = self._parse_profile_files_to_dict("package.use.force", profiles)
49
50                 self._pusedict = self._parse_user_files_to_extatomdict("package.use", abs_user_config, user_config)
51
52         def _parse_user_files_to_extatomdict(self, file_name, location, user_config):
53                 ret = ExtendedAtomDict(dict)
54                 if user_config:
55                         pusedict = grabdict_package(
56                                 os.path.join(location, file_name), recursive=1, allow_wildcard=True, allow_repo=True, verify_eapi=False)
57                         for k, v in pusedict.items():
58                                 ret.setdefault(k.cp, {})[k] = tuple(v)
59
60                 return ret
61
62         def _parse_profile_files_to_tuple(self, file_name, locations):
63                 ret = []
64                 for profile in locations:
65                         profile_lines = []
66                         path = os.path.join(profile, file_name)
67                         lines = grabfile(path, recursive=1)
68                         eapi = read_corresponding_eapi_file(path)
69                         useflag_re = _get_useflag_re(eapi)
70                         for prefixed_useflag in lines:
71                                 if prefixed_useflag[:1] == "-":
72                                         useflag = prefixed_useflag[1:]
73                                 else:
74                                         useflag = prefixed_useflag
75                                 if useflag_re.match(useflag) is None:
76                                         writemsg(_("--- Invalid USE flag in '%s': '%s'\n") % \
77                                                 (path, prefixed_useflag), noiselevel=-1)
78                                 else:
79                                         profile_lines.append(prefixed_useflag)
80                         ret.append(tuple(profile_lines))
81                 return tuple(ret)
82
83         def _parse_profile_files_to_dict(self, file_name, locations, juststrings=False):
84                 ret = []
85                 for profile in locations:
86                         profile_dict = {}
87                         cpdict = {}
88                         path = os.path.join(profile, file_name)
89                         file_dict = grabdict_package(path, recursive=1, verify_eapi=True)
90                         eapi = read_corresponding_eapi_file(path)
91                         useflag_re = _get_useflag_re(eapi)
92                         for k, v in file_dict.items():
93                                 useflags = []
94                                 for prefixed_useflag in v:
95                                         if prefixed_useflag[:1] == "-":
96                                                 useflag = prefixed_useflag[1:]
97                                         else:
98                                                 useflag = prefixed_useflag
99                                         if useflag_re.match(useflag) is None:
100                                                 writemsg(_("--- Invalid USE flag for '%s' in '%s': '%s'\n") % \
101                                                         (k, path, prefixed_useflag), noiselevel=-1)
102                                         else:
103                                                 useflags.append(prefixed_useflag)
104                                 profile_dict.setdefault(k, []).extend(useflags)
105                         for k, v in profile_dict.items():
106                                 if juststrings:
107                                         v = " ".join(v)
108                                 else:
109                                         v = tuple(v)
110                                 cpdict.setdefault(k.cp, {})[k] = v
111                         ret.append(cpdict)
112                 return tuple(ret)
113
114         def getUseMask(self, pkg=None):
115                 if pkg is None:
116                         return frozenset(stack_lists(
117                                 self._usemask_list, incremental=True))
118
119                 cp = getattr(pkg, "cp", None)
120                 if cp is None:
121                         cp = cpv_getkey(remove_slot(pkg))
122                 usemask = []
123                 for i, pusemask_dict in enumerate(self._pusemask_list):
124                         if self._usemask_list[i]:
125                                 usemask.append(self._usemask_list[i])
126                         cpdict = pusemask_dict.get(cp)
127                         if cpdict:
128                                 pkg_usemask = ordered_by_atom_specificity(cpdict, pkg)
129                                 if pkg_usemask:
130                                         usemask.extend(pkg_usemask)
131                 return frozenset(stack_lists(usemask, incremental=True))
132
133         def getUseForce(self, pkg=None):
134                 if pkg is None:
135                         return frozenset(stack_lists(
136                                 self._useforce_list, incremental=True))
137
138                 cp = getattr(pkg, "cp", None)
139                 if cp is None:
140                         cp = cpv_getkey(remove_slot(pkg))
141                 useforce = []
142                 for i, puseforce_dict in enumerate(self._puseforce_list):
143                         if self._useforce_list[i]:
144                                 useforce.append(self._useforce_list[i])
145                         cpdict = puseforce_dict.get(cp)
146                         if cpdict:
147                                 pkg_useforce = ordered_by_atom_specificity(cpdict, pkg)
148                                 if pkg_useforce:
149                                         useforce.extend(pkg_useforce)
150                 return frozenset(stack_lists(useforce, incremental=True))
151
152         def getPUSE(self, pkg):
153                 cp = getattr(pkg, "cp", None)
154                 if cp is None:
155                         cp = cpv_getkey(remove_slot(pkg))
156                 ret = ""
157                 cpdict = self._pusedict.get(cp)
158                 if cpdict:
159                         puse_matches = ordered_by_atom_specificity(cpdict, pkg)
160                         if puse_matches:
161                                 puse_list = []
162                                 for x in puse_matches:
163                                         puse_list.extend(x)
164                                 ret = " ".join(puse_list)
165                 return ret
166
167         def extract_global_USE_changes(self, old=""):
168                 ret = old
169                 cpdict = self._pusedict.get("*/*")
170                 if cpdict is not None:
171                         v = cpdict.pop("*/*", None)
172                         if v is not None:
173                                 ret = " ".join(v)
174                                 if old:
175                                         ret = old + " " + ret
176                                 if not cpdict:
177                                         #No tokens left in atom_license_map, remove it.
178                                         del self._pusedict["*/*"]
179                 return ret