1 # Copyright 2010 Gentoo Foundation
2 # Distributed under the terms of the GNU General Public License v2
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
14 from portage.package.ebuild._config.helper import ordered_by_atom_specificity
16 class UseManager(object):
18 def __init__(self, profiles, abs_user_config, user_config=True):
20 #--------------------------------
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 #--------------------------------
30 #--------------------------------
31 # package.use _pusedict
33 # Dynamic variables tracked by the config class
34 #--------------------------------
36 #--------------------------------
39 #--------------------------------
41 #--------------------------------
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)
50 self._pusedict = self._parse_user_files_to_extatomdict("package.use", abs_user_config, user_config)
52 def _parse_user_files_to_extatomdict(self, file_name, location, user_config):
53 ret = ExtendedAtomDict(dict)
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)
62 def _parse_profile_files_to_tuple(self, file_name, locations):
64 for profile in locations:
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:]
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)
79 profile_lines.append(prefixed_useflag)
80 ret.append(tuple(profile_lines))
83 def _parse_profile_files_to_dict(self, file_name, locations, juststrings=False):
85 for profile in locations:
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():
94 for prefixed_useflag in v:
95 if prefixed_useflag[:1] == "-":
96 useflag = prefixed_useflag[1:]
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)
103 useflags.append(prefixed_useflag)
104 profile_dict.setdefault(k, []).extend(useflags)
105 for k, v in profile_dict.items():
110 cpdict.setdefault(k.cp, {})[k] = v
114 def getUseMask(self, pkg=None):
116 return frozenset(stack_lists(
117 self._usemask_list, incremental=True))
119 cp = getattr(pkg, "cp", None)
121 cp = cpv_getkey(remove_slot(pkg))
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)
128 pkg_usemask = ordered_by_atom_specificity(cpdict, pkg)
130 usemask.extend(pkg_usemask)
131 return frozenset(stack_lists(usemask, incremental=True))
133 def getUseForce(self, pkg=None):
135 return frozenset(stack_lists(
136 self._useforce_list, incremental=True))
138 cp = getattr(pkg, "cp", None)
140 cp = cpv_getkey(remove_slot(pkg))
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)
147 pkg_useforce = ordered_by_atom_specificity(cpdict, pkg)
149 useforce.extend(pkg_useforce)
150 return frozenset(stack_lists(useforce, incremental=True))
152 def getPUSE(self, pkg):
153 cp = getattr(pkg, "cp", None)
155 cp = cpv_getkey(remove_slot(pkg))
157 cpdict = self._pusedict.get(cp)
159 puse_matches = ordered_by_atom_specificity(cpdict, pkg)
162 for x in puse_matches:
164 ret = " ".join(puse_list)
167 def extract_global_USE_changes(self, old=""):
169 cpdict = self._pusedict.get("*/*")
170 if cpdict is not None:
171 v = cpdict.pop("*/*", None)
175 ret = old + " " + ret
177 #No tokens left in atom_license_map, remove it.
178 del self._pusedict["*/*"]