Merge install_qa_check_prefix from prefix branch.
authorZac Medico <zmedico@gentoo.org>
Wed, 2 Nov 2011 01:47:56 +0000 (18:47 -0700)
committerZac Medico <zmedico@gentoo.org>
Wed, 2 Nov 2011 01:47:56 +0000 (18:47 -0700)
bin/misc-functions.sh

index 55d9663443dfc5264d88d0184dfec69ef3c26a67..80cd0f8b613f7295d8695926fac680fede053ea6 100755 (executable)
@@ -154,6 +154,12 @@ install_qa_check() {
        ecompressdir --dequeue
        ecompress --dequeue
 
+       local ed=${ED}
+       case "$EAPI" in 0|1|2) ed=${D} ;; esac
+
+       # Prefix specific checks
+       [[ ${ed} != ${D} ]] && install_qa_check_prefix
+
        f=
        for x in etc/app-defaults usr/man usr/info usr/X11R6 usr/doc usr/locale ; do
                [[ -d $D/$x ]] && f+="  $x\n"
@@ -731,6 +737,124 @@ install_qa_check() {
        fi
 }
 
+install_qa_check_prefix() {
+       if [[ -d ${ED}/${D} ]] ; then
+               find "${ED}/${D}" | \
+               while read i ; do
+                       eqawarn "QA Notice: /${i##${ED}/${D}} installed in \${ED}/\${D}"
+               done
+               die "Aborting due to QA concerns: files installed in ${ED}/${D}"
+       fi
+
+       if [[ -d ${ED}/${EPREFIX} ]] ; then
+               find "${ED}/${EPREFIX}/" | \
+               while read i ; do
+                       eqawarn "QA Notice: ${i#${D}} double prefix"
+               done
+               die "Aborting due to QA concerns: double prefix files installed"
+       fi
+
+       if [[ -d ${D} ]] ; then
+               INSTALLTOD=$(find ${D%/} | egrep -v "^${ED}" | sed -e "s|^${D%/}||" | awk '{if (length($0) <= length("'"${EPREFIX}"'")) { if (substr("'"${EPREFIX}"'", 1, length($0)) != $0) {print $0;} } else if (substr($0, 1, length("'"${EPREFIX}"'")) != "'"${EPREFIX}"'") {print $0;} }')
+               if [[ -n ${INSTALLTOD} ]] ; then
+                       eqawarn "QA Notice: the following files are outside of the prefix:"
+                       eqawarn "${INSTALLTOD}"
+                       die "Aborting due to QA concerns: there are files installed outside the prefix"
+               fi
+       fi
+
+       # all further checks rely on ${ED} existing
+       [[ -d ${ED} ]] || return
+
+       # this does not really belong here, but it's closely tied to
+       # the code below; many runscripts generate positives here, and we
+       # know they don't work (bug #196294) so as long as that one
+       # remains an issue, simply remove them as they won't work
+       # anyway, avoid etc/init.d/functions.sh from being thrown away
+       if [[ ( -d "${ED}"/etc/conf.d || -d "${ED}"/etc/init.d ) && ! -f "${ED}"/etc/init.d/functions.sh ]] ; then
+               ewarn "removed /etc/init.d and /etc/conf.d directories until bug #196294 has been resolved"
+               rm -Rf "${ED}"/etc/{conf,init}.d
+       fi
+
+       # check shebangs, bug #282539
+       rm -f "${T}"/non-prefix-shebangs-errs
+       local WHITELIST=" /usr/bin/env "
+       # this is hell expensive, but how else?
+       find "${ED}" -executable \! -type d -print0 \
+                       | xargs -0 grep -H -n -m1 "^#!" \
+                       | while read f ;
+       do
+               local fn=${f%%:*}
+               local pos=${f#*:} ; pos=${pos%:*}
+               local line=${f##*:}
+               # shebang always appears on the first line ;)
+               [[ ${pos} != 1 ]] && continue
+               local oldIFS=${IFS}
+               IFS=$'\r'$'\n'$'\t'" "
+               line=( ${line#"#!"} )
+               IFS=${oldIFS}
+               [[ ${WHITELIST} == *" ${line[0]} "* ]] && continue
+               local fp=${fn#${D}} ; fp=/${fp%/*}
+               # line[0] can be an absolutised path, bug #342929
+               local eprefix=$(canonicalize ${EPREFIX})
+               local rf=${fn}
+               # in case we deal with a symlink, make sure we don't replace it
+               # with a real file (sed -i does that)
+               if [[ -L ${fn} ]] ; then
+                       rf=$(readlink ${fn})
+                       [[ ${rf} != /* ]] && rf=${fn%/*}/${rf}
+                       # ignore symlinks pointing to outside prefix
+                       # as seen in sys-devel/native-cctools
+                       [[ $(canonicalize "/${rf#${D}}") != ${eprefix}/* ]] && continue
+               fi
+               # does the shebang start with ${EPREFIX}, and does it exist?
+               if [[ ${line[0]} == ${EPREFIX}/* || ${line[0]} == ${eprefix}/* ]] ; then
+                       if [[ ! -e ${ROOT%/}${line[0]} && ! -e ${D%/}${line[0]} ]] ; then
+                               # hmm, refers explicitly to $EPREFIX, but doesn't exist,
+                               # if it's in PATH that's wrong in any case
+                               if [[ ":${PATH}:" == *":${fp}:"* ]] ; then
+                                       echo "${fn#${D}}:${line[0]} (explicit EPREFIX but target not found)" \
+                                               >> "${T}"/non-prefix-shebangs-errs
+                               else
+                                       eqawarn "${fn#${D}} has explicit EPREFIX in shebang but target not found (${line[0]})"
+                               fi
+                       fi
+                       continue
+               fi
+               # unprefixed shebang, is the script directly in $PATH?
+               if [[ ":${PATH}:" == *":${fp}:"* ]] ; then
+                       if [[ -e ${EROOT}${line[0]} || -e ${ED}${line[0]} ]] ; then
+                               # is it unprefixed, but we can just fix it because a
+                               # prefixed variant exists
+                               eqawarn "prefixing shebang of ${fn#${D}}"
+                               # statement is made idempotent on purpose, because
+                               # symlinks may point to the same target, and hence the
+                               # same real file may be sedded multiple times since we
+                               # read the shebangs in one go upfront for performance
+                               # reasons
+                               sed -i -e '1s:^#! \?'"${line[0]}"':#!'"${EPREFIX}"${line[0]}':' "${rf}"
+                               continue
+                       else
+                               # this is definitely wrong: script in $PATH and invalid shebang
+                               echo "${fn#${D}}:${line[0]} (script ${fn##*/} installed in PATH but interpreter ${line[0]} not found)" \
+                                       >> "${T}"/non-prefix-shebangs-errs
+                       fi
+               else
+                       # unprefixed/invalid shebang, but outside $PATH, this may be
+                       # intended (e.g. config.guess) so remain silent by default
+                       has stricter ${FEATURES} && \
+                               eqawarn "invalid shebang in ${fn#${D}}: ${line[0]}"
+               fi
+       done
+       if [[ -e "${T}"/non-prefix-shebangs-errs ]] ; then
+               eqawarn "QA Notice: the following files use invalid (possible non-prefixed) shebangs:"
+               while read line ; do
+                       eqawarn "  ${line}"
+               done < "${T}"/non-prefix-shebangs-errs
+               rm -f "${T}"/non-prefix-shebangs-errs
+               die "Aborting due to QA concerns: invalid shebangs found"
+       fi
+}
 
 install_mask() {
        local root="$1"