1 |
Author: grobian |
2 |
Date: 2009-06-28 13:41:26 +0000 (Sun, 28 Jun 2009) |
3 |
New Revision: 13721 |
4 |
|
5 |
Modified: |
6 |
main/branches/prefix/pym/_emerge/depgraph.py |
7 |
main/branches/prefix/pym/repoman/checks.py |
8 |
Log: |
9 |
Merged from trunk -r13703:13717 |
10 |
|
11 |
| 13716 | Bug #270953 - New !!atom blockers do not allow temporary | |
12 |
| zmedico | simulaneous installation, so unlike !atom blockers, !!atom | |
13 |
| | blockers aren't ignored when they match other packages | |
14 |
| | occupying the same slot. Thanks to Sebastian Mingramm (few) | |
15 |
| | <s.mingramm@×××.de> for the initial patch. | |
16 |
|
17 |
| 13717 | * Add new abstract PhaseCheck class for ebuild | |
18 |
| zmedico | phase-specific checks. * Reimplement SrcUnpackPatches using | |
19 |
| | PhaseCheck. * Add new SrcCompileEconf, | |
20 |
| | Eapi3IncompatibleFuncs, and Eapi3GoneVars checks. Thanks to | |
21 |
| | Markus Meier <maekke@g.o> for this patch. | |
22 |
|
23 |
|
24 |
Modified: main/branches/prefix/pym/_emerge/depgraph.py |
25 |
=================================================================== |
26 |
--- main/branches/prefix/pym/_emerge/depgraph.py 2009-06-28 13:40:14 UTC (rev 13720) |
27 |
+++ main/branches/prefix/pym/_emerge/depgraph.py 2009-06-28 13:41:26 UTC (rev 13721) |
28 |
@@ -2448,11 +2448,13 @@ |
29 |
unresolved_blocks = False |
30 |
depends_on_order = set() |
31 |
for pkg in blocked_initial: |
32 |
- if pkg.slot_atom == parent.slot_atom: |
33 |
- # TODO: Support blocks within slots in cases where it |
34 |
- # might make sense. For example, a new version might |
35 |
- # require that the old version be uninstalled at build |
36 |
- # time. |
37 |
+ if pkg.slot_atom == parent.slot_atom and \ |
38 |
+ not blocker.atom.blocker.overlap.forbid: |
39 |
+ # New !!atom blockers do not allow temporary |
40 |
+ # simulaneous installation, so unlike !atom |
41 |
+ # blockers, !!atom blockers aren't ignored |
42 |
+ # when they match other packages occupying |
43 |
+ # the same slot. |
44 |
continue |
45 |
if parent.installed: |
46 |
# Two currently installed packages conflict with |
47 |
@@ -2472,8 +2474,13 @@ |
48 |
# so apparently this one is unresolvable. |
49 |
unresolved_blocks = True |
50 |
for pkg in blocked_final: |
51 |
- if pkg.slot_atom == parent.slot_atom: |
52 |
- # TODO: Support blocks within slots. |
53 |
+ if pkg.slot_atom == parent.slot_atom and \ |
54 |
+ not blocker.atom.blocker.overlap.forbid: |
55 |
+ # New !!atom blockers do not allow temporary |
56 |
+ # simulaneous installation, so unlike !atom |
57 |
+ # blockers, !!atom blockers aren't ignored |
58 |
+ # when they match other packages occupying |
59 |
+ # the same slot. |
60 |
continue |
61 |
if parent.operation == "nomerge" and \ |
62 |
pkg.operation == "nomerge": |
63 |
|
64 |
Modified: main/branches/prefix/pym/repoman/checks.py |
65 |
=================================================================== |
66 |
--- main/branches/prefix/pym/repoman/checks.py 2009-06-28 13:40:14 UTC (rev 13720) |
67 |
+++ main/branches/prefix/pym/repoman/checks.py 2009-06-28 13:41:26 UTC (rev 13721) |
68 |
@@ -19,6 +19,10 @@ |
69 |
def new(self, pkg): |
70 |
pass |
71 |
|
72 |
+ def check_eapi(self, eapi): |
73 |
+ """ returns if the check should be run in the given EAPI (default is True) """ |
74 |
+ return True |
75 |
+ |
76 |
def check(self, num, line): |
77 |
"""Run the check on line and return error if there is one""" |
78 |
if self.re.match(line): |
79 |
@@ -198,7 +202,7 @@ |
80 |
class EbuildUselessCdS(LineCheck): |
81 |
"""Check for redundant cd ${S} statements""" |
82 |
repoman_check_name = 'ebuild.minorsyn' |
83 |
- method_re = re.compile(r'^\s*src_(compile|install|test)\s*\(\)') |
84 |
+ method_re = re.compile(r'^\s*src_(prepare|configure|compile|install|test)\s*\(\)') |
85 |
cds_re = re.compile(r'^\s*cd\s+("\$(\{S\}|S)"|\$(\{S\}|S))\s') |
86 |
|
87 |
def __init__(self): |
88 |
@@ -229,39 +233,6 @@ |
89 |
elif self.inherit_re.match(line) is not None: |
90 |
self.inherit_line = line |
91 |
|
92 |
-class SrcUnpackPatches(LineCheck): |
93 |
- repoman_check_name = 'ebuild.minorsyn' |
94 |
- |
95 |
- ignore_line = re.compile(r'(^\s*#)') |
96 |
- src_unpack_re = re.compile(r'^src_unpack\(\)') |
97 |
- func_end_re = re.compile(r'^\}$') |
98 |
- src_prepare_tools_re = re.compile(r'\s(e?patch|sed)\s') |
99 |
- |
100 |
- def new(self, pkg): |
101 |
- if pkg.metadata['EAPI'] not in ('0', '1'): |
102 |
- self.eapi = pkg.metadata['EAPI'] |
103 |
- else: |
104 |
- self.eapi = None |
105 |
- self.in_src_unpack = None |
106 |
- |
107 |
- def check(self, num, line): |
108 |
- |
109 |
- if self.eapi is not None: |
110 |
- |
111 |
- if self.in_src_unpack is None and \ |
112 |
- self.src_unpack_re.match(line) is not None: |
113 |
- self.in_src_unpack = True |
114 |
- |
115 |
- if self.in_src_unpack is True and \ |
116 |
- self.func_end_re.match(line) is not None: |
117 |
- self.in_src_unpack = False |
118 |
- |
119 |
- if self.in_src_unpack: |
120 |
- m = self.src_prepare_tools_re.search(line) |
121 |
- if m is not None: |
122 |
- return ("'%s'" % m.group(1)) + \ |
123 |
- " call should be moved to src_prepare from line: %d" |
124 |
- |
125 |
class EbuildPatches(LineCheck): |
126 |
"""Ensure ebuilds use bash arrays for PATCHES to ensure white space safety""" |
127 |
repoman_check_name = 'ebuild.patches' |
128 |
@@ -285,10 +256,14 @@ |
129 |
since this triggers implicit RDEPEND=$DEPEND assignment. |
130 |
""" |
131 |
|
132 |
- repoman_check_name = 'RDEPEND.implicit' |
133 |
_assignment_re = re.compile(r'^\s*(R?DEPEND)=') |
134 |
|
135 |
def new(self, pkg): |
136 |
+ # RDEPEND=DEPEND is no longer available in EAPI=3 |
137 |
+ if pkg.metadata['EAPI'] in ('0', '1', '2'): |
138 |
+ self.repoman_check_name = 'RDEPEND.implicit' |
139 |
+ else: |
140 |
+ self.repoman_check_name = 'EAPI.incompatible' |
141 |
self._rdepend = False |
142 |
self._depend = False |
143 |
|
144 |
@@ -394,6 +369,107 @@ |
145 |
return 'WANT_AUTO' + m.group(1) + \ |
146 |
' redundantly set to default value "latest" on line: %d' |
147 |
|
148 |
+class PhaseCheck(LineCheck): |
149 |
+ """ basic class for function detection """ |
150 |
+ |
151 |
+ ignore_line = re.compile(r'(^\s*#)') |
152 |
+ func_end_re = re.compile(r'^\}$') |
153 |
+ in_phase = '' |
154 |
+ |
155 |
+ def __init__(self): |
156 |
+ self.phases = ('pkg_setup', 'pkg_preinst', 'pkg_postinst', 'pkg_prerm', 'pkg_postrm', 'pkg_pretend', |
157 |
+ 'src_unpack', 'src_prepare', 'src_compile', 'src_test', 'src_install') |
158 |
+ phase_re = '(' |
159 |
+ for phase in self.phases: |
160 |
+ phase_re += phase + '|' |
161 |
+ phase_re = phase_re[:-1] + ')' |
162 |
+ self.phases_re = re.compile(phase_re) |
163 |
+ |
164 |
+ def check(self, num, line): |
165 |
+ m = self.phases_re.match(line) |
166 |
+ if m is not None: |
167 |
+ self.in_phase = m.group(1) |
168 |
+ if self.in_phase != '' and \ |
169 |
+ self.func_end_re.match(line) is not None: |
170 |
+ self.in_phase = '' |
171 |
+ |
172 |
+ return self.phase_check(num, line) |
173 |
+ |
174 |
+ def phase_check(self, num, line): |
175 |
+ """ override this function for your checks """ |
176 |
+ pass |
177 |
+ |
178 |
+class SrcCompileEconf(PhaseCheck): |
179 |
+ repoman_check_name = 'ebuild.minorsyn' |
180 |
+ configure_re = re.compile(r'\s(econf|./configure)') |
181 |
+ |
182 |
+ def check_eapi(self, eapi): |
183 |
+ return eapi not in ('0', '1') |
184 |
+ |
185 |
+ def phase_check(self, num, line): |
186 |
+ if self.in_phase == 'src_compile': |
187 |
+ m = self.configure_re.match(line) |
188 |
+ if m is not None: |
189 |
+ return ("'%s'" % m.group(1)) + \ |
190 |
+ " call should be moved to src_configure from line: %d" |
191 |
+ |
192 |
+class SrcUnpackPatches(PhaseCheck): |
193 |
+ repoman_check_name = 'ebuild.minorsyn' |
194 |
+ src_prepare_tools_re = re.compile(r'\s(e?patch|sed)\s') |
195 |
+ |
196 |
+ def new(self, pkg): |
197 |
+ if pkg.metadata['EAPI'] not in ('0', '1'): |
198 |
+ self.eapi = pkg.metadata['EAPI'] |
199 |
+ else: |
200 |
+ self.eapi = None |
201 |
+ self.in_src_unpack = None |
202 |
+ |
203 |
+ def check_eapi(self, eapi): |
204 |
+ return eapi not in ('0', '1') |
205 |
+ |
206 |
+ def phase_check(self, num, line): |
207 |
+ if self.in_phase == 'src_unpack': |
208 |
+ m = self.src_prepare_tools_re.search(line) |
209 |
+ if m is not None: |
210 |
+ return ("'%s'" % m.group(1)) + \ |
211 |
+ " call should be moved to src_prepare from line: %d" |
212 |
+ |
213 |
+# EAPI-3 checks |
214 |
+class Eapi3IncompatibleFuncs(LineCheck): |
215 |
+ repoman_check_name = 'EAPI.incompatible' |
216 |
+ ignore_line = re.compile(r'(^\s*#)') |
217 |
+ banned_commands_re = re.compile(r'^\s*(dosed|dohard)') |
218 |
+ |
219 |
+ def new(self, pkg): |
220 |
+ self.eapi = pkg.metadata['EAPI'] |
221 |
+ |
222 |
+ def check_eapi(self, eapi): |
223 |
+ return self.eapi not in ('0', '1', '2') |
224 |
+ |
225 |
+ def check(self, num, line): |
226 |
+ m = self.banned_commands_re.match(line) |
227 |
+ if m is not None: |
228 |
+ return ("'%s'" % m.group(1)) + \ |
229 |
+ " has been banned in EAPI=3 on line: %d" |
230 |
+ |
231 |
+class Eapi3GoneVars(LineCheck): |
232 |
+ repoman_check_name = 'EAPI.incompatible' |
233 |
+ ignore_line = re.compile(r'(^\s*#)') |
234 |
+ undefined_vars_re = re.compile(r'.*\$(\{(AA|KV)\}|(AA|KV))') |
235 |
+ |
236 |
+ def new(self, pkg): |
237 |
+ self.eapi = pkg.metadata['EAPI'] |
238 |
+ |
239 |
+ def check_eapi(self, eapi): |
240 |
+ return self.eapi not in ('0', '1', '2') |
241 |
+ |
242 |
+ def check(self, num, line): |
243 |
+ m = self.undefined_vars_re.match(line) |
244 |
+ if m is not None: |
245 |
+ return ("variable '$%s'" % m.group(1)) + \ |
246 |
+ " is gone in EAPI=3 on line: %d" |
247 |
+ |
248 |
+ |
249 |
_constant_checks = tuple((c() for c in ( |
250 |
EbuildHeader, EbuildWhitespace, EbuildQuote, |
251 |
EbuildAssignment, EbuildUselessDodoc, |
252 |
@@ -401,7 +477,8 @@ |
253 |
EbuildPatches, EbuildQuotedA, EapiDefinition, |
254 |
IUseUndefined, ImplicitRuntimeDeps, InheritAutotools, |
255 |
EMakeParallelDisabled, EMakeParallelDisabledViaMAKEOPTS, |
256 |
- DeprecatedBindnowFlags, SrcUnpackPatches, WantAutoDefaultValue))) |
257 |
+ DeprecatedBindnowFlags, SrcUnpackPatches, WantAutoDefaultValue, |
258 |
+ SrcCompileEconf, Eapi3IncompatibleFuncs, Eapi3GoneVars))) |
259 |
|
260 |
_here_doc_re = re.compile(r'.*\s<<[-]?(\w+)$') |
261 |
|
262 |
@@ -425,11 +502,12 @@ |
263 |
if here_doc_delim is None: |
264 |
# We're not in a here-document. |
265 |
for lc in checks: |
266 |
- ignore = lc.ignore_line |
267 |
- if not ignore or not ignore.match(line): |
268 |
- e = lc.check(num, line) |
269 |
- if e: |
270 |
- yield lc.repoman_check_name, e % (num + 1) |
271 |
+ if lc.check_eapi(pkg.metadata['EAPI']): |
272 |
+ ignore = lc.ignore_line |
273 |
+ if not ignore or not ignore.match(line): |
274 |
+ e = lc.check(num, line) |
275 |
+ if e: |
276 |
+ yield lc.repoman_check_name, e % (num + 1) |
277 |
|
278 |
for lc in checks: |
279 |
i = lc.end() |