summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rwxr-xr-xbin/ebuild.sh11
-rw-r--r--bin/isolated-functions.sh204
-rw-r--r--pym/portage.py61
-rw-r--r--pym/portage_const.py1
4 files changed, 269 insertions, 8 deletions
diff --git a/bin/ebuild.sh b/bin/ebuild.sh
index 8b0d5e9ba..80d915a4b 100755
--- a/bin/ebuild.sh
+++ b/bin/ebuild.sh
@@ -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
index 000000000..860bc5890
--- /dev/null
+++ b/bin/isolated-functions.sh
@@ -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
diff --git a/pym/portage.py b/pym/portage.py
index 7e305ea46..60ab80e4b 100644
--- a/pym/portage.py
+++ b/pym/portage.py
@@ -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):
diff --git a/pym/portage_const.py b/pym/portage_const.py
index 296784aeb..e8341ec5f 100644
--- a/pym/portage_const.py
+++ b/pym/portage_const.py
@@ -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