1 # Copyright 2010-2011 Gentoo Foundation
2 # Distributed under the terms of the GNU General Public License v2
8 from _emerge.Package import Package
10 from portage.dep import ExtendedAtomDict, remove_slot, _get_useflag_re
11 from portage.localization import _
12 from portage.util import grabfile, grabdict_package, read_corresponding_eapi_file, stack_lists, writemsg
13 from portage.versions import cpv_getkey
15 from portage.package.ebuild._config.helper import ordered_by_atom_specificity
17 class UseManager(object):
19 def __init__(self, repositories, profiles, abs_user_config, user_config=True):
21 #--------------------------------
23 #--------------------------------
24 # use.mask _repo_usemask_dict
25 # use.force _repo_useforce_dict
26 # package.use.mask _repo_pusemask_dict
27 # package.use.force _repo_puseforce_dict
28 #--------------------------------
30 #--------------------------------
31 # use.mask _usemask_list
32 # use.force _useforce_list
33 # package.use.mask _pusemask_list
34 # package.use _pkgprofileuse
35 # package.use.force _puseforce_list
36 #--------------------------------
38 #--------------------------------
39 # package.use _pusedict
41 # Dynamic variables tracked by the config class
42 #--------------------------------
44 #--------------------------------
47 #--------------------------------
49 #--------------------------------
52 self._repo_usemask_dict = self._parse_repository_files_to_dict_of_tuples("use.mask", repositories)
53 self._repo_useforce_dict = self._parse_repository_files_to_dict_of_tuples("use.force", repositories)
54 self._repo_pusemask_dict = self._parse_repository_files_to_dict_of_dicts("package.use.mask", repositories)
55 self._repo_puseforce_dict = self._parse_repository_files_to_dict_of_dicts("package.use.force", repositories)
56 self._repo_puse_dict = self._parse_repository_files_to_dict_of_dicts("package.use", repositories)
58 self._usemask_list = self._parse_profile_files_to_tuple_of_tuples("use.mask", profiles)
59 self._useforce_list = self._parse_profile_files_to_tuple_of_tuples("use.force", profiles)
60 self._pusemask_list = self._parse_profile_files_to_tuple_of_dicts("package.use.mask", profiles)
61 self._pkgprofileuse = self._parse_profile_files_to_tuple_of_dicts("package.use", profiles, juststrings=True)
62 self._puseforce_list = self._parse_profile_files_to_tuple_of_dicts("package.use.force", profiles)
64 self._pusedict = self._parse_user_files_to_extatomdict("package.use", abs_user_config, user_config)
66 self.repositories = repositories
68 def _parse_file_to_tuple(self, file_name, recursive=True):
70 lines = grabfile(file_name, recursive=recursive)
71 eapi = read_corresponding_eapi_file(file_name)
72 useflag_re = _get_useflag_re(eapi)
73 for prefixed_useflag in lines:
74 if prefixed_useflag[:1] == "-":
75 useflag = prefixed_useflag[1:]
77 useflag = prefixed_useflag
78 if useflag_re.match(useflag) is None:
79 writemsg(_("--- Invalid USE flag in '%s': '%s'\n") %
80 (file_name, prefixed_useflag), noiselevel=-1)
82 ret.append(prefixed_useflag)
85 def _parse_file_to_dict(self, file_name, juststrings=False, recursive=True):
88 file_dict = grabdict_package(file_name, recursive=recursive, verify_eapi=True)
89 eapi = read_corresponding_eapi_file(file_name)
90 useflag_re = _get_useflag_re(eapi)
91 for k, v in file_dict.items():
93 for prefixed_useflag in v:
94 if prefixed_useflag[:1] == "-":
95 useflag = prefixed_useflag[1:]
97 useflag = prefixed_useflag
98 if useflag_re.match(useflag) is None:
99 writemsg(_("--- Invalid USE flag for '%s' in '%s': '%s'\n") %
100 (k, file_name, prefixed_useflag), noiselevel=-1)
102 useflags.append(prefixed_useflag)
103 location_dict.setdefault(k, []).extend(useflags)
104 for k, v in location_dict.items():
109 ret.setdefault(k.cp, {})[k] = v
112 def _parse_user_files_to_extatomdict(self, file_name, location, user_config):
113 ret = ExtendedAtomDict(dict)
115 pusedict = grabdict_package(
116 os.path.join(location, file_name), recursive=1, allow_wildcard=True, allow_repo=True, verify_eapi=False)
117 for k, v in pusedict.items():
118 ret.setdefault(k.cp, {})[k] = tuple(v)
122 def _parse_repository_files_to_dict_of_tuples(self, file_name, repositories):
124 for repo in repositories.repos_with_profiles():
125 ret[repo.name] = self._parse_file_to_tuple(os.path.join(repo.location, "profiles", file_name))
128 def _parse_repository_files_to_dict_of_dicts(self, file_name, repositories):
130 for repo in repositories.repos_with_profiles():
131 ret[repo.name] = self._parse_file_to_dict(os.path.join(repo.location, "profiles", file_name))
134 def _parse_profile_files_to_tuple_of_tuples(self, file_name, locations):
135 return tuple(self._parse_file_to_tuple(os.path.join(profile[0], file_name), recursive=profile[1])
136 for profile in locations)
138 def _parse_profile_files_to_tuple_of_dicts(self, file_name, locations, juststrings=False):
139 return tuple(self._parse_file_to_dict(os.path.join(profile[0], file_name), juststrings, recursive=profile[1])
140 for profile in locations)
142 def getUseMask(self, pkg=None):
144 return frozenset(stack_lists(
145 self._usemask_list, incremental=True))
147 cp = getattr(pkg, "cp", None)
149 cp = cpv_getkey(remove_slot(pkg))
151 if hasattr(pkg, "repo") and pkg.repo != Package.UNKNOWN_REPO:
154 repos.extend(repo.name for repo in
155 self.repositories[pkg.repo].masters)
158 repos.append(pkg.repo)
160 usemask.append(self._repo_usemask_dict.get(repo, {}))
161 cpdict = self._repo_pusemask_dict.get(repo, {}).get(cp)
163 pkg_usemask = ordered_by_atom_specificity(cpdict, pkg)
165 usemask.extend(pkg_usemask)
166 for i, pusemask_dict in enumerate(self._pusemask_list):
167 if self._usemask_list[i]:
168 usemask.append(self._usemask_list[i])
169 cpdict = pusemask_dict.get(cp)
171 pkg_usemask = ordered_by_atom_specificity(cpdict, pkg)
173 usemask.extend(pkg_usemask)
174 return frozenset(stack_lists(usemask, incremental=True))
176 def getUseForce(self, pkg=None):
178 return frozenset(stack_lists(
179 self._useforce_list, incremental=True))
181 cp = getattr(pkg, "cp", None)
183 cp = cpv_getkey(remove_slot(pkg))
185 if hasattr(pkg, "repo") and pkg.repo != Package.UNKNOWN_REPO:
188 repos.extend(repo.name for repo in
189 self.repositories[pkg.repo].masters)
192 repos.append(pkg.repo)
194 useforce.append(self._repo_useforce_dict.get(repo, {}))
195 cpdict = self._repo_puseforce_dict.get(repo, {}).get(cp)
197 pkg_useforce = ordered_by_atom_specificity(cpdict, pkg)
199 useforce.extend(pkg_useforce)
200 for i, puseforce_dict in enumerate(self._puseforce_list):
201 if self._useforce_list[i]:
202 useforce.append(self._useforce_list[i])
203 cpdict = puseforce_dict.get(cp)
205 pkg_useforce = ordered_by_atom_specificity(cpdict, pkg)
207 useforce.extend(pkg_useforce)
208 return frozenset(stack_lists(useforce, incremental=True))
210 def getPUSE(self, pkg):
211 cp = getattr(pkg, "cp", None)
213 cp = cpv_getkey(remove_slot(pkg))
215 cpdict = self._pusedict.get(cp)
217 puse_matches = ordered_by_atom_specificity(cpdict, pkg)
220 for x in puse_matches:
222 ret = " ".join(puse_list)
225 def extract_global_USE_changes(self, old=""):
227 cpdict = self._pusedict.get("*/*")
228 if cpdict is not None:
229 v = cpdict.pop("*/*", None)
233 ret = old + " " + ret
235 #No tokens left in atom_license_map, remove it.
236 del self._pusedict["*/*"]