| # Copyright 2010-2014 Gentoo Foundation |
| # Distributed under the terms of the GNU General Public License v2 |
| |
| __all__ = ['getmaskingreason'] |
| |
| import portage |
| from portage import os |
| from portage.const import USER_CONFIG_PATH |
| from portage.dep import Atom, match_from_list |
| from portage.exception import InvalidAtom |
| from portage.localization import _ |
| from portage.repository.config import _gen_valid_repo |
| from portage.util import grablines, normalize_path |
| from portage.versions import catpkgsplit, _pkg_str |
| |
| def getmaskingreason(mycpv, metadata=None, settings=None, |
| portdb=None, return_location=False, myrepo=None): |
| """ |
| If specified, the myrepo argument is assumed to be valid. This |
| should be a safe assumption since portdbapi methods always |
| return valid repo names and valid "repository" metadata from |
| aux_get. |
| """ |
| if settings is None: |
| settings = portage.settings |
| if portdb is None: |
| portdb = portage.portdb |
| mysplit = catpkgsplit(mycpv) |
| if not mysplit: |
| raise ValueError(_("invalid CPV: %s") % mycpv) |
| |
| if metadata is None: |
| db_keys = list(portdb._aux_cache_keys) |
| try: |
| metadata = dict(zip(db_keys, |
| portdb.aux_get(mycpv, db_keys, myrepo=myrepo))) |
| except KeyError: |
| if not portdb.cpv_exists(mycpv): |
| raise |
| else: |
| if myrepo is None: |
| myrepo = _gen_valid_repo(metadata["repository"]) |
| |
| elif myrepo is None: |
| myrepo = metadata.get("repository") |
| if myrepo is not None: |
| myrepo = _gen_valid_repo(metadata["repository"]) |
| |
| if metadata is not None and \ |
| not portage.eapi_is_supported(metadata["EAPI"]): |
| # Return early since otherwise we might produce invalid |
| # results given that the EAPI is not supported. Also, |
| # metadata is mostly useless in this case since it doesn't |
| # contain essential things like SLOT. |
| if return_location: |
| return (None, None) |
| else: |
| return None |
| |
| # Sometimes we can't access SLOT or repository due to corruption. |
| pkg = mycpv |
| try: |
| pkg.slot |
| except AttributeError: |
| pkg = _pkg_str(mycpv, metadata=metadata, repo=myrepo) |
| |
| cpv_slot_list = [pkg] |
| |
| mycp = pkg.cp |
| |
| locations = [] |
| if pkg.repo in settings.repositories: |
| for repo in settings.repositories[pkg.repo].masters + (settings.repositories[pkg.repo],): |
| locations.append(os.path.join(repo.location, "profiles")) |
| locations.extend(settings.profiles) |
| locations.append(os.path.join(settings["PORTAGE_CONFIGROOT"], |
| USER_CONFIG_PATH)) |
| locations.reverse() |
| pmasklists = [] |
| for profile in locations: |
| pmask_filename = os.path.join(profile, "package.mask") |
| node = None |
| for l, recursive_filename in grablines(pmask_filename, |
| recursive=1, remember_source_file=True): |
| if node is None or node[0] != recursive_filename: |
| node = (recursive_filename, []) |
| pmasklists.append(node) |
| node[1].append(l) |
| |
| pmaskdict = settings._mask_manager._pmaskdict |
| if mycp in pmaskdict: |
| for x in pmaskdict[mycp]: |
| if match_from_list(x, cpv_slot_list): |
| x = x.without_repo |
| for pmask in pmasklists: |
| comment = "" |
| comment_valid = -1 |
| pmask_filename = pmask[0] |
| for i in range(len(pmask[1])): |
| l = pmask[1][i].strip() |
| try: |
| l_atom = Atom(l, allow_repo=True, |
| allow_wildcard=True).without_repo |
| except InvalidAtom: |
| l_atom = None |
| if l == "": |
| comment = "" |
| comment_valid = -1 |
| elif l[0] == "#": |
| comment += (l+"\n") |
| comment_valid = i + 1 |
| elif l_atom == x: |
| if comment_valid != i: |
| comment = "" |
| if return_location: |
| return (comment, pmask_filename) |
| else: |
| return comment |
| elif comment_valid != -1: |
| # Apparently this comment applies to multiple masks, so |
| # it remains valid until a blank line is encountered. |
| comment_valid += 1 |
| if return_location: |
| return (None, None) |
| else: |
| return None |