1 |
Author: grobian |
2 |
Date: 2008-10-28 18:51:42 +0000 (Tue, 28 Oct 2008) |
3 |
New Revision: 11735 |
4 |
|
5 |
Modified: |
6 |
main/branches/prefix/bin/repoman |
7 |
main/branches/prefix/cnf/sets.conf |
8 |
main/branches/prefix/man/ebuild.5 |
9 |
main/branches/prefix/man/repoman.1 |
10 |
main/branches/prefix/pym/_emerge/__init__.py |
11 |
main/branches/prefix/pym/portage/__init__.py |
12 |
main/branches/prefix/pym/portage/dbapi/vartree.py |
13 |
main/branches/prefix/pym/repoman/checks.py |
14 |
Log: |
15 |
Merged from trunk -r11713:11724 |
16 |
|
17 |
| 11714 | Split dep validation out of doebuild() and skip it when | |
18 |
| zmedico | called by emerge since there's no need to do this every time | |
19 |
| | emerge executes a phase. | |
20 |
|
21 |
| 11715 | Bug #233296 - Add minimal PROPERTIES=interactive support by | |
22 |
| zmedico | simply forcing all package output to stdio whenever the | |
23 |
| | merge list contains one or more interactive packages. | |
24 |
|
25 |
| 11716 | Document PROPERTIES=interactive. | |
26 |
| zmedico | | |
27 |
|
28 |
| 11717 | Add a PROPERTIES.syntax check. | |
29 |
| zmedico | | |
30 |
|
31 |
| 11718 | Fix grammar. | |
32 |
| zmedico | | |
33 |
|
34 |
| 11719 | Bug #243224 - Add an exemption to the inherit.autotools | |
35 |
| zmedico | check for ebuilds that inherit git.eclass since the | |
36 |
| | GIT_BOOTSTRAP variable may be used to call one of autotools | |
37 |
| | functions. | |
38 |
|
39 |
| 11720 | Add "bzr" to the lists of live eclasses. | |
40 |
| zmedico | | |
41 |
|
42 |
| 11721 | Add "bzr" to the lists of live eclasses. | |
43 |
| zmedico | | |
44 |
|
45 |
| 11722 | Add "subversion" to InheritAutotools._exempt_eclasses. | |
46 |
| zmedico | Thanks to Arfrever. | |
47 |
|
48 |
| 11723 | When populating the fake $DISTDIR inside doebuild(), reuse | |
49 |
| zmedico | existing symlinks when possible, instead of recreating the | |
50 |
| | whole directory from scratch. | |
51 |
|
52 |
| 11724 | Fix preserve-libs code inside dblink.unmerge() so that it | |
53 |
| zmedico | will join paths correctly when ROOT != /. | |
54 |
|
55 |
|
56 |
Modified: main/branches/prefix/bin/repoman |
57 |
=================================================================== |
58 |
--- main/branches/prefix/bin/repoman 2008-10-28 18:47:54 UTC (rev 11734) |
59 |
+++ main/branches/prefix/bin/repoman 2008-10-28 18:51:42 UTC (rev 11735) |
60 |
@@ -289,6 +289,7 @@ |
61 |
"PDEPEND.syntax":"Syntax error in PDEPEND (usually an extra/missing space/parenthesis)", |
62 |
"LICENSE.syntax":"Syntax error in LICENSE (usually an extra/missing space/parenthesis)", |
63 |
"PROVIDE.syntax":"Syntax error in PROVIDE (usually an extra/missing space/parenthesis)", |
64 |
+ "PROPERTIES.syntax":"Syntax error in PROPERTIES (usually an extra/missing space/parenthesis)", |
65 |
"RESTRICT.syntax":"Syntax error in RESTRICT (usually an extra/missing space/parenthesis)", |
66 |
"SRC_URI.syntax":"Syntax error in SRC_URI (usually an extra/missing space/parenthesis)", |
67 |
"SRC_URI.mirror":"A uri listed in profiles/thirdpartymirrors is found in SRC_URI", |
68 |
@@ -375,6 +376,7 @@ |
69 |
"primaryuri", "strip", "test", "userpriv"]) |
70 |
|
71 |
live_eclasses = frozenset([ |
72 |
+ "bzr", |
73 |
"cvs", |
74 |
"darcs", |
75 |
"git", |
76 |
@@ -1230,7 +1232,8 @@ |
77 |
"java-pkg-opt-2" in inherited |
78 |
operator_tokens = set(["||", "(", ")"]) |
79 |
type_list, badsyntax = [], [] |
80 |
- for mytype in ("DEPEND", "RDEPEND", "PDEPEND", "LICENSE", "PROVIDE"): |
81 |
+ for mytype in ("DEPEND", "RDEPEND", "PDEPEND", |
82 |
+ "LICENSE", "PROPERTIES", "PROVIDE"): |
83 |
mydepstr = myaux[mytype] |
84 |
|
85 |
if mydepstr.find(" ?") != -1: |
86 |
|
87 |
Modified: main/branches/prefix/cnf/sets.conf |
88 |
=================================================================== |
89 |
--- main/branches/prefix/cnf/sets.conf 2008-10-28 18:47:54 UTC (rev 11734) |
90 |
+++ main/branches/prefix/cnf/sets.conf 2008-10-28 18:51:42 UTC (rev 11735) |
91 |
@@ -51,7 +51,7 @@ |
92 |
class = portage.sets.dbapi.VariableSet |
93 |
world-candidate = False |
94 |
variable = INHERITED |
95 |
-includes = cvs darcs git mercurial subversion |
96 |
+includes = bzr cvs darcs git mercurial subversion |
97 |
|
98 |
# Installed packages that own files inside /lib/modules. |
99 |
[module-rebuild] |
100 |
|
101 |
Modified: main/branches/prefix/man/ebuild.5 |
102 |
=================================================================== |
103 |
--- main/branches/prefix/man/ebuild.5 2008-10-28 18:47:54 UTC (rev 11734) |
104 |
+++ main/branches/prefix/man/ebuild.5 2008-10-28 18:51:42 UTC (rev 11735) |
105 |
@@ -401,6 +401,16 @@ |
106 |
.RE |
107 |
.PD 1 |
108 |
.TP |
109 |
+\fBPROPERTIES\fR = \fI[interactive]\fR |
110 |
+A space delimited list of properties, with conditional syntax support. |
111 |
+.PD 0 |
112 |
+.RS |
113 |
+.TP |
114 |
+.I interactive |
115 |
+One or more ebuild phases will produce a prompt that requires user interaction. |
116 |
+.RE |
117 |
+.PD 1 |
118 |
+.TP |
119 |
\fBPROVIDE\fR = \fI"virtual/TARGET"\fR |
120 |
This variable should only be used when a package provides a virtual target. |
121 |
For example, blackdown\-jdk and sun\-jdk provide \fIvirtual/jdk\fR. This |
122 |
|
123 |
Modified: main/branches/prefix/man/repoman.1 |
124 |
=================================================================== |
125 |
--- main/branches/prefix/man/repoman.1 2008-10-28 18:47:54 UTC (rev 11734) |
126 |
+++ main/branches/prefix/man/repoman.1 2008-10-28 18:51:42 UTC (rev 11735) |
127 |
@@ -177,6 +177,12 @@ |
128 |
.B RDEPEND.syntax |
129 |
Syntax error in RDEPEND (usually an extra/missing space/parenthesis) |
130 |
.TP |
131 |
+.B PROPERTIES.syntax |
132 |
+Syntax error in PROPERTIES (usually an extra/missing space/parenthesis) |
133 |
+.TP |
134 |
+.B RESTRICT.syntax |
135 |
+Syntax error in RESTRICT (usually an extra/missing space/parenthesis) |
136 |
+.TP |
137 |
.B SLOT.missing |
138 |
Ebuilds that have a missing or empty SLOT variable |
139 |
.TP |
140 |
|
141 |
Modified: main/branches/prefix/pym/_emerge/__init__.py |
142 |
=================================================================== |
143 |
--- main/branches/prefix/pym/_emerge/__init__.py 2008-10-28 18:47:54 UTC (rev 11734) |
144 |
+++ main/branches/prefix/pym/_emerge/__init__.py 2008-10-28 18:51:42 UTC (rev 11735) |
145 |
@@ -2702,6 +2702,7 @@ |
146 |
_phases = ("prepare", "configure", "compile", "test", "install") |
147 |
|
148 |
_live_eclasses = frozenset([ |
149 |
+ "bzr", |
150 |
"cvs", |
151 |
"darcs", |
152 |
"git", |
153 |
@@ -9237,6 +9238,28 @@ |
154 |
self._max_jobs > 1 or "--quiet" in self.myopts) and \ |
155 |
not bool(self._opts_no_background.intersection(self.myopts)) |
156 |
|
157 |
+ if background: |
158 |
+ interactive_tasks = self._get_interactive_tasks() |
159 |
+ if interactive_tasks: |
160 |
+ background = False |
161 |
+ writemsg_level(">>> Sending package output to stdio due " + \ |
162 |
+ "to interactive package(s):\n", |
163 |
+ level=logging.INFO, noiselevel=-1) |
164 |
+ msg = [""] |
165 |
+ for pkg in interactive_tasks: |
166 |
+ pkg_str = " " + colorize("INFORM", str(pkg.cpv)) |
167 |
+ if pkg.root != "/": |
168 |
+ pkg_str += " for " + pkg.root |
169 |
+ msg.append(pkg_str) |
170 |
+ msg.append("") |
171 |
+ writemsg_level("".join("%s\n" % (l,) for l in msg), |
172 |
+ level=logging.INFO, noiselevel=-1) |
173 |
+ if self._max_jobs is True or self._max_jobs > 1: |
174 |
+ self._set_max_jobs(1) |
175 |
+ writemsg_level(">>> Setting --jobs=1 due " + \ |
176 |
+ "to the above interactive package(s)\n", |
177 |
+ level=logging.INFO, noiselevel=-1) |
178 |
+ |
179 |
self._status_display.quiet = \ |
180 |
not background or \ |
181 |
("--quiet" in self.myopts and \ |
182 |
@@ -9248,6 +9271,20 @@ |
183 |
|
184 |
return background |
185 |
|
186 |
+ def _get_interactive_tasks(self): |
187 |
+ from portage import flatten |
188 |
+ from portage.dep import use_reduce, paren_reduce |
189 |
+ interactive_tasks = [] |
190 |
+ for task in self._mergelist: |
191 |
+ if not (isinstance(task, Package) and \ |
192 |
+ task.operation == "merge"): |
193 |
+ continue |
194 |
+ properties = flatten(use_reduce(paren_reduce( |
195 |
+ task.metadata["PROPERTIES"]), uselist=task.use.enabled)) |
196 |
+ if "interactive" in properties: |
197 |
+ interactive_tasks.append(task) |
198 |
+ return interactive_tasks |
199 |
+ |
200 |
def _set_digraph(self, digraph): |
201 |
if self._max_jobs is not True and \ |
202 |
self._max_jobs < 2: |
203 |
|
204 |
Modified: main/branches/prefix/pym/portage/__init__.py |
205 |
=================================================================== |
206 |
--- main/branches/prefix/pym/portage/__init__.py 2008-10-28 18:47:54 UTC (rev 11734) |
207 |
+++ main/branches/prefix/pym/portage/__init__.py 2008-10-28 18:51:42 UTC (rev 11735) |
208 |
@@ -5427,46 +5427,13 @@ |
209 |
droppriv=droppriv) |
210 |
|
211 |
# Validate dependency metadata here to ensure that ebuilds with invalid |
212 |
- # data are never installed (even via the ebuild command). |
213 |
- invalid_dep_exempt_phases = \ |
214 |
- set(["clean", "cleanrm", "help", "prerm", "postrm"]) |
215 |
- mycpv = mysettings["CATEGORY"] + "/" + mysettings["PF"] |
216 |
- dep_keys = ["DEPEND", "RDEPEND", "PDEPEND"] |
217 |
- misc_keys = ["LICENSE", "PROPERTIES", "PROVIDE", "RESTRICT", "SRC_URI"] |
218 |
- other_keys = ["SLOT"] |
219 |
- all_keys = dep_keys + misc_keys + other_keys |
220 |
- metadata = dict(izip(all_keys, mydbapi.aux_get(mycpv, all_keys))) |
221 |
- class FakeTree(object): |
222 |
- def __init__(self, mydb): |
223 |
- self.dbapi = mydb |
224 |
- dep_check_trees = {myroot:{}} |
225 |
- dep_check_trees[myroot]["porttree"] = \ |
226 |
- FakeTree(fakedbapi(settings=mysettings)) |
227 |
- for dep_type in dep_keys: |
228 |
- mycheck = dep_check(metadata[dep_type], None, mysettings, |
229 |
- myuse="all", myroot=myroot, trees=dep_check_trees) |
230 |
- if not mycheck[0]: |
231 |
- writemsg("%s: %s\n%s\n" % ( |
232 |
- dep_type, metadata[dep_type], mycheck[1]), noiselevel=-1) |
233 |
- if mydo not in invalid_dep_exempt_phases: |
234 |
- return 1 |
235 |
- del dep_type, mycheck |
236 |
- for k in misc_keys: |
237 |
- try: |
238 |
- portage.dep.use_reduce( |
239 |
- portage.dep.paren_reduce(metadata[k]), matchall=True) |
240 |
- except portage.exception.InvalidDependString, e: |
241 |
- writemsg("%s: %s\n%s\n" % ( |
242 |
- k, metadata[k], str(e)), noiselevel=-1) |
243 |
- del e |
244 |
- if mydo not in invalid_dep_exempt_phases: |
245 |
- return 1 |
246 |
- del k |
247 |
- if not metadata["SLOT"]: |
248 |
- writemsg("SLOT is undefined\n", noiselevel=-1) |
249 |
- if mydo not in invalid_dep_exempt_phases: |
250 |
- return 1 |
251 |
- del mycpv, dep_keys, metadata, misc_keys, FakeTree, dep_check_trees |
252 |
+ # data are never installed via the ebuild command. Don't bother when |
253 |
+ # returnpid == True since there's no need to do this every time emerge |
254 |
+ # executes a phase. |
255 |
+ if not returnpid: |
256 |
+ rval = _validate_deps(mysettings, myroot, mydo, mydbapi) |
257 |
+ if rval != os.EX_OK: |
258 |
+ return rval |
259 |
|
260 |
if "PORTAGE_TMPDIR" not in mysettings or \ |
261 |
not os.path.isdir(mysettings["PORTAGE_TMPDIR"]): |
262 |
@@ -5737,24 +5704,31 @@ |
263 |
mysettings["PORTAGE_ACTUAL_DISTDIR"] = orig_distdir |
264 |
edpath = mysettings["DISTDIR"] = \ |
265 |
os.path.join(mysettings["PORTAGE_BUILDDIR"], "distdir") |
266 |
- if os.path.exists(edpath): |
267 |
+ portage.util.ensure_dirs(edpath, uid=portage_uid, mode=0755) |
268 |
+ |
269 |
+ # Remove any unexpected files or directories. |
270 |
+ for x in os.listdir(edpath): |
271 |
+ symlink_path = os.path.join(edpath, x) |
272 |
+ st = os.lstat(symlink_path) |
273 |
+ if x in alist and stat.S_ISLNK(st.st_mode): |
274 |
+ continue |
275 |
+ if stat.S_ISDIR(st.st_mode): |
276 |
+ shutil.rmtree(symlink_path) |
277 |
+ else: |
278 |
+ os.unlink(symlink_path) |
279 |
+ |
280 |
+ # Check for existing symlinks and recreate if necessary. |
281 |
+ for x in alist: |
282 |
+ symlink_path = os.path.join(edpath, x) |
283 |
+ target = os.path.join(orig_distdir, x) |
284 |
try: |
285 |
- if os.path.isdir(edpath) and not os.path.islink(edpath): |
286 |
- shutil.rmtree(edpath) |
287 |
- else: |
288 |
- os.unlink(edpath) |
289 |
+ link_target = os.readlink(symlink_path) |
290 |
except OSError: |
291 |
- print "!!! Failed reseting ebuild distdir path, " + edpath |
292 |
- raise |
293 |
- os.mkdir(edpath) |
294 |
- apply_secpass_permissions(edpath, uid=portage_uid, mode=0755) |
295 |
- try: |
296 |
- for file in alist: |
297 |
- os.symlink(os.path.join(orig_distdir, file), |
298 |
- os.path.join(edpath, file)) |
299 |
- except OSError: |
300 |
- print "!!! Failed symlinking in '%s' to ebuild distdir" % file |
301 |
- raise |
302 |
+ os.symlink(target, symlink_path) |
303 |
+ else: |
304 |
+ if link_target != target: |
305 |
+ os.unlink(symlink_path) |
306 |
+ os.symlink(target, symlink_path) |
307 |
|
308 |
#initial dep checks complete; time to process main commands |
309 |
|
310 |
@@ -5879,6 +5853,50 @@ |
311 |
# and the exemption is no longer needed. |
312 |
_doebuild_manifest_exempt_depend -= 1 |
313 |
|
314 |
+def _validate_deps(mysettings, myroot, mydo, mydbapi): |
315 |
+ |
316 |
+ invalid_dep_exempt_phases = \ |
317 |
+ set(["clean", "cleanrm", "help", "prerm", "postrm"]) |
318 |
+ dep_keys = ["DEPEND", "RDEPEND", "PDEPEND"] |
319 |
+ misc_keys = ["LICENSE", "PROPERTIES", "PROVIDE", "RESTRICT", "SRC_URI"] |
320 |
+ other_keys = ["SLOT"] |
321 |
+ all_keys = dep_keys + misc_keys + other_keys |
322 |
+ metadata = dict(izip(all_keys, |
323 |
+ mydbapi.aux_get(mysettings.mycpv, all_keys))) |
324 |
+ |
325 |
+ class FakeTree(object): |
326 |
+ def __init__(self, mydb): |
327 |
+ self.dbapi = mydb |
328 |
+ dep_check_trees = {myroot:{}} |
329 |
+ dep_check_trees[myroot]["porttree"] = \ |
330 |
+ FakeTree(fakedbapi(settings=mysettings)) |
331 |
+ |
332 |
+ for dep_type in dep_keys: |
333 |
+ mycheck = dep_check(metadata[dep_type], None, mysettings, |
334 |
+ myuse="all", myroot=myroot, trees=dep_check_trees) |
335 |
+ if not mycheck[0]: |
336 |
+ writemsg("%s: %s\n%s\n" % ( |
337 |
+ dep_type, metadata[dep_type], mycheck[1]), noiselevel=-1) |
338 |
+ if mydo not in invalid_dep_exempt_phases: |
339 |
+ return 1 |
340 |
+ |
341 |
+ for k in misc_keys: |
342 |
+ try: |
343 |
+ portage.dep.use_reduce( |
344 |
+ portage.dep.paren_reduce(metadata[k]), matchall=True) |
345 |
+ except portage.exception.InvalidDependString, e: |
346 |
+ writemsg("%s: %s\n%s\n" % ( |
347 |
+ k, metadata[k], str(e)), noiselevel=-1) |
348 |
+ if mydo not in invalid_dep_exempt_phases: |
349 |
+ return 1 |
350 |
+ |
351 |
+ if not metadata["SLOT"]: |
352 |
+ writemsg("SLOT is undefined\n", noiselevel=-1) |
353 |
+ if mydo not in invalid_dep_exempt_phases: |
354 |
+ return 1 |
355 |
+ |
356 |
+ return os.EX_OK |
357 |
+ |
358 |
expandcache={} |
359 |
|
360 |
def _movefile(src, dest, **kwargs): |
361 |
|
362 |
Modified: main/branches/prefix/pym/portage/dbapi/vartree.py |
363 |
=================================================================== |
364 |
--- main/branches/prefix/pym/portage/dbapi/vartree.py 2008-10-28 18:47:54 UTC (rev 11734) |
365 |
+++ main/branches/prefix/pym/portage/dbapi/vartree.py 2008-10-28 18:51:42 UTC (rev 11735) |
366 |
@@ -2373,6 +2373,8 @@ |
367 |
# their real target before the object is found not to be |
368 |
# in the reverse NEEDED map |
369 |
def symlink_compare(x, y): |
370 |
+ x = os.path.join(self.myroot, x.lstrip(os.path.sep)) |
371 |
+ y = os.path.join(self.myroot, y.lstrip(os.path.sep)) |
372 |
if os.path.islink(x): |
373 |
if os.path.islink(y): |
374 |
return 0 |
375 |
@@ -2385,20 +2387,23 @@ |
376 |
|
377 |
plib_dict[cpv].sort(symlink_compare) |
378 |
for f in plib_dict[cpv]: |
379 |
- if not os.path.exists(f): |
380 |
+ f_abs = os.path.join(self.myroot, f.lstrip(os.path.sep)) |
381 |
+ if not os.path.exists(f_abs): |
382 |
continue |
383 |
unlink_list = [] |
384 |
consumers = self.vartree.dbapi.linkmap.findConsumers(f) |
385 |
if not consumers: |
386 |
- unlink_list.append(f) |
387 |
+ unlink_list.append(f_abs) |
388 |
else: |
389 |
keep=False |
390 |
for c in consumers: |
391 |
+ c = os.path.join(self.myroot, |
392 |
+ c.lstrip(os.path.sep)) |
393 |
if c not in self.getcontents(): |
394 |
keep=True |
395 |
break |
396 |
if not keep: |
397 |
- unlink_list.append(f) |
398 |
+ unlink_list.append(f_abs) |
399 |
for obj in unlink_list: |
400 |
try: |
401 |
if os.path.islink(obj): |
402 |
|
403 |
Modified: main/branches/prefix/pym/repoman/checks.py |
404 |
=================================================================== |
405 |
--- main/branches/prefix/pym/repoman/checks.py 2008-10-28 18:47:54 UTC (rev 11734) |
406 |
+++ main/branches/prefix/pym/repoman/checks.py 2008-10-28 18:51:42 UTC (rev 11735) |
407 |
@@ -232,12 +232,21 @@ |
408 |
"eautomake", "eautoreconf", "_elibtoolize") |
409 |
_autotools_func_re = re.compile(r'(^|\s)(' + \ |
410 |
"|".join(_autotools_funcs) + ')(\s|$)') |
411 |
+ # Exempt eclasses: |
412 |
+ # git - An EGIT_BOOTSTRAP variable may be used to call one of |
413 |
+ # the autotools functions. |
414 |
+ # subversion - An ESVN_BOOTSTRAP variable may be used to call one of |
415 |
+ # the autotools functions. |
416 |
+ _exempt_eclasses = frozenset(["git", "subversion"]) |
417 |
|
418 |
def new(self, pkg): |
419 |
self._inherit_autotools = None |
420 |
self._autotools_func_call = None |
421 |
+ self._disabled = self._exempt_eclasses.intersection(pkg.inherited) |
422 |
|
423 |
def check(self, num, line): |
424 |
+ if self._disabled: |
425 |
+ return |
426 |
if self._inherit_autotools is None: |
427 |
self._inherit_autotools = self._inherit_autotools_re.match(line) |
428 |
if self._inherit_autotools is not None and \ |