1 |
Author: grobian |
2 |
Date: 2009-06-19 19:25:10 +0000 (Fri, 19 Jun 2009) |
3 |
New Revision: 13653 |
4 |
|
5 |
Modified: |
6 |
main/branches/prefix/bin/repoman |
7 |
main/branches/prefix/man/color.map.5 |
8 |
main/branches/prefix/man/make.conf.5 |
9 |
main/branches/prefix/pym/_emerge/__init__.py |
10 |
main/branches/prefix/pym/portage/__init__.py |
11 |
main/branches/prefix/pym/portage/output.py |
12 |
Log: |
13 |
Merged from trunk -r13640:13652 |
14 |
|
15 |
| 13641 | Misc fixes and updates. Thanks to Sebastian Mingramm (few) | |
16 |
| zmedico | <s.mingramm@×××.de> for this patch from bug #274279. | |
17 |
|
18 |
| 13642 | Escape hyphens from previous commit. | |
19 |
| zmedico | | |
20 |
|
21 |
| 13643 | Bug #274279 - Add color.map support for mapping a color to a | |
22 |
| zmedico | different color (rather than just mapping a class/style to a | |
23 |
| | different color). Thanks to Sebastian Mingramm (few) | |
24 |
| | <s.mingramm@×××.de> for this patch. | |
25 |
|
26 |
| 13644 | Use map_code_to_color_code() where appropriate inside | |
27 |
| zmedico | ConsoleStyleFile.write(). | |
28 |
|
29 |
| 13645 | Add epydoc docstrings fro codes and color_codes variables. | |
30 |
| zmedico | | |
31 |
|
32 |
| 13646 | Rename map_code_to_color_code() to style_to_ansi_code(). | |
33 |
| zmedico | | |
34 |
|
35 |
| 13647 | Rename codes to _styles. | |
36 |
| zmedico | | |
37 |
|
38 |
| 13648 | Rename color_codes back to codes. | |
39 |
| zmedico | | |
40 |
|
41 |
| 13649 | Add NOCOLOR to the environment whitelist. This fixes | |
42 |
| zmedico | inappropriate colors produced by elog functions. Thanks to | |
43 |
| | Luis F. Araujo <araujo@g.o> for reporting. | |
44 |
|
45 |
| 13650 | When --pretend overrides --ask, don't show any output. | |
46 |
| zmedico | | |
47 |
|
48 |
| 13651 | Allow missing ChangeLog when using git. We don't use | |
49 |
| zmedico | ChangeLogs in distributed SCMs. It will be generated on | |
50 |
| | server side from scm log, before package moves to the rsync | |
51 |
| | server. This is needed because we try to avoid merge | |
52 |
| | collisions. Thanks to Tomas Chvatal <scarabeus@g.o> | |
53 |
| | for this patch. | |
54 |
|
55 |
| 13652 | Add a EMERGE_LOG_DIR variable to control the location of | |
56 |
| zmedico | emerge.log and emerge-fetch.log. This was requested by Eitan | |
57 |
| | Mosenkis <eitan@××××××××.net> for use in his 'online image | |
58 |
| | builder' soc project. | |
59 |
|
60 |
|
61 |
Modified: main/branches/prefix/bin/repoman |
62 |
=================================================================== |
63 |
--- main/branches/prefix/bin/repoman 2009-06-18 19:55:17 UTC (rev 13652) |
64 |
+++ main/branches/prefix/bin/repoman 2009-06-19 19:25:10 UTC (rev 13653) |
65 |
@@ -1113,8 +1113,11 @@ |
66 |
relative_path + ': %s' % error_match.group(1)) |
67 |
|
68 |
del mydigests |
69 |
- |
70 |
- if "ChangeLog" not in checkdirlist: |
71 |
+ # Note: We don't use ChangeLogs in distributed SCMs. |
72 |
+ # It will be generated on server side from scm log, |
73 |
+ # before package moves to the rsync server. |
74 |
+ # This is needed because we try to avoid merge collisions. |
75 |
+ if vcs not in ( "git", ) and "ChangeLog" not in checkdirlist: |
76 |
stats["changelog.missing"]+=1 |
77 |
fails["changelog.missing"].append(x+"/ChangeLog") |
78 |
|
79 |
|
80 |
Modified: main/branches/prefix/man/color.map.5 |
81 |
=================================================================== |
82 |
--- main/branches/prefix/man/color.map.5 2009-06-18 19:55:17 UTC (rev 13652) |
83 |
+++ main/branches/prefix/man/color.map.5 2009-06-19 19:25:10 UTC (rev 13653) |
84 |
@@ -9,9 +9,14 @@ |
85 |
of given color class is found in /etc/portage/color.map, Portage uses default |
86 |
value defined internally. |
87 |
.SH "SYNTAX" |
88 |
-\fBVARIABLE\fR = \fI[space delimited list of attributes]\fR |
89 |
+\fBVARIABLE\fR = \fI[space delimited list of attributes or ansi code pattern]\fR |
90 |
+.TP |
91 |
+\fBATTRIBUTE\fR = \fI[space delimited list of attributes or ansi code pattern]\fR |
92 |
.SH "VARIABLES" |
93 |
.TP |
94 |
+\fBNORMAL\fR = \fI"normal"\fR |
95 |
+Defines color used for some words occuring in other contexts than those below. |
96 |
+.TP |
97 |
\fBBAD\fR = \fI"red"\fR |
98 |
Defines color used for some words occuring in bad context. |
99 |
.TP |
100 |
@@ -89,10 +94,12 @@ |
101 |
.TP |
102 |
.B green |
103 |
.TP |
104 |
-\fBbrown\fR = \fBdarkyellow\fR |
105 |
+.B brown |
106 |
.TP |
107 |
.B yellow |
108 |
.TP |
109 |
+.B darkyellow |
110 |
+.TP |
111 |
.B darkblue |
112 |
.TP |
113 |
.B blue |
114 |
@@ -103,7 +110,7 @@ |
115 |
.TP |
116 |
.B teal |
117 |
.TP |
118 |
-.B turquoise |
119 |
+\fBturquoise\fR = \fBdarkteal\fR |
120 |
.TP |
121 |
.B lightgray |
122 |
.TP |
123 |
@@ -133,6 +140,10 @@ |
124 |
.B Other attributes |
125 |
.RS |
126 |
.TP |
127 |
+.B normal |
128 |
+.TP |
129 |
+.B no\-attr |
130 |
+.TP |
131 |
.B reset |
132 |
.TP |
133 |
.B bold |
134 |
@@ -141,11 +152,25 @@ |
135 |
.TP |
136 |
.B standout |
137 |
.TP |
138 |
+.B no\-standout |
139 |
+.TP |
140 |
.B underline |
141 |
.TP |
142 |
+.B no\-underline |
143 |
+.TP |
144 |
.B blink |
145 |
.TP |
146 |
+.B no\-blink |
147 |
+.TP |
148 |
+.B overline |
149 |
+.TP |
150 |
+.B no\-overline |
151 |
+.TP |
152 |
.B reverse |
153 |
+.TP |
154 |
+.B no\-reverse |
155 |
+.TP |
156 |
+.B invisible |
157 |
.RE |
158 |
.SH "REPORTING BUGS" |
159 |
Please report bugs via http://bugs.gentoo.org/ |
160 |
|
161 |
Modified: main/branches/prefix/man/make.conf.5 |
162 |
=================================================================== |
163 |
--- main/branches/prefix/man/make.conf.5 2009-06-18 19:55:17 UTC (rev 13652) |
164 |
+++ main/branches/prefix/man/make.conf.5 2009-06-19 19:25:10 UTC (rev 13653) |
165 |
@@ -130,6 +130,11 @@ |
166 |
These options will not be appended to the command line if \-\-ignore\-default\-opts |
167 |
is specified. |
168 |
.TP |
169 |
+.B EMERGE_LOG_DIR |
170 |
+Controls the location of emerge.log and emerge-fetch.log. |
171 |
+.br |
172 |
+Defaults to /var/log. |
173 |
+.TP |
174 |
.B EPAUSE_IGNORE |
175 |
Defines whether or not to ignore short pauses that occur when displaying |
176 |
important informational messages. This variable is unset by default. |
177 |
|
178 |
Modified: main/branches/prefix/pym/_emerge/__init__.py |
179 |
=================================================================== |
180 |
--- main/branches/prefix/pym/_emerge/__init__.py 2009-06-18 19:55:17 UTC (rev 13652) |
181 |
+++ main/branches/prefix/pym/_emerge/__init__.py 2009-06-19 19:25:10 UTC (rev 13653) |
182 |
@@ -253,13 +253,15 @@ |
183 |
"v":"--verbose", "V":"--version" |
184 |
} |
185 |
|
186 |
+_emerge_log_dir = EPREFIX+'/var/log' |
187 |
+ |
188 |
def emergelog(xterm_titles, mystr, short_msg=None): |
189 |
if xterm_titles and short_msg: |
190 |
if "HOSTNAME" in os.environ: |
191 |
short_msg = os.environ["HOSTNAME"]+": "+short_msg |
192 |
xtermTitle(short_msg) |
193 |
try: |
194 |
- file_path = EPREFIX+"/var/log/emerge.log" |
195 |
+ file_path = os.path.join(_emerge_log_dir, 'emerge.log') |
196 |
mylogfile = open(file_path, "a") |
197 |
portage.util.apply_secpass_permissions(file_path, |
198 |
uid=portage.portage_uid, gid=portage.portage_gid, |
199 |
@@ -10173,7 +10175,11 @@ |
200 |
_bad_resume_opts = set(["--ask", "--changelog", |
201 |
"--resume", "--skipfirst"]) |
202 |
|
203 |
+<<<<<<< .working |
204 |
_fetch_log = EPREFIX + "/var/log/emerge-fetch.log" |
205 |
+======= |
206 |
+ _fetch_log = os.path.join(_emerge_log_dir, 'emerge-fetch.log') |
207 |
+>>>>>>> .merge-right.r13652 |
208 |
|
209 |
class _iface_class(SlotObject): |
210 |
__slots__ = ("dblinkEbuildPhase", "dblinkDisplayMerge", |
211 |
@@ -16175,9 +16181,8 @@ |
212 |
myopts["--usepkg"] = True |
213 |
|
214 |
# Allow -p to remove --ask |
215 |
- if ("--pretend" in myopts) and ("--ask" in myopts): |
216 |
- print ">>> --pretend disables --ask... removing --ask from options." |
217 |
- del myopts["--ask"] |
218 |
+ if "--pretend" in myopts: |
219 |
+ myopts.pop("--ask", None) |
220 |
|
221 |
# forbid --ask when not in a terminal |
222 |
# note: this breaks `emerge --ask | tee logfile`, but that doesn't work anyway. |
223 |
@@ -16267,6 +16272,20 @@ |
224 |
def emergelog(*pargs, **kargs): |
225 |
pass |
226 |
|
227 |
+ else: |
228 |
+ if 'EMERGE_LOG_DIR' in settings: |
229 |
+ try: |
230 |
+ # At least the parent needs to exist for the lock file. |
231 |
+ portage.util.ensure_dirs(settings['EMERGE_LOG_DIR']) |
232 |
+ except portage.exception.PortageException, e: |
233 |
+ writemsg_level("!!! Error creating directory for " + \ |
234 |
+ "EMERGE_LOG_DIR='%s':\n!!! %s\n" % \ |
235 |
+ (settings['EMERGE_LOG_DIR'], e), |
236 |
+ noiselevel=-1, level=logging.ERROR) |
237 |
+ else: |
238 |
+ global _emerge_log_dir |
239 |
+ _emerge_log_dir = settings['EMERGE_LOG_DIR'] |
240 |
+ |
241 |
if not "--pretend" in myopts: |
242 |
emergelog(xterm_titles, "Started emerge on: "+\ |
243 |
time.strftime("%b %d, %Y %H:%M:%S", time.localtime())) |
244 |
|
245 |
Modified: main/branches/prefix/pym/portage/__init__.py |
246 |
=================================================================== |
247 |
--- main/branches/prefix/pym/portage/__init__.py 2009-06-18 19:55:17 UTC (rev 13652) |
248 |
+++ main/branches/prefix/pym/portage/__init__.py 2009-06-19 19:25:10 UTC (rev 13653) |
249 |
@@ -1066,7 +1066,7 @@ |
250 |
"DISTDIR", "DOC_SYMLINKS_DIR", "EBUILD", |
251 |
"EBUILD_EXIT_STATUS_FILE", "EBUILD_FORCE_TEST", |
252 |
"EBUILD_PHASE", "ECLASSDIR", "ECLASS_DEPTH", "EMERGE_FROM", |
253 |
- "FEATURES", "FILESDIR", "HOME", "PATH", |
254 |
+ "FEATURES", "FILESDIR", "HOME", "NOCOLOR", "PATH", |
255 |
"PKGDIR", |
256 |
"PKGUSE", "PKG_LOGDIR", "PKG_TMPDIR", |
257 |
"PORTAGE_ACTUAL_DISTDIR", "PORTAGE_ARCHLIST", |
258 |
@@ -1142,6 +1142,7 @@ |
259 |
"ACCEPT_KEYWORDS", "AUTOCLEAN", |
260 |
"CLEAN_DELAY", "COLLISION_IGNORE", "CONFIG_PROTECT", |
261 |
"CONFIG_PROTECT_MASK", "EGENCACHE_DEFAULT_OPTS", "EMERGE_DEFAULT_OPTS", |
262 |
+ "EMERGE_LOG_DIR", |
263 |
"EMERGE_WARNING_DELAY", "FETCHCOMMAND", "FETCHCOMMAND_FTP", |
264 |
"FETCHCOMMAND_HTTP", "FETCHCOMMAND_SFTP", |
265 |
"GENTOO_MIRRORS", "NOCONFMEM", "O", |
266 |
@@ -5456,7 +5457,8 @@ |
267 |
# Allow color.map to control colors associated with einfo, ewarn, etc... |
268 |
mycolors = [] |
269 |
for c in ("GOOD", "WARN", "BAD", "HILITE", "BRACKET"): |
270 |
- mycolors.append("%s=$'%s'" % (c, portage.output.codes[c])) |
271 |
+ mycolors.append("%s=$'%s'" % \ |
272 |
+ (c, portage.output.style_to_ansi_code(c))) |
273 |
mysettings["PORTAGE_COLORMAP"] = "\n".join(mycolors) |
274 |
|
275 |
def prepare_build_dirs(myroot, mysettings, cleanup): |
276 |
|
277 |
Modified: main/branches/prefix/pym/portage/output.py |
278 |
=================================================================== |
279 |
--- main/branches/prefix/pym/portage/output.py 2009-06-18 19:55:17 UTC (rev 13652) |
280 |
+++ main/branches/prefix/pym/portage/output.py 2009-06-19 19:25:10 UTC (rev 13653) |
281 |
@@ -4,6 +4,7 @@ |
282 |
|
283 |
__docformat__ = "epytext" |
284 |
|
285 |
+import codecs |
286 |
import commands |
287 |
import errno |
288 |
import formatter |
289 |
@@ -24,80 +25,62 @@ |
290 |
havecolor=1 |
291 |
dotitles=1 |
292 |
|
293 |
+_styles = {} |
294 |
+"""Maps style class to tuple of attribute names.""" |
295 |
+ |
296 |
+codes = {} |
297 |
+"""Maps attribute name to ansi code.""" |
298 |
+ |
299 |
esc_seq = "\x1b[" |
300 |
|
301 |
-g_attr = {} |
302 |
-g_attr["normal"] = 0 |
303 |
+codes["normal"] = esc_seq + "0m" |
304 |
+codes["reset"] = esc_seq + "39;49;00m" |
305 |
|
306 |
-g_attr["bold"] = 1 |
307 |
-g_attr["faint"] = 2 |
308 |
-g_attr["standout"] = 3 |
309 |
-g_attr["underline"] = 4 |
310 |
-g_attr["blink"] = 5 |
311 |
-g_attr["overline"] = 6 # Why is overline actually useful? |
312 |
-g_attr["reverse"] = 7 |
313 |
-g_attr["invisible"] = 8 |
314 |
+codes["bold"] = esc_seq + "01m" |
315 |
+codes["faint"] = esc_seq + "02m" |
316 |
+codes["standout"] = esc_seq + "03m" |
317 |
+codes["underline"] = esc_seq + "04m" |
318 |
+codes["blink"] = esc_seq + "05m" |
319 |
+codes["overline"] = esc_seq + "06m" |
320 |
+codes["reverse"] = esc_seq + "07m" |
321 |
+codes["invisible"] = esc_seq + "08m" |
322 |
|
323 |
-g_attr["no-attr"] = 22 |
324 |
-g_attr["no-standout"] = 23 |
325 |
-g_attr["no-underline"] = 24 |
326 |
-g_attr["no-blink"] = 25 |
327 |
-g_attr["no-overline"] = 26 |
328 |
-g_attr["no-reverse"] = 27 |
329 |
-# 28 isn't defined? |
330 |
-# 29 isn't defined? |
331 |
-g_attr["black"] = 30 |
332 |
-g_attr["red"] = 31 |
333 |
-g_attr["green"] = 32 |
334 |
-g_attr["yellow"] = 33 |
335 |
-g_attr["blue"] = 34 |
336 |
-g_attr["magenta"] = 35 |
337 |
-g_attr["cyan"] = 36 |
338 |
-g_attr["white"] = 37 |
339 |
-# 38 isn't defined? |
340 |
-g_attr["default"] = 39 |
341 |
-g_attr["bg_black"] = 40 |
342 |
-g_attr["bg_red"] = 41 |
343 |
-g_attr["bg_green"] = 42 |
344 |
-g_attr["bg_yellow"] = 43 |
345 |
-g_attr["bg_blue"] = 44 |
346 |
-g_attr["bg_magenta"] = 45 |
347 |
-g_attr["bg_cyan"] = 46 |
348 |
-g_attr["bg_white"] = 47 |
349 |
-g_attr["bg_default"] = 49 |
350 |
+codes["no-attr"] = esc_seq + "22m" |
351 |
+codes["no-standout"] = esc_seq + "23m" |
352 |
+codes["no-underline"] = esc_seq + "24m" |
353 |
+codes["no-blink"] = esc_seq + "25m" |
354 |
+codes["no-overline"] = esc_seq + "26m" |
355 |
+codes["no-reverse"] = esc_seq + "27m" |
356 |
|
357 |
+codes["bg_black"] = esc_seq + "40m" |
358 |
+codes["bg_darkred"] = esc_seq + "41m" |
359 |
+codes["bg_darkgreen"] = esc_seq + "42m" |
360 |
+codes["bg_brown"] = esc_seq + "43m" |
361 |
+codes["bg_darkblue"] = esc_seq + "44m" |
362 |
+codes["bg_purple"] = esc_seq + "45m" |
363 |
+codes["bg_teal"] = esc_seq + "46m" |
364 |
+codes["bg_lightgray"] = esc_seq + "47m" |
365 |
+codes["bg_default"] = esc_seq + "49m" |
366 |
+codes["bg_darkyellow"] = codes["bg_brown"] |
367 |
|
368 |
-# make_seq("blue", "black", "normal") |
369 |
def color(fg, bg="default", attr=["normal"]): |
370 |
- mystr = esc_seq[:] + "%02d" % g_attr[fg] |
371 |
+ mystr = codes[fg] |
372 |
for x in [bg]+attr: |
373 |
- mystr += ";%02d" % g_attr[x] |
374 |
- return mystr+"m" |
375 |
+ mystr += codes[x] |
376 |
+ return mystr |
377 |
|
378 |
|
379 |
- |
380 |
-codes={} |
381 |
-codes["reset"] = esc_seq + "39;49;00m" |
382 |
- |
383 |
-codes["bold"] = esc_seq + "01m" |
384 |
-codes["faint"] = esc_seq + "02m" |
385 |
-codes["standout"] = esc_seq + "03m" |
386 |
-codes["underline"] = esc_seq + "04m" |
387 |
-codes["blink"] = esc_seq + "05m" |
388 |
-codes["overline"] = esc_seq + "06m" # Who made this up? Seriously. |
389 |
-codes["reverse"] = esc_seq + "07m" |
390 |
- |
391 |
-ansi_color_codes = [] |
392 |
+ansi_codes = [] |
393 |
for x in xrange(30, 38): |
394 |
- ansi_color_codes.append("%im" % x) |
395 |
- ansi_color_codes.append("%i;01m" % x) |
396 |
+ ansi_codes.append("%im" % x) |
397 |
+ ansi_codes.append("%i;01m" % x) |
398 |
|
399 |
rgb_ansi_colors = ['0x000000', '0x555555', '0xAA0000', '0xFF5555', '0x00AA00', |
400 |
'0x55FF55', '0xAA5500', '0xFFFF55', '0x0000AA', '0x5555FF', '0xAA00AA', |
401 |
'0xFF55FF', '0x00AAAA', '0x55FFFF', '0xAAAAAA', '0xFFFFFF'] |
402 |
|
403 |
for x in xrange(len(rgb_ansi_colors)): |
404 |
- codes[rgb_ansi_colors[x]] = esc_seq + ansi_color_codes[x] |
405 |
+ codes[rgb_ansi_colors[x]] = esc_seq + ansi_codes[x] |
406 |
|
407 |
del x |
408 |
|
409 |
@@ -130,43 +113,34 @@ |
410 |
codes["0xAAAA00"] = codes["brown"] |
411 |
codes["darkyellow"] = codes["0xAAAA00"] |
412 |
|
413 |
-codes["bg_black"] = esc_seq + "40m" |
414 |
-codes["bg_darkred"] = esc_seq + "41m" |
415 |
-codes["bg_darkgreen"] = esc_seq + "42m" |
416 |
-codes["bg_brown"] = esc_seq + "43m" |
417 |
-codes["bg_darkblue"] = esc_seq + "44m" |
418 |
-codes["bg_purple"] = esc_seq + "45m" |
419 |
-codes["bg_teal"] = esc_seq + "46m" |
420 |
-codes["bg_lightgray"] = esc_seq + "47m" |
421 |
|
422 |
-codes["bg_darkyellow"] = codes["bg_brown"] |
423 |
|
424 |
# Colors from /etc/init.d/functions.sh |
425 |
-codes["NORMAL"] = esc_seq + "0m" |
426 |
-codes["GOOD"] = codes["green"] |
427 |
-codes["WARN"] = codes["yellow"] |
428 |
-codes["BAD"] = codes["red"] |
429 |
-codes["HILITE"] = codes["teal"] |
430 |
-codes["BRACKET"] = codes["blue"] |
431 |
+_styles["NORMAL"] = ( "normal", ) |
432 |
+_styles["GOOD"] = ( "green", ) |
433 |
+_styles["WARN"] = ( "yellow", ) |
434 |
+_styles["BAD"] = ( "red", ) |
435 |
+_styles["HILITE"] = ( "teal", ) |
436 |
+_styles["BRACKET"] = ( "blue", ) |
437 |
|
438 |
# Portage functions |
439 |
-codes["INFORM"] = codes["darkgreen"] |
440 |
-codes["UNMERGE_WARN"] = codes["red"] |
441 |
-codes["SECURITY_WARN"] = codes["red"] |
442 |
-codes["MERGE_LIST_PROGRESS"] = codes["yellow"] |
443 |
-codes["PKG_BLOCKER"] = codes["red"] |
444 |
-codes["PKG_BLOCKER_SATISFIED"] = codes["darkblue"] |
445 |
-codes["PKG_MERGE"] = codes["darkgreen"] |
446 |
-codes["PKG_MERGE_SYSTEM"] = codes["darkgreen"] |
447 |
-codes["PKG_MERGE_WORLD"] = codes["green"] |
448 |
-codes["PKG_UNINSTALL"] = codes["red"] |
449 |
-codes["PKG_NOMERGE"] = codes["darkblue"] |
450 |
-codes["PKG_NOMERGE_SYSTEM"] = codes["darkblue"] |
451 |
-codes["PKG_NOMERGE_WORLD"] = codes["blue"] |
452 |
-codes["PROMPT_CHOICE_DEFAULT"] = codes["green"] |
453 |
-codes["PROMPT_CHOICE_OTHER"] = codes["red"] |
454 |
+_styles["INFORM"] = ( "darkgreen", ) |
455 |
+_styles["UNMERGE_WARN"] = ( "red", ) |
456 |
+_styles["SECURITY_WARN"] = ( "red", ) |
457 |
+_styles["MERGE_LIST_PROGRESS"] = ( "yellow", ) |
458 |
+_styles["PKG_BLOCKER"] = ( "red", ) |
459 |
+_styles["PKG_BLOCKER_SATISFIED"] = ( "darkblue", ) |
460 |
+_styles["PKG_MERGE"] = ( "darkgreen", ) |
461 |
+_styles["PKG_MERGE_SYSTEM"] = ( "darkgreen", ) |
462 |
+_styles["PKG_MERGE_WORLD"] = ( "green", ) |
463 |
+_styles["PKG_UNINSTALL"] = ( "red", ) |
464 |
+_styles["PKG_NOMERGE"] = ( "darkblue", ) |
465 |
+_styles["PKG_NOMERGE_SYSTEM"] = ( "darkblue", ) |
466 |
+_styles["PKG_NOMERGE_WORLD"] = ( "blue", ) |
467 |
+_styles["PROMPT_CHOICE_DEFAULT"] = ( "green", ) |
468 |
+_styles["PROMPT_CHOICE_OTHER"] = ( "red", ) |
469 |
|
470 |
-def parse_color_map(onerror=None): |
471 |
+def _parse_color_map(onerror=None): |
472 |
""" |
473 |
Parse /etc/portage/color.map and return a dict of error codes. |
474 |
|
475 |
@@ -177,32 +151,40 @@ |
476 |
@return: a dictionary mapping color classes to color codes |
477 |
""" |
478 |
myfile = EPREFIX + COLOR_MAP_FILE |
479 |
- ansi_code_pattern = re.compile("^[0-9;]*m$") |
480 |
- def strip_quotes(token, quotes): |
481 |
+ ansi_code_pattern = re.compile("^[0-9;]*m$") |
482 |
+ quotes = '\'"' |
483 |
+ def strip_quotes(token): |
484 |
if token[0] in quotes and token[0] == token[-1]: |
485 |
token = token[1:-1] |
486 |
return token |
487 |
try: |
488 |
- s = shlex.shlex(open(myfile)) |
489 |
- s.wordchars = s.wordchars + ";" # for ansi codes |
490 |
- while True: |
491 |
- k, o, v = s.get_token(), s.get_token(), s.get_token() |
492 |
- if k is s.eof: |
493 |
- break |
494 |
- if o != "=": |
495 |
- e = ParseError("%s%s'%s'" % ( |
496 |
- s.error_leader(myfile, s.lineno), |
497 |
- "expected '=' operator: ", o)) |
498 |
+ lineno=0 |
499 |
+ for line in codecs.open( myfile, mode = 'r', errors = 'replace' ): |
500 |
+ lineno += 1 |
501 |
+ |
502 |
+ commenter_pos = line.find("#") |
503 |
+ line = line[:commenter_pos].strip() |
504 |
+ |
505 |
+ if len(line) == 0: |
506 |
+ continue |
507 |
+ |
508 |
+ split_line = line.split("=") |
509 |
+ if len(split_line) != 2: |
510 |
+ e = ParseError("'%s', line %s: %s" % ( |
511 |
+ myfile, lineno, |
512 |
+ "expected exactly one occurence of '=' operator")) |
513 |
+ raise e |
514 |
if onerror: |
515 |
onerror(e) |
516 |
else: |
517 |
raise e |
518 |
continue |
519 |
- k = strip_quotes(k, s.quotes) |
520 |
- v = strip_quotes(v, s.quotes) |
521 |
- if not k in codes: |
522 |
- e = ParseError("%s%s'%s'" % ( |
523 |
- s.error_leader(myfile, s.lineno), |
524 |
+ |
525 |
+ k = strip_quotes(split_line[0].strip()) |
526 |
+ v = strip_quotes(split_line[1].strip()) |
527 |
+ if not k in _styles and not k in codes: |
528 |
+ e = ParseError("'%s', line %s: %s'%s'" % ( |
529 |
+ myfile, lineno, |
530 |
"Unknown variable: ", k)) |
531 |
if onerror: |
532 |
onerror(e) |
533 |
@@ -210,21 +192,30 @@ |
534 |
raise e |
535 |
continue |
536 |
if ansi_code_pattern.match(v): |
537 |
- codes[k] = esc_seq + v |
538 |
+ if k in _styles: |
539 |
+ _styles[k] = ( esc_seq + v, ) |
540 |
+ elif k in codes: |
541 |
+ codes[k] = esc_seq + v |
542 |
else: |
543 |
code_list = [] |
544 |
- for x in v.split(" "): |
545 |
+ for x in v.split(): |
546 |
if x in codes: |
547 |
- code_list.append(codes[x]) |
548 |
+ if k in _styles: |
549 |
+ code_list.append(x) |
550 |
+ elif k in codes: |
551 |
+ code_list.append(codes[x]) |
552 |
else: |
553 |
- e = ParseError("%s%s'%s'" % ( |
554 |
- s.error_leader(myfile, s.lineno), |
555 |
+ e = ParseError("'%s', line %s: %s'%s'" % ( |
556 |
+ myfile, lineno, |
557 |
"Undefined: ", x)) |
558 |
if onerror: |
559 |
onerror(e) |
560 |
else: |
561 |
raise e |
562 |
- codes[k] = "".join(code_list) |
563 |
+ if k in _styles: |
564 |
+ _styles[k] = tuple(code_list) |
565 |
+ elif k in codes: |
566 |
+ codes[k] = "".join(code_list) |
567 |
except (IOError, OSError), e: |
568 |
if e.errno == errno.ENOENT: |
569 |
raise FileNotFound(myfile) |
570 |
@@ -232,17 +223,6 @@ |
571 |
raise PermissionDenied(myfile) |
572 |
raise |
573 |
|
574 |
-try: |
575 |
- parse_color_map(onerror=lambda e: writemsg("%s\n" % str(e), noiselevel=-1)) |
576 |
-except FileNotFound: |
577 |
- pass |
578 |
-except PermissionDenied, e: |
579 |
- writemsg("Permission denied: '%s'\n" % str(e), noiselevel=-1) |
580 |
- del e |
581 |
-except PortageException, e: |
582 |
- writemsg("%s\n" % str(e), noiselevel=-1) |
583 |
- del e |
584 |
- |
585 |
def nc_len(mystr): |
586 |
tmp = re.sub(esc_seq + "^m]+m", "", mystr); |
587 |
return len(tmp) |
588 |
@@ -310,10 +290,29 @@ |
589 |
def resetColor(): |
590 |
return codes["reset"] |
591 |
|
592 |
+def style_to_ansi_code(style): |
593 |
+ """ |
594 |
+ @param style: A style name |
595 |
+ @type style: String |
596 |
+ @rtype: String |
597 |
+ @return: A string containing one or more ansi escape codes that are |
598 |
+ used to render the given style. |
599 |
+ """ |
600 |
+ ret = "" |
601 |
+ for attr_name in _styles[style]: |
602 |
+ # allow stuff that has found it's way through ansi_code_pattern |
603 |
+ ret += codes.get(attr_name, attr_name) |
604 |
+ return ret |
605 |
+ |
606 |
def colorize(color_key, text): |
607 |
global havecolor |
608 |
if havecolor: |
609 |
- return codes[color_key] + text + codes["reset"] |
610 |
+ if color_key in codes: |
611 |
+ return codes[color_key] + text + codes["reset"] |
612 |
+ elif color_key in _styles: |
613 |
+ return style_to_ansi_code(color_key) + text + codes["reset"] |
614 |
+ else: |
615 |
+ return text |
616 |
else: |
617 |
return text |
618 |
|
619 |
@@ -350,7 +349,7 @@ |
620 |
global havecolor |
621 |
if havecolor and self._styles: |
622 |
for style in self._styles: |
623 |
- self._file.write(codes[style]) |
624 |
+ self._file.write(style_to_ansi_code(style)) |
625 |
self._file.write(s) |
626 |
self._file.write(codes["reset"]) |
627 |
else: |
628 |
@@ -715,3 +714,14 @@ |
629 |
image = image + "[" + (bar_width * "=") + \ |
630 |
">" + ((max_bar_width - bar_width) * " ") + "]" |
631 |
return image |
632 |
+ |
633 |
+try: |
634 |
+ _parse_color_map(onerror=lambda e: writemsg("%s\n" % str(e), noiselevel=-1)) |
635 |
+except FileNotFound: |
636 |
+ pass |
637 |
+except PermissionDenied, e: |
638 |
+ writemsg("Permission denied: '%s'\n" % str(e), noiselevel=-1) |
639 |
+ del e |
640 |
+except PortageException, e: |
641 |
+ writemsg("%s\n" % str(e), noiselevel=-1) |
642 |
+ del e |