add depcheck

This commit is contained in:
mudler
2016-09-10 12:40:45 +02:00
parent b34388c259
commit e86c134e61
2 changed files with 304 additions and 0 deletions
+1
View File
@@ -23,6 +23,7 @@ install:
install -d $(DESTDIR)/$(USBINDIR)
install -m 0755 builder $(DESTDIR)/$(USBINDIR)/
install -m 0755 depcheck $(DESTDIR)/$(USBINDIR)/
install -d $(DESTDIR)/$(UBINDIR)
install -m 0755 sabayon-* $(DESTDIR)/$(UBINDIR)/
+303
View File
@@ -0,0 +1,303 @@
#!/bin/bash
# PODNAME: depcheck
#
# Copyright (c) 2014 Michael Palimaka <kensington@gentoo.org>
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
# THE SOFTWARE.
#
# A tool to report both undeclared and potentially-unused runtime dependencies.
#
# Depends on app-misc/pax-utils, app-portage/portage-utils and
# sys-apps/gentoo-functions.
DEBUG=FALSE
IGNORE_DEPS=( "sys-libs/glibc" "sys-devel/gcc" )
IGNORE_LINKS=( "/lib64/libgcc_s.so.1" )
PKG_DIR="/var/db/pkg/"
. /lib/gentoo/functions.sh
bold() {
echo $@
return
local bold=$(tput bold)
local normal=$(tput sgr0)
echo "${bold}${@}${normal}"
}
debug() {
if [ $DEBUG = TRUE ]; then
# write to stderr so as not to interfere with function returns
echo "$@" 1>&2
fi
}
# app-foo/bar-1.2.3-r1 -> app-foo/bar
remove_atom_version() {
local atom=`qatom "${1}" | cut -d " " -f 1-2 | tr " " /`
echo $atom
}
virtualcheck() {
debug Checking if ${libowner_pn} is provided by a virtual
for virtual in $(qdepends --nocolor --name-only --${1} --query ${libowner_pn} | grep ^virtual/)
do
debug Checking if ${virtual} is in dependencies
local isvirtualdep=$(qdepends --${1} ${atom} | grep ${virtual})
if [ $? -eq 0 ]; then
used_virtuals+=( ${virtual} )
continue 2
fi
done
if [ "${1}" = "depend" ]; then
eerror "${obj} links to ${link}"
fi
eindent
eerror Missing ${1^^} on $(bold ${libowner_pn})
eoutdent
errors=1
}
check_atom() {
local errors=0
local atom=$1
local checked=()
local rdepends=()
local used_virtuals=()
local objects=`qlist -qo ${atom}`
if [ ! "${objects}" ]; then
einfo ${atom} does not have any objects installed, skipping...
echo
return
fi
if [ -z "${INSIDE_PORTAGE}" ]; then
einfo Checking ${atom} for undeclared dependencies
eindent
fi
local obj
for obj in $objects
do
debug "Checking ${obj}"
readelf -h ${obj} > /dev/null 2>&1
# can it have stuff linked to it?
if [ $? -ne 0 ]; then
debug "It can't have links, skipping"
continue
fi
local elf=`scanelf --format "#f%n" --nobanner --use-ldpath ${obj} 2>&1`
local links=`echo ${elf} | tr "," " "`
# get a list of everything that it's linked to
local link
for link in $links
do
local ignore
for ignore in "${IGNORE_LINKS[@]}"; do
if [ "${ignore}" = "${link}" ]; then
debug "Ignoring ${link} due to blacklist"
continue 2
fi
done
# only check a library once per atom for performance reasons
local check
for check in "${checked[@]}"; do
if [ "${check}" = "${link}" ]; then
debug "Already checked ${link} for this atom, skipping"
continue 2
fi
done
checked=( "${checked[@]}" "${link}" )
debug "Found ${link}"
local libowner=`qfile -vqC ${link} | uniq`
if [ ! "${libowner}" ]; then
ewarn "Warning: installed file ${obj} is linked to ${link} which is not owned by any installed atom."
continue
fi
debug "Owning package for ${link} is ${libowner}"
local libowner_pn=$(remove_atom_version ${libowner})
local my_pn=$(remove_atom_version ${atom})
rdepends+=( "${libowner_pn}" )
if [ "${libowner_pn}" = "${my_pn}" ]; then
debug "Owning package is self, ignoring"
continue
fi
local ignorelib
for ignorelib in "${IGNORE_DEPS[@]}"
do
if [ "${libowner_pn}" = "${ignorelib}" ]; then
debug "Ignoring objects belonging to ${ignorelib}"
continue 2
fi
done
debug "Checking if ${libowner_pn} is in the [R]DEPEND list of ${atom}"
local isdep
isdep=`qdepends -d ${atom} | grep ${libowner_pn}`
if [ $? -ne 0 ]; then
virtualcheck depend
fi
local isrdep
isrdep=`qdepends -r ${atom} | grep ${libowner_pn}`
if [ $? -ne 0 ]; then
virtualcheck rdepend
fi
done
done
local ebuild_rdepends=()
for rdepend in $(qdepends --nocolor --quiet --rdepend ${atom} | sed -e "s/\[[^]]*\]//g" | cut -d : -f 2-)
do
if [[ ${rdepend} = !* ]] ; then
debug Skipping blocker: ${rdepend}
continue
elif [[ ${rdepend} = virtual/* ]] ; then
for virtual in "${used_virtuals[@]}"
do
if [[ ${virtual} == $(remove_atom_version ${rdepend}) ]]; then
debug Skipping virtual: ${rdepend}
continue 2
fi
done
fi
ebuild_rdepends+=( $(remove_atom_version $rdepend) )
done
debug "Ebuild RDEPENDS: ${ebuild_rdepends[@]}"
debug "Linked RDEPENDS: ${rdepends[@]}"
local suspect_rdepends=$(comm -13 <(echo ${rdepends[@]} | sed 's/ /\n/g' | sort -u) <(echo ${ebuild_rdepends[@]} | sed 's/ /\n/g' | sort -u))
if [ "${suspect_rdepends}" ]; then
ewarn "Suspect RDEPEND: $(bold ${suspect_rdepends})"
fi
if [ -z "${INSIDE_PORTAGE}" ]; then
eoutdent
if [ -n "${CAT}" ]; then
echo
fi
fi
return $errors
}
check_package() {
local package=$1
local atoms=`qlist -IcCS ${package} | tr ' ' '-' | cut -d : -f1`
debug Package ${package} own atoms: ${atoms}
if [ ! "${atoms}" ]; then
eerror ERROR: ${package} is not a valid atom
exit 1
fi
for atom in ${atoms}; do
check_atom ${atom}
done
}
check_category() {
local errors=0
for package in `ls "${PKG_DIR}/${1}"`; do
check_package "${1}/${package}"
if [ $? -ne 0 ]; then
errors=1
fi
done;
return $errors
}
BINNAME=`basename ${0}`
if [ -z $1 ]; then
echo "Checks emerged package(s) for undeclared depedencies"
echo
echo "Usage: ${BINNAME} [ atom | -c category | -a ]"
echo
echo "Examples:"
echo "Check a single package: ${BINNAME} app-foo/bar-1.2.3"
echo "Check a category: ${BINNAME} -c app-foo"
echo "Check everything: ${BINNAME} -a"
exit 1
fi
# check a particular category
if [ "$1" = "-c" ]; then
CAT=$2
if [ ! -d "${PKG_DIR}/${CAT}" ]; then
eerror ERROR: No packages from the category ${CAT} have been emerged yet
exit 1
fi
check_category $CAT
# check everything
elif [ "$1" = "-a" ]; then
for category in `ls ${PKG_DIR}`; do
check_category $category
done;
else
check_package $1
fi
if [ $DEBUG = TRUE ]; then
if [ $? -eq 0 ]; then
einfo Checking complete, no errors found
else
eerror Checking complete, errors found
fi
fi