Add slightly modified elog_base patch containing the basic framework for ebuild logging.
authorMarius Mauch <genone@gentoo.org>
Sun, 13 Nov 2005 14:49:21 +0000 (14:49 -0000)
committerMarius Mauch <genone@gentoo.org>
Sun, 13 Nov 2005 14:49:21 +0000 (14:49 -0000)
svn path=/main/trunk/; revision=2306

bin/ebuild.sh
bin/isolated-functions.sh [new file with mode: 0644]
pym/portage.py
pym/portage_const.py

index 8b0d5e9bae9ee8505d69329104e7ad33795c3a24..80d915a4bb481fabb4b6e5e90bcc57db4580fb28 100755 (executable)
@@ -50,14 +50,9 @@ fi
 export PATH="/sbin:/usr/sbin:/usr/lib/portage/bin:/bin:/usr/bin:${ROOTPATH}"
 [ ! -z "$PREROOTPATH" ] && export PATH="${PREROOTPATH%%:}:$PATH"
 
-if [ -e /etc/init.d/functions.sh ]; then
-       source /etc/init.d/functions.sh  &>/dev/null
-elif [ -e /etc/rc.d/config/functions ];        then
-       source /etc/rc.d/config/functions &>/dev/null
-else
-       #Mac OS X
-       source /usr/lib/portage/bin/functions.sh &>/dev/null
-fi
+source /usr/lib/portage/bin/isolated-functions.sh  &>/dev/null
+# TODO: make this conditional on config settings, fix any remaining stuff
+set_colors
 
 # the sandbox is disabled by default except when overridden in the relevant stages
 export SANDBOX_ON="0"
diff --git a/bin/isolated-functions.sh b/bin/isolated-functions.sh
new file mode 100644 (file)
index 0000000..860bc58
--- /dev/null
@@ -0,0 +1,204 @@
+# Copyright 1999-2004 Gentoo Technologies, Inc.
+# Distributed under the terms of the GNU General Public License v2
+# $Header$
+
+# Internal logging function, don't use this in ebuilds
+elog_base() {
+       local messagetype
+       [ -z "${1}" -o -z "${T}" -o ! -d "${T}/logging" ] && return 1
+       case "${1}" in
+               INFO|WARN|ERROR|LOG)
+                       messagetype="${1}"
+                       shift
+                       ;;
+               *)
+                       echo -e " ${BAD}*${NORMAL} Invalid use of internal function elog_base(), next message will not be logged"
+                       return 1
+                       ;;
+       esac
+       echo ${*} >> ${T}/logging/${EBUILD_PHASE}.${messagetype}
+       return 0
+}
+
+elog() {
+       elog_base LOG ${*}
+       echo -e " ${GOOD}*${NORMAL} ${*}"
+       return 0
+}
+
+esyslog() {
+       local pri=
+       local tag=
+       
+       if [ -x /usr/bin/logger ]
+       then
+               pri="$1"
+               tag="$2"
+               
+               shift 2
+               [ -z "$*" ] && return 0
+               
+               /usr/bin/logger -p "${pri}" -t "${tag}" -- "$*"
+       fi
+
+       return 0
+}
+
+einfo() {
+       einfon ${*}
+       echo
+       return 0
+}
+
+einfon() {
+       elog_base INFO ${*}
+       echo -ne " ${GOOD}*${NORMAL} ${*}"
+       return 0
+}
+
+ewarn() {
+       elog_base WARN ${*}
+       echo -e " ${WARN}*${NORMAL} ${*}"
+       return 0
+}
+
+eerror() {
+       elog_base ERROR ${*}
+       echo -e " ${BAD}*${NORMAL} ${*}"
+       return 0
+}
+
+ebegin() {
+       if [ -z "${NOCOLOR}" ]; then
+               echo -ne " ${GOOD}*${NORMAL} ${*}..."
+       else
+               echo -e " ${GOOD}*${NORMAL} ${*}..."
+       fi
+       return 0
+}
+
+eend() {
+       local retval=
+       if [ "$#" -eq 0 ] || [ "${1:-1}" -eq  0 ]; then
+               echo -e "${ENDCOL}  ${BRACKET}[ ${GOOD}ok${BRACKET} ]${NORMAL}"
+       else
+               retval="$1"
+               
+               if [ "$#" -ge 2 ]
+               then
+                       shift
+                       eerror "${*}"
+               fi
+               echo -e "${ENDCOL}  ${BRACKET}[ ${BAD}!!${BRACKET} ]${NORMAL}"
+               # extra spacing makes it easier to read
+               echo
+               return ${retval}
+       fi
+       return 0
+}
+
+KV_major() {
+       local KV=
+       
+       [ -z "$1" ] && return 1
+
+       KV="$(echo "$1" | \
+               awk '{ tmp = $0; gsub(/^[0-9\.]*/, "", tmp); sub(tmp, ""); print }')"
+       echo "${KV}" | awk -- 'BEGIN { FS = "." } { print $1 }'
+
+       return 0
+}
+
+KV_minor() {
+       local KV=
+       
+       [ -z "$1" ] && return 1
+
+       KV="$(echo "$1" | \
+               awk '{ tmp = $0; gsub(/^[0-9\.]*/, "", tmp); sub(tmp, ""); print }')"
+       echo "${KV}" | awk -- 'BEGIN { FS = "." } { print $2 }'
+
+       return 0
+}
+
+KV_micro() {
+       local KV=
+       
+       [ -z "$1" ] && return 1
+
+       KV="$(echo "$1" | \
+               awk '{ tmp = $0; gsub(/^[0-9\.]*/, "", tmp); sub(tmp, ""); print }')"
+       echo "${KV}" | awk -- 'BEGIN { FS = "." } { print $3 }'
+
+       return 0
+}
+
+KV_to_int() {
+       local KV_MAJOR=
+       local KV_MINOR=
+       local KV_MICRO=
+       local KV_int=
+       
+       [ -z "$1" ] && return 1
+    
+       KV_MAJOR="$(KV_major "$1")"
+       KV_MINOR="$(KV_minor "$1")"
+       KV_MICRO="$(KV_micro "$1")"
+       KV_int="$((KV_MAJOR * 65536 + KV_MINOR * 256 + KV_MICRO))"
+    
+       # We make version 2.2.0 the minimum version we will handle as
+       # a sanity check ... if its less, we fail ...
+       if [ "${KV_int}" -ge 131584 ]
+       then 
+               echo "${KV_int}"
+
+               return 0
+       fi
+
+       return 1
+}   
+
+get_KV() {
+       local KV="$(uname -r)"
+
+       echo "$(KV_to_int "${KV}")"
+
+       return $?
+}
+
+getcols() {
+       echo "$2"
+}
+
+unset_colors() {
+       COLS="25 80"
+       ENDCOL=
+       
+       GOOD=
+       WARN=
+       BAD=
+       NORMAL=
+       HILITE=
+       BRACKET=
+       
+       if [ -n "${EBUILD}" ] && [ "${*/depend}" = "$*" ]; then
+               stty cols 80 &>/dev/null
+               stty rows 25 &>/dev/null
+       fi
+}
+
+set_colors() {
+       COLS="`stty size 2> /dev/null`"
+       COLS="`getcols ${COLS}`"
+       COLS=$((${COLS} - 7))
+       ENDCOL=$'\e[A\e['${COLS}'G'    # Now, ${ENDCOL} will move us to the end of the
+                                      # column;  irregardless of character width
+       
+       GOOD=$'\e[32;01m'
+       WARN=$'\e[33;01m'
+       BAD=$'\e[31;01m'
+       NORMAL=$'\e[0m'
+       HILITE=$'\e[36;01m'
+       BRACKET=$'\e[34;01m'
+}
+true
index 7e305ea46d33cd19a0f381904741221d8ab6dc5f..60ab80e4b5b33cf94b35180f19cef3002f735a5a 100644 (file)
@@ -456,6 +456,57 @@ class digraph:
                        mygraph.okeys=self.okeys[:]
                return mygraph
 
+def elog_process(cpv, mysettings):
+       mylogfiles = listdir(mysettings["T"]+"/logging/")
+       # shortcut for packages without any messages
+       if len(mylogfiles) == 0:
+               return
+       # exploit listdir() file order so we process log entries in cronological order
+       mylogfiles.reverse()
+       mylogentries = {}
+       for f in mylogfiles:
+               msgfunction, msgtype = f.split(".")
+               if not msgtype.upper() in mysettings["PORTAGE_ELOG_CLASSES"].split() \
+                               and not msgtype.lower() in mysettings["PORTAGE_ELOG_CLASSES"].split():
+                       continue
+               if msgfunction not in portage_const.EBUILD_PHASES:
+                       print "!!! can't process invalid log file: %s" % f
+                       continue
+               if not msgfunction in mylogentries:
+                       mylogentries[msgfunction] = []
+               msgcontent = open(mysettings["T"]+"/logging/"+f, "r").readlines()
+               mylogentries[msgfunction].append((msgtype, msgcontent))
+
+       # in case the filters matched all messages
+       if len(mylogentries) == 0:
+               return
+
+       # generate a single string with all log messages
+       fulllog = ""
+       for phase in portage_const.EBUILD_PHASES:
+               if not phase in mylogentries:
+                       continue
+               for msgtype,msgcontent in mylogentries[phase]:
+                       fulllog += "%s: %s\n" % (msgtype, phase)
+                       for line in msgcontent:
+                               fulllog += line
+                       fulllog += "\n"
+
+       # pass the processing to the individual modules
+       logsystems = mysettings["PORTAGE_ELOG_SYSTEM"].split()
+       for s in logsystems:
+               try:
+                       # FIXME: ugly ad.hoc import code
+                       # TODO:  implement a common portage module loader
+                       logmodule = __import__("elog_modules.mod_"+s)
+                       m = getattr(logmodule, "mod_"+s)
+                       m.process(mysettings, cpv, mylogentries, fulllog)
+               except (ImportError, AttributeError), e:
+                       print "!!! Error while importing logging modules while loading \"mod_%s\":" % s
+                       print e
+               except portage_exception.PortageException, e:
+                       print e
+
 # valid end of version components; integers specify offset from release version
 # pre=prerelease, p=patchlevel (should always be followed by an int), rc=release candidate
 # all but _p (where it is required) can be followed by an optional trailing integer
@@ -2510,6 +2561,12 @@ def doebuild(myebuild,mydo,myroot,mysettings,debug=0,listonly=0,fetchonly=0,clea
                        os.chown(mysettings["T"],portage_uid,portage_gid)
                        os.chmod(mysettings["T"],02770)
 
+               logdir = mysettings["T"]+"/logging"
+               if not os.path.exists(logdir):
+                       os.makedirs(logdir)
+               os.chown(logdir, portage_uid, portage_gid)
+               os.chmod(logdir, 0770)
+
                try: # XXX: negative RESTRICT
                        if not (("nouserpriv" in string.split(mysettings["PORTAGE_RESTRICT"])) or \
                           ("userpriv" in string.split(mysettings["PORTAGE_RESTRICT"]))):
@@ -6544,6 +6601,10 @@ class dblink:
                if dircache.has_key(self.dbcatdir):
                        del dircache[self.dbcatdir]
                print ">>>",self.mycpv,"merged."
+
+               # Process ebuild logfiles
+               elog_process(self.mycpv, self.settings)
+               
                return 0
 
        def mergeme(self,srcroot,destroot,outfile,secondhand,stufftomerge,cfgfiledict,thismtime):
index 296784aeb9786dd06cba8ee9614d3f2eb5dc0c45..e8341ec5ff43a33b925300ad902b9609f0b7ffff 100644 (file)
@@ -41,6 +41,7 @@ CONFIG_MEMORY_FILE      = PRIVATE_PATH + "/config"
 
 INCREMENTALS=["USE","USE_EXPAND","FEATURES","ACCEPT_KEYWORDS","ACCEPT_LICENSE","CONFIG_PROTECT_MASK","CONFIG_PROTECT","PRELINK_PATH","PRELINK_PATH_MASK"]
 STICKIES=["KEYWORDS_ACCEPT","USE","CFLAGS","CXXFLAGS","MAKEOPTS","EXTRA_ECONF","EXTRA_EINSTALL","EXTRA_EMAKE"]
+EBUILD_PHASES                  = ["setup","unpack","compile","test","install","preinst","postinst","prerm","postrm"]
 
 EAPI = 0