Gentoo Archives: gentoo-commits

From: "Fabian Groffen (grobian)" <grobian@g.o>
To: gentoo-commits@l.g.o
Subject: [gentoo-commits] portage r11286 - in main/branches/prefix: doc/package/ebuild/eapi man pym/_emerge pym/portage pym/portage/sets
Date: Wed, 30 Jul 2008 13:55:46
Message-Id: E1KOC9W-0006Wp-R9@stork.gentoo.org
1 Author: grobian
2 Date: 2008-07-30 13:55:41 +0000 (Wed, 30 Jul 2008)
3 New Revision: 11286
4
5 Modified:
6 main/branches/prefix/doc/package/ebuild/eapi/2.docbook
7 main/branches/prefix/man/emerge.1
8 main/branches/prefix/pym/_emerge/__init__.py
9 main/branches/prefix/pym/_emerge/help.py
10 main/branches/prefix/pym/portage/dep.py
11 main/branches/prefix/pym/portage/sets/dbapi.py
12 main/branches/prefix/pym/portage/util.py
13 Log:
14 Merged from trunk 11248:11267
15
16 | 11249 | Bug #233165 - When waiting for jobs and merges to finish in |
17 | zmedico | Scheduler._main_loop(), keep scheduling the merge queue |
18 | | since it doesn't autoschedule, and skip the poll loop if |
19 | | there no event handlers due to synchronous merge tasks being |
20 | | the only things left to do. |
21
22 | 11250 | Fix broken reference to "categories" in |
23 | zmedico | CategorySet.singleBuilder(). Thanks to Thargor for |
24 | | reporting. |
25
26 | 11251 | Make use of the new config.iteritems() method. |
27 | zmedico | |
28
29 | 11252 | Document the doman language code path translation extension |
30 | zmedico | from bug #222439. |
31
32 | 11253 | Tweak the conditional USE deps examples. |
33 | zmedico | |
34
35 | 11254 | Fix alignment. |
36 | zmedico | |
37
38 | 11255 | Add syntax examples for unconditional USE deps. |
39 | zmedico | |
40
41 | 11256 | Redirect the FEATURES=buildsyspkg message to the log when in |
42 | zmedico | background mode. |
43
44 | 11257 | Fix _use_dep.__str__() to work correctly in the case when |
45 | zmedico | conditional USE deps have evaluated to nothing (empty string |
46 | | rather than []). Thanks to ABCD for reporting. |
47
48 | 11258 | Implement _use_dep.__nonzero__(). |
49 | zmedico | |
50
51 | 11259 | Tweak table alignment. |
52 | zmedico | |
53
54 | 11260 | In apply_recursive_permissions(), ignore InvalidLocation |
55 | zmedico | exceptions such as FileNotFound and DirectoryNotFound since |
56 | | sometimes things disappear, like when adjusting permissions |
57 | | on DISTCC_DIR. |
58
59 | 11261 | Add support for the --jobs option to be specified without an |
60 | zmedico | argument, and also support -j as a short option. Since |
61 | | optparse doesn't natively support options with non-required |
62 | | args, create an insert_optional_args() function that inserts |
63 | | the required argument into the args so that optparse is |
64 | | happy. The function inserts the string True as a substitute |
65 | | for the argument that is required. This string is later |
66 | | converted to the True constant when stored in the emerge |
67 | | opts dict (similar to how normal boolean options are |
68 | | stored). The PollScheduler and SequentialTaskQueue classes |
69 | | recognize the meaning of the True constant to mean unlimited |
70 | | concurrent jobs. |
71
72 | 11262 | Fix slightly broken loop logic in insert_optional_args() by |
73 | zmedico | converting it to pop args off of a stack. |
74
75 | 11263 | During the first minute of entering the main scheduler loop, |
76 | zmedico | if --load-average is enabled then limit the rate that new |
77 | | jobs are spawned, so that the load average measurement has |
78 | | time to respond to the new load introduced by the new jobs. |
79 | | The time between spawning new jobs is proportional to the |
80 | | number of currently running jobs. |
81
82 | 11264 | Enable Scheduler._job_delay() whenever --load-average is |
83 | zmedico | enabled, for whole time the scheduler is running. This |
84 | | protects against too many jobs being sheduled if the load |
85 | | average temporarily drops. |
86
87 | 11265 | Fix Scheduler._choose_pkg() so that it doesn't choose |
88 | zmedico | packages prematurely in some cases. |
89
90 | 11266 | Make sure Scheduler._choose_pkg() doesn't return a package |
91 | zmedico | too early when there's no digraph and the previous merge |
92 | | hasn't completed yet. |
93
94 | 11267 | Fix Scheduler._set_digraph() to correctly handle cases when |
95 | zmedico | max_jobs is True. |
96
97
98 Modified: main/branches/prefix/doc/package/ebuild/eapi/2.docbook
99 ===================================================================
100 --- main/branches/prefix/doc/package/ebuild/eapi/2.docbook 2008-07-30 10:27:58 UTC (rev 11285)
101 +++ main/branches/prefix/doc/package/ebuild/eapi/2.docbook 2008-07-30 13:55:41 UTC (rev 11286)
102 @@ -1,7 +1,67 @@
103 <sect1 id='package-ebuild-eapi-2'>
104 <title>EAPI 2_pre0</title>
105 + <sect2 id='package-ebuild-eapi-2-helpers'>
106 + <title>Helpers</title>
107 + <sect3 id='package-ebuild-eapi-2-helpers-doman'>
108 + <title>doman</title>
109 + <para>
110 + Language codes in file names are now used for path translation.
111 + </para>
112 + <table><title>Man Page Path Translation</title>
113 + <tgroup cols='2' align='left' >
114 + <colspec colname='source'/>
115 + <colspec colname='destination'/>
116 + <thead>
117 + <row>
118 + <entry>Source</entry>
119 + <entry>Destination</entry>
120 + </row>
121 + </thead>
122 + <tbody>
123 + <row>
124 + <entry>foo.1</entry>
125 + <entry>/usr/share/man/man1/foo.1</entry>
126 + </row>
127 + <row>
128 + <entry>foo.lang.1</entry>
129 + <entry>/usr/share/man/lang/man1/foo.1</entry>
130 + </row>
131 + </tbody>
132 + </tgroup>
133 + </table>
134 + </sect3>
135 + </sect2>
136 <sect2 id='package-ebuild-eapi-2-use-deps'>
137 <title>USE Dependencies</title>
138 + <sect3 id='package-ebuild-eapi-2-use-deps-unconditional'>
139 + <title>Unconditional USE Dependencies</title>
140 + <table><title>Syntax Examples</title>
141 + <tgroup cols='2' align='left' >
142 + <colspec colname='example'/>
143 + <colspec colname='meaning'/>
144 + <thead>
145 + <row>
146 + <entry>Example</entry>
147 + <entry>Meaning</entry>
148 + </row>
149 + </thead>
150 + <tbody>
151 + <row>
152 + <entry>foo[bar]</entry>
153 + <entry>foo must have bar enabled</entry>
154 + </row>
155 + <row>
156 + <entry>foo[bar,baz]</entry>
157 + <entry>foo must have both bar and baz enabled</entry>
158 + </row>
159 + <row>
160 + <entry>foo[-bar,baz]</entry>
161 + <entry>foo must have bar disabled and baz enabled</entry>
162 + </row>
163 + </tbody>
164 + </tgroup>
165 + </table>
166 + </sect3>
167 <sect3 id='package-ebuild-eapi-2-use-deps-conditional'>
168 <title>Conditional USE Dependencies</title>
169 <table><title>Syntax Examples</title>
170 @@ -17,19 +77,19 @@
171 <tbody>
172 <row>
173 <entry>foo[bar?]</entry>
174 - <entry>foo bar? ( foo[bar] )</entry>
175 + <entry>bar? ( foo[bar] ) !bar? ( foo )</entry>
176 </row>
177 <row>
178 <entry>foo[-bar?]</entry>
179 - <entry>foo !bar? ( foo[-bar] )</entry>
180 + <entry>bar? ( foo ) !bar? ( foo[-bar] )</entry>
181 </row>
182 <row>
183 <entry>foo[bar=]</entry>
184 - <entry>foo bar? ( foo[bar] ) !bar? ( foo[-bar] )</entry>
185 + <entry>bar? ( foo[bar] ) !bar? ( foo[-bar] )</entry>
186 </row>
187 <row>
188 <entry>foo[bar!=]</entry>
189 - <entry>foo bar? ( foo[-bar] ) !bar? ( foo[bar] )</entry>
190 + <entry>bar? ( foo[-bar] ) !bar? ( foo[bar] )</entry>
191 </row>
192 </tbody>
193 </tgroup>
194
195 Modified: main/branches/prefix/man/emerge.1
196 ===================================================================
197 --- main/branches/prefix/man/emerge.1 2008-07-30 10:27:58 UTC (rev 11285)
198 +++ main/branches/prefix/man/emerge.1 2008-07-30 13:55:41 UTC (rev 11286)
199 @@ -323,9 +323,10 @@
200 .BR "\-\-ignore-default-opts"
201 Causes \fIEMERGE_DEFAULT_OPTS\fR (see \fBmake.conf\fR(5)) to be ignored.
202 .TP
203 -.BR \-\-jobs=JOBS
204 -Specifies the number of packages to build simultaneously. Also see
205 -the related \fB\-\-load\-average\fR option.
206 +.BR "-j [JOBS], \-\-jobs[=JOBS]"
207 +Specifies the number of packages to build simultaneously. If this option is
208 +given without an argument, emerge will not limit the number of jobs that can
209 +run simultaneously. Also see the related \fB\-\-load\-average\fR option.
210 .TP
211 .BR "\-\-keep\-going"
212 Continue as much as possible after an error. When an error occurs,
213
214 Modified: main/branches/prefix/pym/_emerge/__init__.py
215 ===================================================================
216 --- main/branches/prefix/pym/_emerge/__init__.py 2008-07-30 10:27:58 UTC (rev 11285)
217 +++ main/branches/prefix/pym/_emerge/__init__.py 2008-07-30 13:55:41 UTC (rev 11286)
218 @@ -2348,7 +2348,7 @@
219 __slots__ = ("args_set", "background", "find_blockers",
220 "ldpath_mtimes", "logger", "opts", "pkg", "pkg_count",
221 "prefetcher", "settings", "world_atom") + \
222 - ("_build_dir", "_buildpkg", "_ebuild_path", "_tree")
223 + ("_build_dir", "_buildpkg", "_ebuild_path", "_issyspkg", "_tree")
224
225 def _start(self):
226
227 @@ -2460,16 +2460,13 @@
228 logger.log(msg, short_msg=short_msg)
229
230 #buildsyspkg: Check if we need to _force_ binary package creation
231 - issyspkg = "buildsyspkg" in features and \
232 + self._issyspkg = "buildsyspkg" in features and \
233 system_set.findAtomForPackage(pkg) and \
234 not opts.buildpkg
235
236 - if opts.buildpkg or issyspkg:
237 + if opts.buildpkg or self._issyspkg:
238
239 self._buildpkg = True
240 - if issyspkg:
241 - portage.writemsg_stdout(">>> This is a system package, " + \
242 - "let's pack a rescue tarball.\n", noiselevel=-1)
243
244 msg = " === (%s of %s) Compiling/Packaging (%s::%s)" % \
245 (pkg_count.curval, pkg_count.maxval, pkg.cpv, ebuild_path)
246 @@ -2506,6 +2503,21 @@
247 self.wait()
248 return
249
250 + if self._issyspkg:
251 + msg = ">>> This is a system package, " + \
252 + "let's pack a rescue tarball.\n"
253 +
254 + log_path = self.settings.get("PORTAGE_LOG_FILE")
255 + if log_path is not None:
256 + log_file = open(log_path, 'a')
257 + try:
258 + log_file.write(msg)
259 + finally:
260 + log_file.close()
261 +
262 + if not self.background:
263 + portage.writemsg_stdout(msg, noiselevel=-1)
264 +
265 packager = EbuildBinpkg(background=self.background, pkg=self.pkg,
266 scheduler=self.scheduler, settings=self.settings)
267
268 @@ -3286,7 +3298,7 @@
269 "FILE" : os.path.basename(pkg_path)
270 }
271
272 - fetch_env = dict((k, settings[k]) for k in settings)
273 + fetch_env = dict(settings.iteritems())
274 fetch_args = [portage.util.varexpand(x, mydict=fcmd_vars) \
275 for x in shlex.split(fcmd)]
276
277 @@ -8182,7 +8194,8 @@
278 if task.poll() is not None:
279 state_changed = True
280
281 - while task_queue and (len(running_tasks) < max_jobs):
282 + while task_queue and \
283 + (max_jobs is True or len(running_tasks) < max_jobs):
284 task = task_queue.popleft()
285 cancelled = getattr(task, "cancelled", None)
286 if not cancelled:
287 @@ -8300,10 +8313,12 @@
288 max_jobs = self._max_jobs
289 max_load = self._max_load
290
291 - if self._running_job_count() >= self._max_jobs:
292 + if self._max_jobs is not True and \
293 + self._running_job_count() >= self._max_jobs:
294 return False
295
296 - if max_load is not None and max_jobs > 1 and \
297 + if max_load is not None and \
298 + (max_jobs is True or max_jobs > 1) and \
299 self._running_job_count() > 1:
300 try:
301 avg1, avg5, avg15 = os.getloadavg()
302 @@ -8886,6 +8901,12 @@
303
304 self._max_load = myopts.get("--load-average")
305
306 + # The load average takes some time to respond when new
307 + # jobs are added, so we need to limit the rate of adding
308 + # new jobs.
309 + self._job_delay_factor = 0.5
310 + self._previous_job_start_time = None
311 +
312 self._set_digraph(digraph)
313
314 # This is used to memoize the _choose_pkg() result when
315 @@ -8940,7 +8961,8 @@
316 @rtype: bool
317 @returns: True if background mode is enabled, False otherwise.
318 """
319 - background = (self._max_jobs > 1 or "--quiet" in self.myopts) and \
320 + background = (self._max_jobs is True or \
321 + self._max_jobs > 1 or "--quiet" in self.myopts) and \
322 not bool(self._opts_no_background.intersection(self.myopts))
323
324 self._status_display.quiet = \
325 @@ -8955,7 +8977,8 @@
326 return background
327
328 def _set_digraph(self, digraph):
329 - if self._max_jobs < 2:
330 + if self._max_jobs is not True and \
331 + self._max_jobs < 2:
332 # save some memory
333 self._digraph = None
334 return
335 @@ -9587,7 +9610,10 @@
336 if self._choose_pkg_return_early:
337 return None
338
339 - if self._max_jobs < 2 or self._jobs == 0:
340 + if self._digraph is None:
341 + if self._jobs or self._task_queues.merge:
342 + self._choose_pkg_return_early = True
343 + return None
344 return self._pkg_queue.pop(0)
345
346 self._prune_digraph()
347 @@ -9664,6 +9690,9 @@
348 self._poll_loop()
349
350 while self._jobs or merge_queue:
351 + if merge_queue.schedule() and \
352 + not self._poll_event_handlers:
353 + continue
354 self._poll_loop()
355
356 def _schedule_tasks(self):
357 @@ -9679,6 +9708,22 @@
358 self._status_display.display()
359 return remaining
360
361 + def _job_delay(self):
362 + """
363 + @rtype: bool
364 + @returns: True if job scheduling should be delayed, False otherwise.
365 + """
366 +
367 + if self._jobs and self._max_load is not None:
368 +
369 + current_time = time.time()
370 +
371 + if current_time - self._previous_job_start_time < \
372 + self._job_delay_factor * self._jobs:
373 + return True
374 +
375 + return False
376 +
377 def _schedule_tasks_imp(self):
378 """
379 @rtype: bool
380 @@ -9693,7 +9738,8 @@
381 return (False, state_change)
382
383 if self._choose_pkg_return_early or \
384 - not self._can_add_job():
385 + not self._can_add_job() or \
386 + self._job_delay():
387 return (True, state_change)
388
389 pkg = self._choose_pkg()
390 @@ -9714,12 +9760,14 @@
391
392 elif pkg.built:
393 self._jobs += 1
394 + self._previous_job_start_time = time.time()
395 self._status_display.running = self._jobs
396 task.addExitListener(self._extract_exit)
397 self._task_queues.jobs.add(task)
398
399 else:
400 self._jobs += 1
401 + self._previous_job_start_time = time.time()
402 self._status_display.running = self._jobs
403 task.addExitListener(self._build_exit)
404 self._task_queues.jobs.add(task)
405 @@ -12798,6 +12846,63 @@
406 sys.stderr.write("!!! '%s' or '%s'\n\n" % (action1, action2))
407 sys.exit(1)
408
409 +def insert_optional_args(args):
410 + """
411 + Parse optional arguments and insert a value if one has
412 + not been provided. This is done before feeding the args
413 + to the optparse parser since that parser does not support
414 + this feature natively.
415 + """
416 +
417 + new_args = []
418 + jobs_opts = ("-j", "--jobs")
419 + arg_stack = args[:]
420 + arg_stack.reverse()
421 + while arg_stack:
422 + arg = arg_stack.pop()
423 +
424 + short_job_opt = bool("j" in arg and arg[:1] == "-" and arg[:2] != "--")
425 + if not (short_job_opt or arg in jobs_opts):
426 + new_args.append(arg)
427 + continue
428 +
429 + # Insert an empty placeholder in order to
430 + # satisfy the requirements of optparse.
431 +
432 + new_args.append("--jobs")
433 + job_count = None
434 + saved_opts = None
435 + if short_job_opt and len(arg) > 2:
436 + if arg[:2] == "-j":
437 + try:
438 + job_count = int(arg[2:])
439 + except ValueError:
440 + saved_opts = arg[2:]
441 + else:
442 + job_count = "True"
443 + saved_opts = arg[1:].replace("j", "")
444 +
445 + if job_count is None and arg_stack:
446 + try:
447 + job_count = int(arg_stack[-1])
448 + except ValueError:
449 + pass
450 + else:
451 + # Discard the job count from the stack
452 + # since we're consuming it here.
453 + arg_stack.pop()
454 +
455 + if job_count is None:
456 + # unlimited number of jobs
457 + new_args.append("True")
458 + else:
459 + new_args.append(str(job_count))
460 +
461 + if saved_opts is not None:
462 + new_args.append("-" + saved_opts)
463 +
464 + return new_args
465 +
466 def parse_opts(tmpcmdline, silent=False):
467 myaction=None
468 myopts = {}
469 @@ -12868,15 +12973,22 @@
470 parser.add_option(myopt,
471 dest=myopt.lstrip("--").replace("-", "_"), **kwargs)
472
473 + tmpcmdline = insert_optional_args(tmpcmdline)
474 +
475 myoptions, myargs = parser.parse_args(args=tmpcmdline)
476
477 if myoptions.jobs:
478 - try:
479 - jobs = int(myoptions.jobs)
480 - except ValueError:
481 - jobs = 0
482 + jobs = None
483 + if myoptions.jobs == "True":
484 + jobs = True
485 + else:
486 + try:
487 + jobs = int(myoptions.jobs)
488 + except ValueError:
489 + jobs = -1
490
491 - if jobs < 1:
492 + if jobs is not True and \
493 + jobs < 1:
494 jobs = None
495 if not silent:
496 writemsg("!!! Invalid --jobs parameter: '%s'\n" % \
497
498 Modified: main/branches/prefix/pym/_emerge/help.py
499 ===================================================================
500 --- main/branches/prefix/pym/_emerge/help.py 2008-07-30 10:27:58 UTC (rev 11285)
501 +++ main/branches/prefix/pym/_emerge/help.py 2008-07-30 13:55:41 UTC (rev 11286)
502 @@ -14,7 +14,7 @@
503 print " "+turquoise("emerge")+" < "+turquoise("--sync")+" | "+turquoise("--metadata")+" | "+turquoise("--info")+" >"
504 print " "+turquoise("emerge")+" "+turquoise("--resume")+" [ "+green("--pretend")+" | "+green("--ask")+" | "+green("--skipfirst")+" ]"
505 print " "+turquoise("emerge")+" "+turquoise("--help")+" [ "+green("system")+" | "+green("world")+" | "+green("--sync")+" ] "
506 - print bold("Options:")+" "+green("-")+"["+green("abBcCdDefgGhkKlnNoOpqPsStuvV")+"]"
507 + print bold("Options:")+" "+green("-")+"["+green("abBcCdDefgGhjkKlnNoOpqPsStuvV")+"]"
508 print " [ " + green("--color")+" < " + turquoise("y") + " | "+ turquoise("n")+" > ] [ "+green("--columns")+" ]"
509 print " [ "+green("--complete-graph")+" ] [ "+green("--deep")+" ]"
510 print " [ "+green("--jobs") + " " + turquoise("JOBS")+" ] [ "+green("--keep-going")+" ] [ " + green("--load-average")+" " + turquoise("LOAD") + " ]"
511 @@ -305,9 +305,12 @@
512 print " downloaded from the remote server without consulting packages"
513 print " existing in the packages directory."
514 print
515 - print " " + green("--jobs") + " " + turquoise("JOBS")
516 + print " " + green("--jobs") + " " + turquoise("[JOBS]") + " ("+green("-j")+" short option)"
517 desc = "Specifies the number of packages " + \
518 - "to build simultaneously. Also see " + \
519 + "to build simultaneously. If this option is " + \
520 + "given without an argument, emerge will not " + \
521 + "limit the number of jobs that " + \
522 + "can run simultaneously. Also see " + \
523 "the related --load-average option."
524 for line in wrap(desc, desc_width):
525 print desc_indent + line
526
527 Modified: main/branches/prefix/pym/portage/dep.py
528 ===================================================================
529 --- main/branches/prefix/pym/portage/dep.py 2008-07-30 10:27:58 UTC (rev 11285)
530 +++ main/branches/prefix/pym/portage/dep.py 2008-07-30 13:55:41 UTC (rev 11286)
531 @@ -395,7 +395,12 @@
532 self.conditional = conditional
533 break
534
535 + def __nonzero__(self):
536 + return bool(self.tokens)
537 +
538 def __str__(self):
539 + if not self.tokens:
540 + return ""
541 return "[%s]" % (",".join(self.tokens),)
542
543 def evaluate_conditionals(self, use):
544 @@ -413,17 +418,17 @@
545
546 x x= x
547 -x x= -x
548 - x x!= -x
549 - -x x!= x
550 + x x!= -x
551 + -x x!= x
552
553 Conditional syntax examples:
554
555 compact form equivalent expanded form
556
557 - foo[bar?] foo bar? ( foo[bar] )
558 - foo[-bar?] foo !bar? ( foo[-bar] )
559 - foo[bar=] foo bar? ( foo[bar] ) !bar? ( foo[-bar] )
560 - foo[bar!=] foo bar? ( foo[-bar] ) !bar? ( foo[bar] )
561 + foo[bar?] bar? ( foo[bar] ) !bar? ( foo )
562 + foo[-bar?] bar? ( foo ) !bar? ( foo[-bar] )
563 + foo[bar=] bar? ( foo[bar] ) !bar? ( foo[-bar] )
564 + foo[bar!=] bar? ( foo[-bar] ) !bar? ( foo[bar] )
565
566 """
567 tokens = []
568
569 Modified: main/branches/prefix/pym/portage/sets/dbapi.py
570 ===================================================================
571 --- main/branches/prefix/pym/portage/sets/dbapi.py 2008-07-30 10:27:58 UTC (rev 11285)
572 +++ main/branches/prefix/pym/portage/sets/dbapi.py 2008-07-30 13:55:41 UTC (rev 11286)
573 @@ -70,7 +70,7 @@
574 raise SetConfigError("no category given")
575
576 category = options["category"]
577 - if not category in categories:
578 + if not category in settings.categories:
579 raise SetConfigError("invalid category name '%s'" % category)
580
581 repository = cls._builderGetRepository(options, trees.keys())
582
583 Modified: main/branches/prefix/pym/portage/util.py
584 ===================================================================
585 --- main/branches/prefix/pym/portage/util.py 2008-07-30 10:27:58 UTC (rev 11285)
586 +++ main/branches/prefix/pym/portage/util.py 2008-07-30 13:55:41 UTC (rev 11286)
587 @@ -801,8 +801,12 @@
588 if not applied:
589 all_applied = False
590 except PortageException, e:
591 - all_applied = False
592 - onerror(e)
593 + # Ignore InvalidLocation exceptions such as FileNotFound
594 + # and DirectoryNotFound since sometimes things disappear,
595 + # like when adjusting permissions on DISTCC_DIR.
596 + if not isinstance(e, portage.exception.InvalidLocation):
597 + all_applied = False
598 + onerror(e)
599 return all_applied
600
601 def apply_secpass_permissions(filename, uid=-1, gid=-1, mode=-1, mask=-1,