Merged from trunk -r13640:13652
authorFabian Groffen <grobian@gentoo.org>
Fri, 19 Jun 2009 19:25:10 +0000 (19:25 -0000)
committerFabian Groffen <grobian@gentoo.org>
Fri, 19 Jun 2009 19:25:10 +0000 (19:25 -0000)
   | 13641   | Misc fixes and updates. Thanks to Sebastian Mingramm (few)   |
   | zmedico | <s.mingramm@gmx.de> for this patch from bug #274279.         |

   | 13642   | Escape hyphens from previous commit.                         |
   | zmedico |                                                              |

   | 13643   | Bug #274279 - Add color.map support for mapping a color to a |
   | zmedico | different color (rather than just mapping a class/style to a |
   |         | different color). Thanks to Sebastian Mingramm (few)         |
   |         | <s.mingramm@gmx.de> for this patch.                          |

   | 13644   | Use map_code_to_color_code() where appropriate inside        |
   | zmedico | ConsoleStyleFile.write().                                    |

   | 13645   | Add epydoc docstrings fro codes and color_codes variables.   |
   | zmedico |                                                              |

   | 13646   | Rename map_code_to_color_code() to style_to_ansi_code().     |
   | zmedico |                                                              |

   | 13647   | Rename codes to _styles.                                     |
   | zmedico |                                                              |

   | 13648   | Rename color_codes back to codes.                            |
   | zmedico |                                                              |

   | 13649   | Add NOCOLOR to the environment whitelist. This fixes         |
   | zmedico | inappropriate colors produced by elog functions. Thanks to   |
   |         | Luis F. Araujo <araujo@gentoo.org> for reporting.            |

   | 13650   | When --pretend overrides --ask, don't show any output.       |
   | zmedico |                                                              |

   | 13651   | Allow missing ChangeLog when using git. We don't use         |
   | zmedico | ChangeLogs in distributed SCMs. It will be generated on      |
   |         | server side from scm log, before package moves to the rsync  |
   |         | server. This is needed because we try to avoid merge         |
   |         | collisions. Thanks to Tomas Chvatal <scarabeus@gentoo.org>   |
   |         | for this patch.                                              |

   | 13652   | Add a EMERGE_LOG_DIR variable to control the location of     |
   | zmedico | emerge.log and emerge-fetch.log. This was requested by Eitan |
   |         | Mosenkis <eitan@mosenkis.net> for use in his 'online image   |
   |         | builder' soc project.                                        |

svn path=/main/branches/prefix/; revision=13653

bin/repoman
man/color.map.5
man/make.conf.5
pym/_emerge/__init__.py
pym/portage/__init__.py
pym/portage/output.py

index 243645bec014cdece1bf4e5ad69b1b76737f9cc2..bcde969de62be3f71649ad73675c71b47f23aa49 100755 (executable)
@@ -1113,8 +1113,11 @@ for x in scanlist:
                                                        relative_path + ': %s' % error_match.group(1))
 
        del mydigests
-
-       if "ChangeLog" not in checkdirlist:
+       # Note: We don't use ChangeLogs in distributed SCMs.
+       # It will be generated on server side from scm log,
+       # before package moves to the rsync server.
+       # This is needed because we try to avoid merge collisions.
+       if vcs not in ( "git", ) and "ChangeLog" not in checkdirlist:
                stats["changelog.missing"]+=1
                fails["changelog.missing"].append(x+"/ChangeLog")
        
index 7b11ba23a4b854bb5d0a41bab35c4b024f28cdab..9ce76ad26f5050560b4a4d935c03d209415467fa 100644 (file)
@@ -9,9 +9,14 @@ Portage will check this file first for color classes settings. If no setting
 of given color class is found in /etc/portage/color.map, Portage uses default
 value defined internally.
 .SH "SYNTAX"
-\fBVARIABLE\fR = \fI[space delimited list of attributes]\fR
+\fBVARIABLE\fR = \fI[space delimited list of attributes or ansi code pattern]\fR
+.TP
+\fBATTRIBUTE\fR = \fI[space delimited list of attributes or ansi code pattern]\fR
 .SH "VARIABLES"
 .TP
+\fBNORMAL\fR = \fI"normal"\fR
+Defines color used for some words occuring in other contexts than those below.
+.TP
 \fBBAD\fR = \fI"red"\fR
 Defines color used for some words occuring in bad context.
 .TP
@@ -89,10 +94,12 @@ Defines color used for warnings.
 .TP
 .B green
 .TP
-\fBbrown\fR = \fBdarkyellow\fR
+.B brown
 .TP
 .B yellow
 .TP
+.B darkyellow
+.TP
 .B darkblue
 .TP
 .B blue
@@ -103,7 +110,7 @@ Defines color used for warnings.
 .TP
 .B teal
 .TP
-.B turquoise
+\fBturquoise\fR = \fBdarkteal\fR
 .TP
 .B lightgray
 .TP
@@ -133,6 +140,10 @@ Defines color used for warnings.
 .B Other attributes
 .RS
 .TP
+.B normal
+.TP
+.B no\-attr
+.TP
 .B reset
 .TP
 .B bold
@@ -141,11 +152,25 @@ Defines color used for warnings.
 .TP
 .B standout
 .TP
+.B no\-standout
+.TP
 .B underline
 .TP
+.B no\-underline
+.TP
 .B blink
 .TP
+.B no\-blink
+.TP
+.B overline
+.TP
+.B no\-overline
+.TP
 .B reverse
+.TP
+.B no\-reverse
+.TP
+.B invisible
 .RE
 .SH "REPORTING BUGS"
 Please report bugs via http://bugs.gentoo.org/
index ef5913a8539bf55dc9b7cea1a7b4add8a2f7e664..2b5a7645f470bb1ff84589e97a2acdf658b6b1f9 100644 (file)
@@ -130,6 +130,11 @@ Options to append to the end of the \fBemerge\fR(1) command line on every invoca
 These options will not be appended to the command line if \-\-ignore\-default\-opts
 is specified.
 .TP
+.B EMERGE_LOG_DIR
+Controls the location of emerge.log and emerge-fetch.log.
+.br
+Defaults to /var/log.
+.TP
 .B EPAUSE_IGNORE
 Defines whether or not to ignore short pauses that occur when displaying
 important informational messages.  This variable is unset by default.
index c2fe495c187e45e83135b62bd897944dff3f540a..2f15be0c724f54730c32543ad1218d43cf56da97 100644 (file)
@@ -253,13 +253,15 @@ shortmapping={
 "v":"--verbose",   "V":"--version"
 }
 
+_emerge_log_dir = EPREFIX+'/var/log'
+
 def emergelog(xterm_titles, mystr, short_msg=None):
        if xterm_titles and short_msg:
                if "HOSTNAME" in os.environ:
                        short_msg = os.environ["HOSTNAME"]+": "+short_msg
                xtermTitle(short_msg)
        try:
-               file_path = EPREFIX+"/var/log/emerge.log"
+               file_path = os.path.join(_emerge_log_dir, 'emerge.log')
                mylogfile = open(file_path, "a")
                portage.util.apply_secpass_permissions(file_path,
                        uid=portage.portage_uid, gid=portage.portage_gid,
@@ -10173,7 +10175,11 @@ class Scheduler(PollScheduler):
        _bad_resume_opts = set(["--ask", "--changelog",
                "--resume", "--skipfirst"])
 
+<<<<<<< .working
        _fetch_log = EPREFIX + "/var/log/emerge-fetch.log"
+=======
+       _fetch_log = os.path.join(_emerge_log_dir, 'emerge-fetch.log')
+>>>>>>> .merge-right.r13652
 
        class _iface_class(SlotObject):
                __slots__ = ("dblinkEbuildPhase", "dblinkDisplayMerge",
@@ -16175,9 +16181,8 @@ def emerge_main():
                myopts["--usepkg"] = True
 
        # Allow -p to remove --ask
-       if ("--pretend" in myopts) and ("--ask" in myopts):
-               print ">>> --pretend disables --ask... removing --ask from options."
-               del myopts["--ask"]
+       if "--pretend" in myopts:
+               myopts.pop("--ask", None)
 
        # forbid --ask when not in a terminal
        # note: this breaks `emerge --ask | tee logfile`, but that doesn't work anyway.
@@ -16267,6 +16272,20 @@ def emerge_main():
                def emergelog(*pargs, **kargs):
                        pass
 
+       else:
+               if 'EMERGE_LOG_DIR' in settings:
+                       try:
+                               # At least the parent needs to exist for the lock file.
+                               portage.util.ensure_dirs(settings['EMERGE_LOG_DIR'])
+                       except portage.exception.PortageException, e:
+                               writemsg_level("!!! Error creating directory for " + \
+                                       "EMERGE_LOG_DIR='%s':\n!!! %s\n" % \
+                                       (settings['EMERGE_LOG_DIR'], e),
+                                       noiselevel=-1, level=logging.ERROR)
+                       else:
+                               global _emerge_log_dir
+                               _emerge_log_dir = settings['EMERGE_LOG_DIR']
+
        if not "--pretend" in myopts:
                emergelog(xterm_titles, "Started emerge on: "+\
                        time.strftime("%b %d, %Y %H:%M:%S", time.localtime()))
index fbad5fe24b78dd35de4e6f0b2e9459bf59423eb4..b5c2abf05aa8c02e3f0254d32b0f9fee8c0e531d 100644 (file)
@@ -1066,7 +1066,7 @@ class config(object):
                "DISTDIR", "DOC_SYMLINKS_DIR", "EBUILD",
                "EBUILD_EXIT_STATUS_FILE", "EBUILD_FORCE_TEST",
                "EBUILD_PHASE", "ECLASSDIR", "ECLASS_DEPTH", "EMERGE_FROM",
-               "FEATURES", "FILESDIR", "HOME", "PATH",
+               "FEATURES", "FILESDIR", "HOME", "NOCOLOR", "PATH",
                "PKGDIR",
                "PKGUSE", "PKG_LOGDIR", "PKG_TMPDIR",
                "PORTAGE_ACTUAL_DISTDIR", "PORTAGE_ARCHLIST",
@@ -1142,6 +1142,7 @@ class config(object):
                "ACCEPT_KEYWORDS", "AUTOCLEAN",
                "CLEAN_DELAY", "COLLISION_IGNORE", "CONFIG_PROTECT",
                "CONFIG_PROTECT_MASK", "EGENCACHE_DEFAULT_OPTS", "EMERGE_DEFAULT_OPTS",
+               "EMERGE_LOG_DIR",
                "EMERGE_WARNING_DELAY", "FETCHCOMMAND", "FETCHCOMMAND_FTP",
                "FETCHCOMMAND_HTTP", "FETCHCOMMAND_SFTP",
                "GENTOO_MIRRORS", "NOCONFMEM", "O",
@@ -5456,7 +5457,8 @@ def doebuild_environment(myebuild, mydo, myroot, mysettings, debug, use_cache, m
        # Allow color.map to control colors associated with einfo, ewarn, etc...
        mycolors = []
        for c in ("GOOD", "WARN", "BAD", "HILITE", "BRACKET"):
-               mycolors.append("%s=$'%s'" % (c, portage.output.codes[c]))
+               mycolors.append("%s=$'%s'" % \
+                       (c, portage.output.style_to_ansi_code(c)))
        mysettings["PORTAGE_COLORMAP"] = "\n".join(mycolors)
 
 def prepare_build_dirs(myroot, mysettings, cleanup):
index 0711c4b5df5e173da28bab13e566ffd03e16a1bb..771a28ea72fbc3ef21f97b4952be99cb7f5de5c6 100644 (file)
@@ -4,6 +4,7 @@
 
 __docformat__ = "epytext"
 
+import codecs
 import commands
 import errno
 import formatter
@@ -24,80 +25,62 @@ from portage.exception import CommandNotFound, FileNotFound, \
 havecolor=1
 dotitles=1
 
-esc_seq = "\x1b["
+_styles = {}
+"""Maps style class to tuple of attribute names."""
 
-g_attr = {}
-g_attr["normal"]       =  0
-
-g_attr["bold"]         =  1
-g_attr["faint"]        =  2
-g_attr["standout"]     =  3
-g_attr["underline"]    =  4
-g_attr["blink"]        =  5
-g_attr["overline"]     =  6  # Why is overline actually useful?
-g_attr["reverse"]      =  7
-g_attr["invisible"]    =  8
-
-g_attr["no-attr"]      = 22
-g_attr["no-standout"]  = 23
-g_attr["no-underline"] = 24
-g_attr["no-blink"]     = 25
-g_attr["no-overline"]  = 26
-g_attr["no-reverse"]   = 27
-# 28 isn't defined?
-# 29 isn't defined?
-g_attr["black"]        = 30
-g_attr["red"]          = 31
-g_attr["green"]        = 32
-g_attr["yellow"]       = 33
-g_attr["blue"]         = 34
-g_attr["magenta"]      = 35
-g_attr["cyan"]         = 36
-g_attr["white"]        = 37
-# 38 isn't defined?
-g_attr["default"]      = 39
-g_attr["bg_black"]     = 40
-g_attr["bg_red"]       = 41
-g_attr["bg_green"]     = 42
-g_attr["bg_yellow"]    = 43
-g_attr["bg_blue"]      = 44
-g_attr["bg_magenta"]   = 45
-g_attr["bg_cyan"]      = 46
-g_attr["bg_white"]     = 47
-g_attr["bg_default"]   = 49
-
-
-# make_seq("blue", "black", "normal")
-def color(fg, bg="default", attr=["normal"]):
-       mystr = esc_seq[:] + "%02d" % g_attr[fg]
-       for x in [bg]+attr:
-               mystr += ";%02d" % g_attr[x]
-       return mystr+"m"
+codes = {}
+"""Maps attribute name to ansi code."""
 
+esc_seq = "\x1b["
 
+codes["normal"]       =  esc_seq + "0m"
+codes["reset"]        =  esc_seq + "39;49;00m"
+
+codes["bold"]         =  esc_seq + "01m"
+codes["faint"]        =  esc_seq + "02m"
+codes["standout"]     =  esc_seq + "03m"
+codes["underline"]    =  esc_seq + "04m"
+codes["blink"]        =  esc_seq + "05m"
+codes["overline"]     =  esc_seq + "06m"
+codes["reverse"]      =  esc_seq + "07m"
+codes["invisible"]    =  esc_seq + "08m"
+
+codes["no-attr"]      = esc_seq + "22m"
+codes["no-standout"]  = esc_seq + "23m"
+codes["no-underline"] = esc_seq + "24m"
+codes["no-blink"]     = esc_seq + "25m"
+codes["no-overline"]  = esc_seq + "26m"
+codes["no-reverse"]   = esc_seq + "27m"
+
+codes["bg_black"]      = esc_seq + "40m"
+codes["bg_darkred"]    = esc_seq + "41m"
+codes["bg_darkgreen"]  = esc_seq + "42m"
+codes["bg_brown"]      = esc_seq + "43m"
+codes["bg_darkblue"]   = esc_seq + "44m"
+codes["bg_purple"]     = esc_seq + "45m"
+codes["bg_teal"]       = esc_seq + "46m"
+codes["bg_lightgray"]  = esc_seq + "47m"
+codes["bg_default"]    = esc_seq + "49m"
+codes["bg_darkyellow"] = codes["bg_brown"]
 
-codes={}
-codes["reset"]     = esc_seq + "39;49;00m"
+def color(fg, bg="default", attr=["normal"]):
+       mystr = codes[fg]
+       for x in [bg]+attr:
+               mystr += codes[x]
+       return mystr
 
-codes["bold"]      = esc_seq + "01m"
-codes["faint"]     = esc_seq + "02m"
-codes["standout"]  = esc_seq + "03m"
-codes["underline"] = esc_seq + "04m"
-codes["blink"]     = esc_seq + "05m"
-codes["overline"]  = esc_seq + "06m"  # Who made this up? Seriously.
-codes["reverse"]   = esc_seq + "07m"
 
-ansi_color_codes = []
+ansi_codes = []
 for x in xrange(30, 38):
-       ansi_color_codes.append("%im" % x)
-       ansi_color_codes.append("%i;01m" % x)
+       ansi_codes.append("%im" % x)
+       ansi_codes.append("%i;01m" % x)
 
 rgb_ansi_colors = ['0x000000', '0x555555', '0xAA0000', '0xFF5555', '0x00AA00',
        '0x55FF55', '0xAA5500', '0xFFFF55', '0x0000AA', '0x5555FF', '0xAA00AA',
        '0xFF55FF', '0x00AAAA', '0x55FFFF', '0xAAAAAA', '0xFFFFFF']
 
 for x in xrange(len(rgb_ansi_colors)):
-       codes[rgb_ansi_colors[x]] = esc_seq + ansi_color_codes[x]
+       codes[rgb_ansi_colors[x]] = esc_seq + ansi_codes[x]
 
 del x
 
@@ -130,43 +113,34 @@ codes["darkteal"]   = codes["turquoise"]
 codes["0xAAAA00"]   = codes["brown"]
 codes["darkyellow"] = codes["0xAAAA00"]
 
-codes["bg_black"]      = esc_seq + "40m"
-codes["bg_darkred"]    = esc_seq + "41m"
-codes["bg_darkgreen"]  = esc_seq + "42m"
-codes["bg_brown"]      = esc_seq + "43m"
-codes["bg_darkblue"]   = esc_seq + "44m"
-codes["bg_purple"]     = esc_seq + "45m"
-codes["bg_teal"]       = esc_seq + "46m"
-codes["bg_lightgray"]  = esc_seq + "47m"
 
-codes["bg_darkyellow"] = codes["bg_brown"]
 
 # Colors from /etc/init.d/functions.sh
-codes["NORMAL"]     = esc_seq + "0m"
-codes["GOOD"]       = codes["green"]
-codes["WARN"]       = codes["yellow"]
-codes["BAD"]        = codes["red"]
-codes["HILITE"]     = codes["teal"]
-codes["BRACKET"]    = codes["blue"]
+_styles["NORMAL"]     = ( "normal", )
+_styles["GOOD"]       = ( "green", )
+_styles["WARN"]       = ( "yellow", )
+_styles["BAD"]        = ( "red", )
+_styles["HILITE"]     = ( "teal", )
+_styles["BRACKET"]    = ( "blue", )
 
 # Portage functions
-codes["INFORM"]                  = codes["darkgreen"]
-codes["UNMERGE_WARN"]            = codes["red"]
-codes["SECURITY_WARN"]           = codes["red"]
-codes["MERGE_LIST_PROGRESS"]     = codes["yellow"]
-codes["PKG_BLOCKER"]             = codes["red"]
-codes["PKG_BLOCKER_SATISFIED"]   = codes["darkblue"]
-codes["PKG_MERGE"]               = codes["darkgreen"]
-codes["PKG_MERGE_SYSTEM"]        = codes["darkgreen"]
-codes["PKG_MERGE_WORLD"]         = codes["green"]
-codes["PKG_UNINSTALL"]           = codes["red"]
-codes["PKG_NOMERGE"]             = codes["darkblue"]
-codes["PKG_NOMERGE_SYSTEM"]      = codes["darkblue"]
-codes["PKG_NOMERGE_WORLD"]       = codes["blue"]
-codes["PROMPT_CHOICE_DEFAULT"]   = codes["green"]
-codes["PROMPT_CHOICE_OTHER"]     = codes["red"]
-
-def parse_color_map(onerror=None):
+_styles["INFORM"]                  = ( "darkgreen", )
+_styles["UNMERGE_WARN"]            = ( "red", )
+_styles["SECURITY_WARN"]           = ( "red", )
+_styles["MERGE_LIST_PROGRESS"]     = ( "yellow", )
+_styles["PKG_BLOCKER"]             = ( "red", )
+_styles["PKG_BLOCKER_SATISFIED"]   = ( "darkblue", )
+_styles["PKG_MERGE"]               = ( "darkgreen", )
+_styles["PKG_MERGE_SYSTEM"]        = ( "darkgreen", )
+_styles["PKG_MERGE_WORLD"]         = ( "green", )
+_styles["PKG_UNINSTALL"]           = ( "red", )
+_styles["PKG_NOMERGE"]             = ( "darkblue", )
+_styles["PKG_NOMERGE_SYSTEM"]      = ( "darkblue", )
+_styles["PKG_NOMERGE_WORLD"]       = ( "blue", )
+_styles["PROMPT_CHOICE_DEFAULT"]   = ( "green", )
+_styles["PROMPT_CHOICE_OTHER"]     = ( "red", )
+
+def _parse_color_map(onerror=None):
        """
        Parse /etc/portage/color.map and return a dict of error codes.
 
@@ -177,32 +151,40 @@ def parse_color_map(onerror=None):
        @return: a dictionary mapping color classes to color codes
        """
        myfile = EPREFIX + COLOR_MAP_FILE
-       ansi_code_pattern = re.compile("^[0-9;]*m$")
-       def strip_quotes(token, quotes):
+       ansi_code_pattern = re.compile("^[0-9;]*m$") 
+       quotes = '\'"'
+       def strip_quotes(token):
                if token[0] in quotes and token[0] == token[-1]:
                        token = token[1:-1]
                return token
        try:
-               s = shlex.shlex(open(myfile))
-               s.wordchars = s.wordchars + ";" # for ansi codes
-               while True:
-                       k, o, v = s.get_token(), s.get_token(), s.get_token()
-                       if k is s.eof:
-                               break
-                       if o != "=":
-                               e = ParseError("%s%s'%s'" % (
-                                       s.error_leader(myfile, s.lineno),
-                                       "expected '=' operator: ", o))
+               lineno=0
+               for line in codecs.open( myfile, mode = 'r', errors = 'replace' ):
+                       lineno += 1
+
+                       commenter_pos = line.find("#")
+                       line = line[:commenter_pos].strip()
+                       
+                       if len(line) == 0:
+                               continue
+                       
+                       split_line = line.split("=")
+                       if len(split_line) != 2:
+                               e = ParseError("'%s', line %s: %s" % (
+                                       myfile, lineno,
+                                       "expected exactly one occurence of '=' operator"))
+                               raise e
                                if onerror:
                                        onerror(e)
                                else:
                                        raise e
                                continue
-                       k = strip_quotes(k, s.quotes)
-                       v = strip_quotes(v, s.quotes)
-                       if not k in codes:
-                               e = ParseError("%s%s'%s'" % (
-                                       s.error_leader(myfile, s.lineno),
+
+                       k = strip_quotes(split_line[0].strip())
+                       v = strip_quotes(split_line[1].strip())
+                       if not k in _styles and not k in codes:
+                               e = ParseError("'%s', line %s: %s'%s'" % (
+                                       myfile, lineno,
                                        "Unknown variable: ", k))
                                if onerror:
                                        onerror(e)
@@ -210,21 +192,30 @@ def parse_color_map(onerror=None):
                                        raise e
                                continue
                        if ansi_code_pattern.match(v):
-                               codes[k] = esc_seq + v
+                               if k in _styles:
+                                       _styles[k] = ( esc_seq + v, )
+                               elif k in codes:
+                                       codes[k] = esc_seq + v
                        else:
                                code_list = []
-                               for x in v.split(" "):
+                               for x in v.split():
                                        if x in codes:
-                                               code_list.append(codes[x])
+                                               if k in _styles:
+                                                       code_list.append(x)
+                                               elif k in codes:
+                                                       code_list.append(codes[x])
                                        else:
-                                               e = ParseError("%s%s'%s'" % (
-                                                       s.error_leader(myfile, s.lineno),
+                                               e = ParseError("'%s', line %s: %s'%s'" % (
+                                                       myfile, lineno,
                                                        "Undefined: ", x))
                                                if onerror:
                                                        onerror(e)
                                                else:
                                                        raise e
-                               codes[k] = "".join(code_list)
+                               if k in _styles:
+                                       _styles[k] = tuple(code_list)
+                               elif k in codes:
+                                       codes[k] = "".join(code_list)
        except (IOError, OSError), e:
                if e.errno == errno.ENOENT:
                        raise FileNotFound(myfile)
@@ -232,17 +223,6 @@ def parse_color_map(onerror=None):
                        raise PermissionDenied(myfile)
                raise
 
-try:
-       parse_color_map(onerror=lambda e: writemsg("%s\n" % str(e), noiselevel=-1))
-except FileNotFound:
-       pass
-except PermissionDenied, e:
-       writemsg("Permission denied: '%s'\n" % str(e), noiselevel=-1)
-       del e
-except PortageException, e:
-       writemsg("%s\n" % str(e), noiselevel=-1)
-       del e
-
 def nc_len(mystr):
        tmp = re.sub(esc_seq + "^m]+m", "", mystr);
        return len(tmp)
@@ -310,10 +290,29 @@ def nocolor():
 def resetColor():
        return codes["reset"]
 
+def style_to_ansi_code(style):
+       """
+       @param style: A style name
+       @type style: String
+       @rtype: String
+       @return: A string containing one or more ansi escape codes that are
+               used to render the given style.
+       """
+       ret = ""
+       for attr_name in _styles[style]:
+               # allow stuff that has found it's way through ansi_code_pattern
+               ret += codes.get(attr_name, attr_name)
+       return ret
+
 def colorize(color_key, text):
        global havecolor
        if havecolor:
-               return codes[color_key] + text + codes["reset"]
+               if color_key in codes:
+                       return codes[color_key] + text + codes["reset"]
+               elif color_key in _styles:
+                       return style_to_ansi_code(color_key) + text + codes["reset"]
+               else:
+                       return text
        else:
                return text
 
@@ -350,7 +349,7 @@ class ConsoleStyleFile(object):
                global havecolor
                if havecolor and self._styles:
                        for style in self._styles:
-                               self._file.write(codes[style])
+                               self._file.write(style_to_ansi_code(style))
                        self._file.write(s)
                        self._file.write(codes["reset"])
                else:
@@ -715,3 +714,14 @@ class TermProgressBar(ProgressBar):
                        image = image + "[" + (bar_width * "=") + \
                                ">" + ((max_bar_width - bar_width) * " ") + "]"
                        return image
+
+try:
+       _parse_color_map(onerror=lambda e: writemsg("%s\n" % str(e), noiselevel=-1))
+except FileNotFound:
+       pass
+except PermissionDenied, e:
+       writemsg("Permission denied: '%s'\n" % str(e), noiselevel=-1)
+       del e
+except PortageException, e:
+       writemsg("%s\n" % str(e), noiselevel=-1)
+       del e