Bug #370693: Support use.force, package.use.force, use.mask and
authorArfrever Frehtes Taifersar Arahesis <Arfrever@Gentoo.Org>
Sun, 19 Jun 2011 16:37:56 +0000 (18:37 +0200)
committerArfrever Frehtes Taifersar Arahesis <Arfrever@Gentoo.Org>
Sun, 19 Jun 2011 16:37:56 +0000 (18:37 +0200)
package.use.mask files in ${repository}/profiles.

pym/portage/package/ebuild/_config/UseManager.py
pym/portage/package/ebuild/config.py

index ae87b2f0dd6e7a4411189a00801a7f38d0ebea50..d9ca940b377f111b443e6b914aa6e80b67881001 100644 (file)
@@ -1,10 +1,11 @@
-# Copyright 2010 Gentoo Foundation
+# Copyright 2010-2011 Gentoo Foundation
 # Distributed under the terms of the GNU General Public License v2
 
 __all__ = (
        'UseManager',
 )
 
+from _emerge.Package import Package
 from portage import os
 from portage.dep import ExtendedAtomDict, remove_slot, _get_useflag_re
 from portage.localization import _
@@ -15,9 +16,16 @@ from portage.package.ebuild._config.helper import ordered_by_atom_specificity
 
 class UseManager(object):
 
-       def __init__(self, profiles, abs_user_config, user_config=True):
+       def __init__(self, repositories, profiles, abs_user_config, user_config=True):
                #       file                            variable
                #--------------------------------
+               #       repositories
+               #--------------------------------
+               #       use.mask                        _repo_usemask_dict
+               #       use.force                       _repo_useforce_dict
+               #       package.use.mask                _repo_pusemask_dict
+               #       package.use.force               _repo_puseforce_dict
+               #--------------------------------
                #       profiles
                #--------------------------------
                #       use.mask                        _usemask_list
@@ -41,13 +49,62 @@ class UseManager(object):
                #--------------------------------
                #       puse
 
-               self._usemask_list = self._parse_profile_files_to_tuple("use.mask", profiles)
-               self._useforce_list = self._parse_profile_files_to_tuple("use.force", profiles)
-               self._pusemask_list = self._parse_profile_files_to_dict("package.use.mask", profiles)
-               self._pkgprofileuse = self._parse_profile_files_to_dict("package.use", profiles, juststrings=True)
-               self._puseforce_list = self._parse_profile_files_to_dict("package.use.force", profiles)
+               self._repo_usemask_dict = self._parse_repository_files_to_dict_of_tuples("use.mask", repositories)
+               self._repo_useforce_dict = self._parse_repository_files_to_dict_of_tuples("use.force", repositories)
+               self._repo_pusemask_dict = self._parse_repository_files_to_dict_of_dicts("package.use.mask", repositories)
+               self._repo_puseforce_dict = self._parse_repository_files_to_dict_of_dicts("package.use.force", repositories)
+
+               self._usemask_list = self._parse_profile_files_to_tuple_of_tuples("use.mask", profiles)
+               self._useforce_list = self._parse_profile_files_to_tuple_of_tuples("use.force", profiles)
+               self._pusemask_list = self._parse_profile_files_to_tuple_of_dicts("package.use.mask", profiles)
+               self._pkgprofileuse = self._parse_profile_files_to_tuple_of_dicts("package.use", profiles, juststrings=True)
+               self._puseforce_list = self._parse_profile_files_to_tuple_of_dicts("package.use.force", profiles)
 
                self._pusedict = self._parse_user_files_to_extatomdict("package.use", abs_user_config, user_config)
+       
+       def _parse_file_to_tuple(self, file_name):
+               ret = []
+               lines = grabfile(file_name, recursive=1)
+               eapi = read_corresponding_eapi_file(file_name)
+               useflag_re = _get_useflag_re(eapi)
+               for prefixed_useflag in lines:
+                       if prefixed_useflag[:1] == "-":
+                               useflag = prefixed_useflag[1:]
+                       else:
+                               useflag = prefixed_useflag
+                       if useflag_re.match(useflag) is None:
+                               writemsg(_("--- Invalid USE flag in '%s': '%s'\n") %
+                                       (file_name, prefixed_useflag), noiselevel=-1)
+                       else:
+                               ret.append(prefixed_useflag)
+               return tuple(ret)
+
+       def _parse_file_to_dict(self, file_name, juststrings=False):
+               ret = {}
+               location_dict = {}
+               file_dict = grabdict_package(file_name, recursive=1, verify_eapi=True)
+               eapi = read_corresponding_eapi_file(file_name)
+               useflag_re = _get_useflag_re(eapi)
+               for k, v in file_dict.items():
+                       useflags = []
+                       for prefixed_useflag in v:
+                               if prefixed_useflag[:1] == "-":
+                                       useflag = prefixed_useflag[1:]
+                               else:
+                                       useflag = prefixed_useflag
+                               if useflag_re.match(useflag) is None:
+                                       writemsg(_("--- Invalid USE flag for '%s' in '%s': '%s'\n") %
+                                               (k, file_name, prefixed_useflag), noiselevel=-1)
+                               else:
+                                       useflags.append(prefixed_useflag)
+                       location_dict.setdefault(k, []).extend(useflags)
+               for k, v in location_dict.items():
+                       if juststrings:
+                               v = " ".join(v)
+                       else:
+                               v = tuple(v)
+                       ret.setdefault(k.cp, {})[k] = v
+               return ret
 
        def _parse_user_files_to_extatomdict(self, file_name, location, user_config):
                ret = ExtendedAtomDict(dict)
@@ -59,57 +116,28 @@ class UseManager(object):
 
                return ret
 
-       def _parse_profile_files_to_tuple(self, file_name, locations):
-               ret = []
-               for profile in locations:
-                       profile_lines = []
-                       path = os.path.join(profile, file_name)
-                       lines = grabfile(path, recursive=1)
-                       eapi = read_corresponding_eapi_file(path)
-                       useflag_re = _get_useflag_re(eapi)
-                       for prefixed_useflag in lines:
-                               if prefixed_useflag[:1] == "-":
-                                       useflag = prefixed_useflag[1:]
-                               else:
-                                       useflag = prefixed_useflag
-                               if useflag_re.match(useflag) is None:
-                                       writemsg(_("--- Invalid USE flag in '%s': '%s'\n") % \
-                                               (path, prefixed_useflag), noiselevel=-1)
-                               else:
-                                       profile_lines.append(prefixed_useflag)
-                       ret.append(tuple(profile_lines))
-               return tuple(ret)
+       def _parse_repository_files_to_dict_of_tuples(self, file_name, repositories):
+               ret = {}
+               for repo in repositories.repos_with_profiles():
+                       lines = []
+                       for master in repo.masters:
+                               lines.extend(self._parse_file_to_tuple(os.path.join(master.location, "profiles", file_name)))
+                       lines.extend(self._parse_file_to_tuple(os.path.join(repo.location, "profiles", file_name)))
+                       ret[repo.name] = tuple(lines)
+               return ret
 
-       def _parse_profile_files_to_dict(self, file_name, locations, juststrings=False):
-               ret = []
-               for profile in locations:
-                       profile_dict = {}
-                       cpdict = {}
-                       path = os.path.join(profile, file_name)
-                       file_dict = grabdict_package(path, recursive=1, verify_eapi=True)
-                       eapi = read_corresponding_eapi_file(path)
-                       useflag_re = _get_useflag_re(eapi)
-                       for k, v in file_dict.items():
-                               useflags = []
-                               for prefixed_useflag in v:
-                                       if prefixed_useflag[:1] == "-":
-                                               useflag = prefixed_useflag[1:]
-                                       else:
-                                               useflag = prefixed_useflag
-                                       if useflag_re.match(useflag) is None:
-                                               writemsg(_("--- Invalid USE flag for '%s' in '%s': '%s'\n") % \
-                                                       (k, path, prefixed_useflag), noiselevel=-1)
-                                       else:
-                                               useflags.append(prefixed_useflag)
-                               profile_dict.setdefault(k, []).extend(useflags)
-                       for k, v in profile_dict.items():
-                               if juststrings:
-                                       v = " ".join(v)
-                               else:
-                                       v = tuple(v)
-                               cpdict.setdefault(k.cp, {})[k] = v
-                       ret.append(cpdict)
-               return tuple(ret)
+       def _parse_repository_files_to_dict_of_dicts(self, file_name, repositories):
+               ret = {}
+               for repo in repositories.repos_with_profiles():
+                       # TODO: Handle master repositories.
+                       ret[repo.name] = self._parse_file_to_dict(os.path.join(repo.location, "profiles", file_name))
+               return ret
+
+       def _parse_profile_files_to_tuple_of_tuples(self, file_name, locations):
+               return tuple(self._parse_file_to_tuple(os.path.join(profile, file_name)) for profile in locations)
+
+       def _parse_profile_files_to_tuple_of_dicts(self, file_name, locations, juststrings=False):
+               return tuple(self._parse_file_to_dict(os.path.join(profile, file_name), juststrings) for profile in locations)
 
        def getUseMask(self, pkg=None):
                if pkg is None:
@@ -120,6 +148,13 @@ class UseManager(object):
                if cp is None:
                        cp = cpv_getkey(remove_slot(pkg))
                usemask = []
+               if hasattr(pkg, "repo") and pkg.repo != Package.UNKNOWN_REPO:
+                       usemask.append(self._repo_usemask_dict[pkg.repo])
+                       cpdict = self._repo_pusemask_dict[pkg.repo].get(cp)
+                       if cpdict:
+                               pkg_usemask = ordered_by_atom_specificity(cpdict, pkg)
+                               if pkg_usemask:
+                                       usemask.extend(pkg_usemask)
                for i, pusemask_dict in enumerate(self._pusemask_list):
                        if self._usemask_list[i]:
                                usemask.append(self._usemask_list[i])
@@ -139,6 +174,13 @@ class UseManager(object):
                if cp is None:
                        cp = cpv_getkey(remove_slot(pkg))
                useforce = []
+               if hasattr(pkg, "repo") and pkg.repo != Package.UNKNOWN_REPO:
+                       useforce.append(self._repo_useforce_dict[pkg.repo])
+                       cpdict = self._repo_puseforce_dict[pkg.repo].get(cp)
+                       if cpdict:
+                               pkg_useforce = ordered_by_atom_specificity(cpdict, pkg)
+                               if pkg_useforce:
+                                       useforce.extend(pkg_useforce)
                for i, puseforce_dict in enumerate(self._puseforce_list):
                        if self._useforce_list[i]:
                                useforce.append(self._useforce_list[i])
index b45f3c1160e274829a69a53c0f753900d1a27106..466b701f9951ab150327fcf8ea939b5980dc389e 100644 (file)
@@ -513,7 +513,7 @@ class config(object):
                                local_config, global_accept_keywords=self.configdict["defaults"].get("ACCEPT_KEYWORDS", ""))
 
                        #Read all USE related files from profiles and optionally from user config.
-                       self._use_manager = UseManager(self.profiles, abs_user_config, user_config=local_config)
+                       self._use_manager = UseManager(self.repositories, self.profiles, abs_user_config, user_config=local_config)
                        #Initialize all USE related variables we track ourselves.
                        self.usemask = self._use_manager.getUseMask()
                        self.useforce = self._use_manager.getUseForce()