getmaskingreason: use _pkg_str
[portage.git] / pym / portage / package / ebuild / getmaskingreason.py
1 # Copyright 2010-2012 Gentoo Foundation
2 # Distributed under the terms of the GNU General Public License v2
3
4 __all__ = ['getmaskingreason']
5
6 import portage
7 from portage import os
8 from portage.const import USER_CONFIG_PATH
9 from portage.dep import Atom, match_from_list
10 from portage.exception import InvalidAtom
11 from portage.localization import _
12 from portage.repository.config import _gen_valid_repo
13 from portage.util import grablines, normalize_path
14 from portage.versions import catpkgsplit, _pkg_str
15
16 def getmaskingreason(mycpv, metadata=None, settings=None,
17         portdb=None, return_location=False, myrepo=None):
18         """
19         If specified, the myrepo argument is assumed to be valid. This
20         should be a safe assumption since portdbapi methods always
21         return valid repo names and valid "repository" metadata from
22         aux_get.
23         """
24         if settings is None:
25                 settings = portage.settings
26         if portdb is None:
27                 portdb = portage.portdb
28         mysplit = catpkgsplit(mycpv)
29         if not mysplit:
30                 raise ValueError(_("invalid CPV: %s") % mycpv)
31
32         if metadata is None:
33                 db_keys = list(portdb._aux_cache_keys)
34                 try:
35                         metadata = dict(zip(db_keys,
36                                 portdb.aux_get(mycpv, db_keys, myrepo=myrepo)))
37                 except KeyError:
38                         if not portdb.cpv_exists(mycpv):
39                                 raise
40                 else:
41                         if myrepo is None:
42                                 myrepo = _gen_valid_repo(metadata["repository"])
43
44         elif myrepo is None:
45                 myrepo = metadata.get("repository")
46                 if myrepo is not None:
47                         myrepo = _gen_valid_repo(metadata["repository"])
48
49         if metadata is not None and \
50                 not portage.eapi_is_supported(metadata["EAPI"]):
51                 # Return early since otherwise we might produce invalid
52                 # results given that the EAPI is not supported. Also,
53                 # metadata is mostly useless in this case since it doesn't
54                 # contain essential things like SLOT.
55                 if return_location:
56                         return (None, None)
57                 else:
58                         return None
59
60         # Sometimes we can't access SLOT or repository due to corruption.
61         pkg = mycpv
62         try:
63                 pkg.slot
64         except AttributeError:
65                 pkg = _pkg_str(mycpv, metadata=metadata, repo=myrepo)
66
67         cpv_slot_list = [pkg]
68
69         mycp = pkg.cp
70
71         # XXX- This is a temporary duplicate of code from the config constructor.
72         locations = [os.path.join(settings["PORTDIR"], "profiles")]
73         locations.extend(settings.profiles)
74         for ov in settings["PORTDIR_OVERLAY"].split():
75                 profdir = os.path.join(normalize_path(ov), "profiles")
76                 if os.path.isdir(profdir):
77                         locations.append(profdir)
78         locations.append(os.path.join(settings["PORTAGE_CONFIGROOT"],
79                 USER_CONFIG_PATH))
80         locations.reverse()
81         pmasklists = []
82         for profile in locations:
83                 pmask_filename = os.path.join(profile, "package.mask")
84                 node = None
85                 for l, recursive_filename in grablines(pmask_filename,
86                         recursive=1, remember_source_file=True):
87                         if node is None or node[0] != recursive_filename:
88                                 node = (recursive_filename, [])
89                                 pmasklists.append(node)
90                         node[1].append(l)
91
92         pmaskdict = settings._mask_manager._pmaskdict
93         if mycp in pmaskdict:
94                 for x in pmaskdict[mycp]:
95                         if match_from_list(x, cpv_slot_list):
96                                 x = x.without_repo
97                                 for pmask in pmasklists:
98                                         comment = ""
99                                         comment_valid = -1
100                                         pmask_filename = pmask[0]
101                                         for i in range(len(pmask[1])):
102                                                 l = pmask[1][i].strip()
103                                                 try:
104                                                         l_atom = Atom(l, allow_repo=True,
105                                                                 allow_wildcard=True).without_repo
106                                                 except InvalidAtom:
107                                                         l_atom = None
108                                                 if l == "":
109                                                         comment = ""
110                                                         comment_valid = -1
111                                                 elif l[0] == "#":
112                                                         comment += (l+"\n")
113                                                         comment_valid = i + 1
114                                                 elif l_atom == x:
115                                                         if comment_valid != i:
116                                                                 comment = ""
117                                                         if return_location:
118                                                                 return (comment, pmask_filename)
119                                                         else:
120                                                                 return comment
121                                                 elif comment_valid != -1:
122                                                         # Apparently this comment applies to multiple masks, so
123                                                         # it remains valid until a blank line is encountered.
124                                                         comment_valid += 1
125         if return_location:
126                 return (None, None)
127         else:
128                 return None