#!/bin/bash #Shows unrequired packages and missing dependencies. #Author/Maintainer: Brandon Low #Author: Jerry Haltom echo echo -e "\x1b[31;01m!!! As of Gentoolkit 0.2.0, this tool is deprecated." echo -e "!!!\x1b[0;0m Please refer to 'emerge clean' and 'emerge depclean' for replacements." echo PROG=`basename ${0}` tmp="/tmp/$$" #Get PORTDIR and PORTDIR_OVERLAY from portage PORTDIR_OVERLAY="$(/usr/lib/portage/bin/portageq portdir_overlay)" PORTDIR="$(/usr/lib/portage/bin/portageq portdir)" rm -rf ${tmp} > /dev/null 2>&1 mkdir ${tmp} > /dev/null 2>&1 declare -i i set -- `getopt -n ${PROG} -o N,R,U,I,v,q,C,h -l needed,removed,unneeded,interactive,verbose,quiet,nocolor,help -- ${*/ --/};[ $? != 0 ] && echo "y"` while [ ${#} -gt 0 ] do a=${1} shift case "${a}" in -I|--interactive) interactive=y ;; -N|--needed) needed=y ;; -U|--unneeded) unneeded=y ;; -R|--removed) removed=y ;; -v|--verbose) verb=y ;; -q|--quiet) quiet=y ;; -C|--nocolor) nocolor=y ;; -h|--help) usage=y ;; --) [ ${1} ] && usage=y && broke=y break ;; *) usage=y broke=y echo "FIXME - OPTION PARSING - ${a}" break ;; esac done if [ ! ${needed} ] && [ ! ${unneeded} ] && [ ! ${removed} ]; then needed=y unneeded=y removed=y fi #Set up colors if [ ! "${nocolor}" ]; then NO="\x1b[0;0m" BR="\x1b[0;01m" CY="\x1b[36;01m" GR="\x1b[32;01m" RD="\x1b[31;01m" YL="\x1b[33;01m" BL="\x1b[34;01m" elif [ ${quiet} ] && ( ( [ ${needed} ] && [ ${unneeded} ] ) || ( [ ${unneeded} ] && [ ${removed} ] ) || ( [ ${removed} ] && [ ${needed} ] ) ); then NEED=" N" UNNE=" U" REMO=" R" fi if [ ${usage} ]; then echo -e "${BR}GenToolKit's Dependency Checker! ${NO}Displays packages that are installed but which none of the packages in world or system depend on, and displays packages which are depended on by world or system, but are not currently installed. ${BR}USAGE: ${BL}${PROG}${YL} [${NO}options${YL}]${NO} ${BL}${PROG}${GR} --help${NO} ${BR}OPTIONS: ${GR}-U, --unneeded${NO} display unneeded packages that are installed (${GR}green${NO}) ${GR}-N, --needed${NO} display needed packages that are not installed (${RD}red${NO}) ${GR}-R, --removed${NO} display installed packages not in portage (${YL}yellow${NO}) ${GR}-I, --interactive${NO} interactively modify world file before proceeding ${GR}-C, --nocolor${NO} output without color, if necessary, package types are noted with ${GR}U, N${NO} and ${GR}R${NO} respectively ${GR}-v, --verbose${NO} be more verbose ${GR}-q, --quiet${NO} be quiet (just output the packages, no extra info) ${BR}NOTES: ${GR}*${NO} If this script is run on a system that is not up-to-date or which hasn't been cleaned (with '${BL}emerge -c${NO}') recently, the output may be deceptive. ${GR}*${NO} If the same package name appears in all three categories, then it is definitely time to update that package and then run '${BL}emerge -c${NO}'. ${GR}*${NO} The ${GR}-U, -N${NO} and ${GR}-R${NO} options may be combined, defaults to ${GR}-UNR${NO}" rm -rf ${tmp} > /dev/null 2>&1 [ ${broke} ] && exit 1 || exit 0 fi X="\([^/]*\)" #Retrieve currently merged packages. if [ ${verb} ];then echo -e "${CY}Retrieving currently merged packages.${NO}" fi find /var/db/pkg/ -name '*.ebuild' | \ sed -e "s:/var/db/pkg/::" \ -e "s:${X}/${X}/${X}:\1/\2:" | \ sort -u >> ${tmp}/current if [ ${verb} ]; then echo -e "${CY}"`cat ${tmp}/current | wc -l` "currently merged packages.${NO}" echo -e fi #Retrieve system packages and add to image. if [ ${verb} ];then echo -e "${CY}Retrieving system packages.${NO}" fi emerge system -ep | \ sed -e "/ebuild/s:^.*] \([^ ]*\) *:\1:p;d" | \ sort -u \ > ${tmp}/system if [ ${verb} ]; then echo -e "${CY}"`cat ${tmp}/system | wc -l 2> /dev/null` "packages contained in system.${NO}" echo -e echo -e "${CY}Preparing world file.${NO}" fi #Create local copy of world and ask user to verify it. cp /var/cache/edb/world ${tmp}/world if [ ${interactive} ]; then ${EDITOR} ${tmp}/world fi #Retrieve world packages and dependencies and add to image. if [ ${verb} ]; then echo -e echo -e "${CY}Preparing list of installed world packages.${NO}" echo -e fi cat ${tmp}/current | grep -f ${tmp}/world | sort > ${tmp}/world.inst find ${PORTDIR} ${PORTDIR_OVERLAY} -iname '*.ebuild' | \ awk -F'/' '{printf("%s/%s\n", $(NF-2), $NF)}' | \ sed -e 's:\.ebuild::' > ${tmp}/ebuilds grep -xf ${tmp}/world.inst ${tmp}/ebuilds >> ${tmp}/world.new if [ ${verb} ]; then echo -e "${CY}"`cat ${tmp}/ebuilds | wc -l`"\tebuilds available.${NO}" echo -e "${CY}"`cat ${tmp}/world.new | wc -l`"\tpackages contained in final world file.${NO}" echo -e echo -e "${CY}List prepared, checking dependencies with emerge -ep${NO}" fi sort ${tmp}/world.new |sed -e 's:^:\\\=:' | uniq | xargs emerge -ep | \ tee ${tmp}/log | sed -e '/ebuild/s:^.*] \([^ ]*\) *$:\1:p;d' > ${tmp}/image.unsorted depends=`cat ${tmp}/image.unsorted|wc -l` if [ ${depends} -lt "2" ]; then echo -e "${RD}There appears to be an unresolved dependency in your world file." echo -e "Please check for masking errors or other world file issues," echo -e "and then try again." echo -e echo -e "The following is the emerge output for your reference:${NO}" cat ${tmp}/log rm -rf ${tmp} > /dev/null 2>&1 exit 1 fi cat ${tmp}/system >> ${tmp}/image.unsorted #Cleanup image sort -u ${tmp}/image.unsorted > ${tmp}/image if [ ${verb} ];then echo -e "${CY}"`cat ${tmp}/image | wc -l` "packages contained in final image.${NO}" echo -e fi #Determine packages that exist in current but not in image. #These packages are safe to clean up. if [ ${unneeded} ]; then if [ ! ${quiet} ]; then echo -e "${CY}These packages have no other packages depending on them.${NO}" fi grep -vxf ${tmp}/image ${tmp}/current > ${tmp}/unneeded for line in `cat ${tmp}/unneeded`;do echo -e "${GR}${line}${CY}${UNNE}${NO}" done if [ ! ${quiet} ];then echo -e "${CY}Total of"`cat ${tmp}/unneeded|wc -l` "unneeded packages.${NO}" fi fi #Determine packages that exist in image but not in current. #These packages should be added. if [ ${needed} ]; then if [ ! ${quiet} ];then echo -e echo -e "${CY}These packages are depended upon but are not present on the system.${NO}" fi grep -vxf ${tmp}/current ${tmp}/image > ${tmp}/needed for line in `cat ${tmp}/needed`;do echo -e "${RD}${line}${CY}${NEED}${NO}" done if [ ! ${quiet} ];then echo -e "${CY}Total of"`cat ${tmp}/needed|wc -l` "needed packages.${NO}" fi fi #Determine packages that are installed but not currently in portage if [ ${removed} ]; then if [ ! ${quiet} ];then echo -e echo -e "${CY}These packages are installed but not in the portage tree.${NO}" fi grep -xf ${tmp}/current ${tmp}/ebuilds > ${tmp}/hascurrent grep -vxf ${tmp}/hascurrent ${tmp}/current > ${tmp}/removed for line in `cat ${tmp}/removed`;do echo -e "${YL}${line}${CY}${REMO}${NO}" done if [ ! ${quiet} ];then echo -e "${CY}Total of"`cat ${tmp}/removed|wc -l` "removed packages.${NO}" fi fi rm -rf ${tmp} > /dev/null 2>&1