Search:  
Gentoo Wiki

Tip_Make_common_emerges_easier_with_an_update_script

Contents

Usages

Every once in a while I run into an emerge that I tend to run often. These emerges are simple, usually they involve simply updating a few svn, bzr, or git packages. To make this easier, and also ease rebuilding an entire system, I wrote this script.

Script: rebuild

#!/bin/bash
packagedir="/home/mozes/scripts/package_lists"
total=-1
builtcorrect=0
triedtobuild=0
function count(){
        if [ "$total" -lt "1" ]
        then
                for p in $list; do
                        total=$(( $total + 1 ))
                done
                if [ "$total" -ge "30" ]
                then
                        NEEDLESS=yes
                else
                        CUSTOM=custom
                        NEEDLESS=no
                fi
        else
                tbroken=0
                for p in $broken; do
                        tbroken=$(( $tbroken + 1 ))
                done
                if [ "$tbroken" -ge "30" ]
                then
                        NEEDLESS=yes
                else
                        NEEDLESS=no
                fi
        fi
}
function list_updates(){
        if [ -n "$plist" ]
        then
                prettylist="\n${plist}"
        else
                for x in $list; do
                        prettylist="${prettylist}\n ${GOOD}\0452${NORMAL} ${x}"
                done
        fi
        if [ "$NEEDLESS" == "yes" ]
        then
                echo -e "This is the list of packages to emerge:${prettylist}" | less
        else
                echo -e "This is the list of packages to emerge:${prettylist}"
        fi
}
function build(){
        for x in $list; do
                buildcount=0
                echo -e " ${GOOD}\0452${NORMAL} (${currentpackage} of ${total}) Building ${x}"
                if [ "$triedtobuild" != "$builtcorrect" ]
                then
                        echo -e " ${BAD}\0452${NORMAL} Only $builtcorrect out of the $triedtobuild packages have been built correctly"
                fi
                triedtobuild=$(( $triedtobuild + 1 ))
                PORTAGE_ELOG_SYSTEM="save $CUSTOM" FEATURES="${features}" emerge -v1 ${x} && buildcount=1 && builtcorrect=$(( $builtcorrect + 1 ))
                if [ "$buildcount" == "0" ]
                then
                        echo -e " ${GOOD}\0452${NORMAL} (${currentpackage} of ${total}) Trying to build ${x} again"
                        PORTAGE_ELOG_SYSTEM="save $CUSTOM" FEATURES="${features}" emerge -v1 ${x} && buildcount=1 && builtcorrect=$(( $builtcorrect + 1 ))
                fi
                if [ "$buildcount" == "0" ]
                then
                        echo "Couldn't successfully build ${x}"
                        broken="${broken}\n ${GOOD}\0452${NORMAL} ${x}"
                fi
                currentpackage=$(( $currentpackage + 1 ))
        done
}
function question(){
        echo "Do you want to continue with the emerge? (Y/n)"
        read x
        if [ "${x}" == "n" ]
        then
                exit 0
        elif [ "${x}" == "" ] || [ "${x}" == "Y" ] || [ "${x}" == "y" ]  || [ "${x}" == "yes" ]  || [ "${x}" == "YES" ] || [ "${x}" == "Yes" ]
        # This does multiple matchings, i want it to continue by default if nothing is entered
        then
                continue_script
        else
                echo "Sorry, response '${x}' not understood."
                question
        fi
}
function continue_script(){
        build
        if [ -e ${packagedir}/$brokenname ]
        then
                rm ${packagedir}/$brokenname
        fi
        if [ -n "${broken}" ]
        then
                count
                echo -e "${broken}" | sed -e 's/\*//g' -e 's/\ //g' -e 's/^............//g' | grep '\.' > ${packagedir}/${brokenname}
                if [ "$NEEDLESS" == "yes" ]
                then
                        echo -e " ${BAD}\0452${NORMAL} Only $builtcorrect out of the $triedtobuild packages have been built correctly\nThese are the packages that are broken:${broken}\nThese can be retried with '`basename $0` $brokenname'" | less
                else
                        echo -e " ${BAD}\0452${NORMAL} Only $builtcorrect out of the $triedtobuild packages have been built correctly\nThese are the packages that are broken:${broken}\nThese can be retried with '`basename $0` $brokenname'"
                fi
        else
                echo -e "All packages built correctly."
        fi

}
currentpackage=1
total=0
GOOD=$'\e[32;01m'
BAD=$'\e[31;01m'
NORMAL=$'\e[0m'


case "$1" in
        world)
                echo "Getting a list of packages to be upgraded"
                plist=`emerge -pvuDN world | grep ebuild`
                list=`echo "${plist}" | sed -e 's/^................/=/g' | awk '{ print $1 }'`
                listupdates=yes
                brokenname=broken.world
                ;;
        system)
                echo "Getting a list of packages to be upgraded"
                plist=`emerge -pvuDN system | grep ebuild`
                list=`echo "${plist}" | sed -e 's/^................/=/g' | awk '{ print $1 }'`
                listupdates=yes
                brokenname=broken.system
                ;;
        *)
                recheck=yes
esac


if [ "$recheck" == "yes" ]
then
        case "$2" in
                world)
                        echo "Getting a list of packages to rebuild"
                        plist=`emerge -pveuDN world | grep ebuild | grep -v open-office`
                        list=`echo "${plist}" | sed -e 's/^................/=/g' | awk '{ print $1 }'`
                        listupdates=yes
                        brokenname=broken.e.world
                        ;;
                system)
                        echo "Getting a list of packages to rebuild"
                        plist=`emerge -pveuDN system | grep ebuild`
                        list=`echo "${plist}" | sed -e 's/^................/=/g' | awk '{ print $1 }'`
                        listupdates=yes
                        brokenname=broken.e.system
                        ;;
                *)
                        if [ -n "$1" ] && [ -e "${packagedir}/$1" ]
                        then
                                if [ -n "`cat ${packagedir}/$1 | sed -n '1p' | grep 'FEATURES'`" ]
                                then
                                        features=`cat ${packagedir}/$1 | sed -n '1p' | awk -F "\"" '{ print $2 }'`
                                        lc=`cat ${packagedir}/$1 | wc -l`
                                        list=`cat ${packagedir}/$1 | sed -n 2,${lc}p `
                                        listupdates=yes
                                else
                                        list=`cat ${packagedir}/$1`
                                        listupdates=yes
                                fi
                                if [ "`echo "$1" | head -c 6`" == "broken" ]
                                then
                                        brokenname=$1
                                else
                                        brokenname=broken.$1
                                fi
                        else
                                for x in `ls -1 ${packagedir}`
                                do
                                        packagelist="${packagelist}|${x}"
                                done
                                echo "`basename $0` {e} {world|system${packagelist}}"
                                echo "e stands for 'emptytree'"
                        fi
        esac
fi

if [ -n "${list}" ]
then
        count
        if [ "$listupdates" == "yes" ]
        then
                list_updates
        fi
        question
else
        echo "Nothing to do... exiting"
fi

How to set up

In order to use this script, you simply need to modify the variable "packagedir" (the second line of the script) Change it to point at an empty directory, we will put something in it later (if you want it to take care of -9999 packages) In its current state, it will be more than happy to function. You can run

  1. ./rebuild world

and it will output a list of <world> updates, if the list is longer 30 packages, it will output it in `less` so that you can view all of them. As the script continues, it will ask you if you want to perform the action (update). If you answer yes it will update those packages, 1 emerge at a time. If it fails on one it will retry it. If it fails a second time it simply moves on.

When the script has finished the emerge, it will tell you which packages it failed on, and outputs those failed packages to $packagedir/broken.$1 (or if it is an empty tree merge to $packagedir/broken.e.$1)

As soon as a file is within the $packagedir folder, it can be specified as an argument to rebuild

Package File Syntax

This syntax is very simple, as anything you can pass directly to emerge will get sent on directly to emerge

  1. Packages should be 1 per line
  2. You can specify versions with =${packagename}-$version
  3. You CAN specify special FEATURES for a package group.
    1. Must be done on the first line, and must be done with FEATURES="$whatever"

Sample Package File

compiz-fusion

x11-wm/compiz
x11-libs/compiz-bcop
x11-plugins/compiz-fusion-plugins-main
x11-plugins/compiz-fusion-plugins-extra
x11-plugins/compiz-fusion-plugins-unsupported
x11-plugins/compiz-fusion-plugins-wallpaper
x11-plugins/compiz-plugins-screensaver
x11-wm/emerald
x11-themes/emerald-themes
x11-libs/libcompizconfig
dev-python/compizconfig-python
x11-apps/ccsm
x11-apps/fusion-icon

Bugs

Ignores issues with compatibility

It doesn't care if a package is Fetch restricted, or if it Blocks another package. It will still try to emerge it.

Retrieved from "http://www.gentoo-wiki.info/Tip_Make_common_emerges_easier_with_an_update_script"

Last modified: Thu, 04 Sep 2008 06:01:00 +0000 Hits: 1,713