1 |
Author: zmedico |
2 |
Date: 2009-03-23 21:16:27 +0000 (Mon, 23 Mar 2009) |
3 |
New Revision: 13173 |
4 |
|
5 |
Modified: |
6 |
main/trunk/man/make.conf.5 |
7 |
main/trunk/pym/_emerge/__init__.py |
8 |
main/trunk/pym/portage/__init__.py |
9 |
main/trunk/pym/portage/cache/util.py |
10 |
main/trunk/pym/portage/dbapi/porttree.py |
11 |
Log: |
12 |
Add support for FEATURES=parse-eapi-ebuild-head, which is similar to GLEP 55 |
13 |
except that the EAPI is parsed from the head of the ebuild (first 30 lines). |
14 |
This feature is only intended for experimental purposes and should not be |
15 |
enabled under normal circumstances. |
16 |
|
17 |
|
18 |
Modified: main/trunk/man/make.conf.5 |
19 |
=================================================================== |
20 |
--- main/trunk/man/make.conf.5 2009-03-23 07:16:00 UTC (rev 13172) |
21 |
+++ main/trunk/man/make.conf.5 2009-03-23 21:16:27 UTC (rev 13173) |
22 |
@@ -269,6 +269,11 @@ |
23 |
`tail \-f /var/log/emerge\-fetch.log` in a |
24 |
terminal to view parallel-fetch progress. |
25 |
.TP |
26 |
+.B parse\-eapi\-ebuild\-head |
27 |
+Parse \fBEAPI\fR from the head of the ebuild (first 30 lines). This feature |
28 |
+is only intended for experimental purposes and should not be enabled under |
29 |
+normal circumstances. |
30 |
+.TP |
31 |
.B preserve\-libs |
32 |
Preserve libraries when the sonames change during upgrade or downgrade. |
33 |
Libraries are preserved only if consumers of those libraries are detected. |
34 |
|
35 |
Modified: main/trunk/pym/_emerge/__init__.py |
36 |
=================================================================== |
37 |
--- main/trunk/pym/_emerge/__init__.py 2009-03-23 07:16:00 UTC (rev 13172) |
38 |
+++ main/trunk/pym/_emerge/__init__.py 2009-03-23 21:16:27 UTC (rev 13173) |
39 |
@@ -4,6 +4,7 @@ |
40 |
# $Id$ |
41 |
|
42 |
import array |
43 |
+import codecs |
44 |
from collections import deque |
45 |
import fcntl |
46 |
import formatter |
47 |
@@ -3029,6 +3030,19 @@ |
48 |
settings = self.settings |
49 |
settings.setcpv(self.cpv) |
50 |
ebuild_path = self.ebuild_path |
51 |
+ |
52 |
+ if 'parse-eapi-ebuild-head' in settings.features: |
53 |
+ eapi = portage._parse_eapi_ebuild_head(codecs.open(ebuild_path, |
54 |
+ mode='r', encoding='utf_8', errors='replace')) |
55 |
+ if not portage.eapi_is_supported(eapi): |
56 |
+ self.metadata_callback(self.cpv, self.ebuild_path, |
57 |
+ self.repo_path, {'EAPI' : eapi}, self.ebuild_mtime) |
58 |
+ self.returncode = os.EX_OK |
59 |
+ self.wait() |
60 |
+ return |
61 |
+ |
62 |
+ settings.configdict['pkg']['EAPI'] = eapi |
63 |
+ |
64 |
debug = settings.get("PORTAGE_DEBUG") == "1" |
65 |
master_fd = None |
66 |
slave_fd = None |
67 |
|
68 |
Modified: main/trunk/pym/portage/__init__.py |
69 |
=================================================================== |
70 |
--- main/trunk/pym/portage/__init__.py 2009-03-23 07:16:00 UTC (rev 13172) |
71 |
+++ main/trunk/pym/portage/__init__.py 2009-03-23 21:16:27 UTC (rev 13173) |
72 |
@@ -1790,6 +1790,9 @@ |
73 |
|
74 |
self["FEATURES"] = " ".join(sorted(self.features)) |
75 |
self.backup_changes("FEATURES") |
76 |
+ global _validate_cache_for_unsupported_eapis |
77 |
+ if 'parse-eapi-ebuild-head' in self.features: |
78 |
+ _validate_cache_for_unsupported_eapis = False |
79 |
|
80 |
self._init_dirs() |
81 |
|
82 |
@@ -5024,6 +5027,30 @@ |
83 |
return False |
84 |
return eapi <= portage.const.EAPI |
85 |
|
86 |
+# Generally, it's best not to assume that cache entries for unsupported EAPIs |
87 |
+# can be validated. However, the current package manager specification does not |
88 |
+# guarantee that that the EAPI can be parsed without sourcing the ebuild, so |
89 |
+# it's too costly to discard existing cache entries for unsupported EAPIs. |
90 |
+# Therefore, by default, assume that cache entries for unsupported EAPIs can be |
91 |
+# validated. If FEATURES=parse-eapi-* is enabled, this assumption is discarded |
92 |
+# since the EAPI can be determined without the incurring the cost of sourcing |
93 |
+# the ebuild. |
94 |
+_validate_cache_for_unsupported_eapis = True |
95 |
+ |
96 |
+_parse_eapi_ebuild_head_re = re.compile(r'^EAPI=[\'"]?([^\'"]*)') |
97 |
+_parse_eapi_ebuild_head_max_lines = 30 |
98 |
+ |
99 |
+def _parse_eapi_ebuild_head(f): |
100 |
+ count = 0 |
101 |
+ for line in f: |
102 |
+ m = _parse_eapi_ebuild_head_re.match(line) |
103 |
+ if m is not None: |
104 |
+ return m.group(1).strip() |
105 |
+ count += 1 |
106 |
+ if count >= _parse_eapi_ebuild_head_max_lines: |
107 |
+ break |
108 |
+ return '0' |
109 |
+ |
110 |
def doebuild_environment(myebuild, mydo, myroot, mysettings, debug, use_cache, mydbapi): |
111 |
|
112 |
ebuild_path = os.path.abspath(myebuild) |
113 |
@@ -5096,6 +5123,15 @@ |
114 |
if portage.util.noiselimit < 0: |
115 |
mysettings["PORTAGE_QUIET"] = "1" |
116 |
|
117 |
+ if mydo == 'depend' and \ |
118 |
+ 'EAPI' not in mysettings.configdict['pkg'] and \ |
119 |
+ 'parse-eapi-ebuild-head' in mysettings.features: |
120 |
+ eapi = _parse_eapi_ebuild_head(codecs.open(ebuild_path, |
121 |
+ mode='r', encoding='utf_8', errors='replace')) |
122 |
+ if not eapi_is_supported(eapi): |
123 |
+ raise portage.exception.UnsupportedAPIException(mycpv, eapi) |
124 |
+ mysettings.configdict['pkg']['EAPI'] = eapi |
125 |
+ |
126 |
if mydo != "depend": |
127 |
# Metadata vars such as EAPI and RESTRICT are |
128 |
# set by the above config.setcpv() call. |
129 |
|
130 |
Modified: main/trunk/pym/portage/cache/util.py |
131 |
=================================================================== |
132 |
--- main/trunk/pym/portage/cache/util.py 2009-03-23 07:16:00 UTC (rev 13172) |
133 |
+++ main/trunk/pym/portage/cache/util.py 2009-03-23 21:16:27 UTC (rev 13173) |
134 |
@@ -10,7 +10,8 @@ |
135 |
|
136 |
def mirror_cache(valid_nodes_iterable, src_cache, trg_cache, eclass_cache=None, verbose_instance=None): |
137 |
|
138 |
- from portage import eapi_is_supported |
139 |
+ from portage import eapi_is_supported, \ |
140 |
+ _validate_cache_for_unsupported_eapis |
141 |
if not src_cache.complete_eclass_entries and not eclass_cache: |
142 |
raise Exception("eclass_cache required for cache's of class %s!" % src_cache.__class__) |
143 |
|
144 |
@@ -39,6 +40,17 @@ |
145 |
noise.exception(x, ce) |
146 |
del ce |
147 |
continue |
148 |
+ |
149 |
+ eapi = entry.get('EAPI') |
150 |
+ if not eapi: |
151 |
+ eapi = '0' |
152 |
+ eapi = eapi.lstrip('-') |
153 |
+ eapi_supported = eapi_is_supported(eapi) |
154 |
+ if not eapi_supported: |
155 |
+ if not _validate_cache_for_unsupported_eapis: |
156 |
+ noise.misc(x, "unable to validate cache for EAPI='%s'" % eapi) |
157 |
+ continue |
158 |
+ |
159 |
write_it = True |
160 |
trg = None |
161 |
try: |
162 |
@@ -102,13 +114,10 @@ |
163 |
continue |
164 |
entry["_eclasses_"] = eclasses |
165 |
|
166 |
- eapi = entry.get("EAPI") |
167 |
- if not eapi: |
168 |
- eapi = "0" |
169 |
- if not eapi_is_supported(eapi): |
170 |
+ if not eapi_supported: |
171 |
for k in set(entry).difference(("_mtime_", "_eclasses_")): |
172 |
entry[k] = "" |
173 |
- entry["EAPI"] = "-" + eapi.lstrip("-") |
174 |
+ entry["EAPI"] = "-" + eapi |
175 |
|
176 |
# by this time, if it reaches here, the eclass has been validated, and the entry has |
177 |
# been updated/translated (if needs be, for metadata/cache mainly) |
178 |
|
179 |
Modified: main/trunk/pym/portage/dbapi/porttree.py |
180 |
=================================================================== |
181 |
--- main/trunk/pym/portage/dbapi/porttree.py 2009-03-23 07:16:00 UTC (rev 13172) |
182 |
+++ main/trunk/pym/portage/dbapi/porttree.py 2009-03-23 21:16:27 UTC (rev 13173) |
183 |
@@ -25,7 +25,7 @@ |
184 |
listdir, dep_expand, eapi_is_supported, key_expand, dep_check, \ |
185 |
_eapi_is_deprecated |
186 |
|
187 |
-import os, stat |
188 |
+import codecs, os, stat |
189 |
from itertools import izip |
190 |
|
191 |
def _src_uri_validate(cpv, eapi, src_uri): |
192 |
@@ -419,13 +419,23 @@ |
193 |
|
194 |
self.doebuild_settings.setcpv(mycpv) |
195 |
mydata = {} |
196 |
- myret = doebuild(myebuild, "depend", |
197 |
- self.doebuild_settings["ROOT"], self.doebuild_settings, |
198 |
- dbkey=mydata, tree="porttree", mydbapi=self) |
199 |
- if myret != os.EX_OK: |
200 |
- self._broken_ebuilds.add(myebuild) |
201 |
- raise KeyError(mycpv) |
202 |
+ eapi = None |
203 |
|
204 |
+ if 'parse-eapi-ebuild-head' in self.doebuild_settings.features: |
205 |
+ eapi = portage._parse_eapi_ebuild_head(codecs.open(myebuild, |
206 |
+ mode='r', encoding='utf_8', errors='replace')) |
207 |
+ self.doebuild_settings.configdict['pkg']['EAPI'] = eapi |
208 |
+ |
209 |
+ if eapi is not None and not portage.eapi_is_supported(eapi): |
210 |
+ mydata['EAPI'] = eapi |
211 |
+ else: |
212 |
+ myret = doebuild(myebuild, "depend", |
213 |
+ self.doebuild_settings["ROOT"], self.doebuild_settings, |
214 |
+ dbkey=mydata, tree="porttree", mydbapi=self) |
215 |
+ if myret != os.EX_OK: |
216 |
+ self._broken_ebuilds.add(myebuild) |
217 |
+ raise KeyError(mycpv) |
218 |
+ |
219 |
self._metadata_callback( |
220 |
mycpv, myebuild, mylocation, mydata, emtime) |