TIP Easy cleaning of package.keywords

From Gentoo Linux Wiki

Jump to: navigation, search
This article is part of the Tips & Tricks series.
Terminals / Shells Network X Window System Portage System Filesystems Kernel Other
Merge-arrows.gif It has been suggested that this article be Merged into one article with TIP_Clean_Portage_Package_Dot_Files.    (Discuss)

[edit] A even more totally new approach

Since 0.6.2, eix can do all this on its own, with -t and -T parameters. Consult man eix on usage details.

[edit] Easy script for cleaning of /etc/portage/package.keywords

Do you know that problem: After syncing your tree, you have to check every entry in /etc/portage/package.keywords if is has gone stable. I wrote a simple script which take all entries in /etc/portage/package.keywords and uses EiX to check the packages. It displays the entries you don't need anymore. It's rather dumb, so you better check the results of the script.

Warning: you have to put 'LOCAL_PORTAGE_CONFIG=false' in /etc/eixrc for eix to provide the right output. this option prevents eix from "masking the output" with the contents of /etc/portage/*, it displays the values purely from you portage tree.

Code: Script to clean /etc/portage/package.*
#!/bin/sh

echo "## Cleaning out package.keywords..."

atoms=`cat /etc/portage/package.keywords | grep -P "^[a-z]*\-[a-z]*\/.*~x86$" | sed 's/\s*~x86$//'`

for i in $atoms
do
        cat=`echo $i | sed 's/\/.*//'`
        atom=`echo $i | sed 's/.*\///'`
        installedversion=`eix -C $cat -e $atom | grep Installed | sed 's/.*\s\([^\s]*\)$/\1/'`
        availableversions=`eix -C $cat -e $atom | grep Available`
        if [ "$installedversion" == "" ]; then
                echo "$cat/$atom : Problem!"
        else
                result=`echo $availableversions | grep -P "\s$installedversion(\s|\[)"`
                if [ ! "$result" == "" ]; then
                        echo "$cat/$atom : not needed in package.keywords!";
                fi
        fi
done

[edit] A totally new approach

I looked at the code above and didn't understand it and what a better way to understand the code, then to rewrite the whole script? It turned out that you can very easily check for a *little* more than the script above and also fix a few eventualities the above script doesn't think of (eg. comments in a file). There are certain things you should be aware of, if you use this (or the above) script, non of which are dangerous:

  • I use eix 0.5.1 which is still ~x86. 0.5.0 has problems with package.mask, some packages (all related to modular xorg) appear unmasked, when in fact they are still masked. eix 0.5.1 fixes this.
  • As the above script it requires the line 'LOCAL_PORTAGE_CONFIG=false' in either ~/.eixrc or /etc/eixrc
  • On multislotted packages (eg. gcc or gtk+) this script only checks the newest version. If the entry in package.mask or package.keyword is for the lower version (eg. some gcc 3.3 or gtk+ 1.2) it will still tell you it has gone stable because the higher installed version is no longer (or never has been) masked or marked unstable.
  • On my other machine, which happens to be an Athlon64, grep for some reason doesn't support pcre (perl compatible regular expressions). Simply replace all "grep -P" with "pcregrep".

This script checks in both package.mask and package.keywords if

  • The package itself is still in portage (or any overlay)
  • The package is installed
  • The specific version is still in portage
  • The version of the package that is installed is now stable


Well enough blabla, here is the script:

Code: Script to clean /etc/portage/package.*
#!/bin/bash

echo "## Showing useless entries in package.keywords..."
while read line; do 
        # skip empty or commented out lines
        if [[ $(echo $line | grep ^[^\#$]) == "" ]]; then
                continue
        fi
        
        # parse the entry from the file
        category=`echo $line | cut -d" " -f1 | sed -e 's/^[<>=]*//' -e 's/\/.*//'`
        package=`echo $line | cut -d" " -f1 | sed  -e 's/^[<>=]*[a-z]*\-[a-z]*\///' -e 's/\-[0-9].*$//'`
        # parse the output of eix
        installed_version=`eix --format '{installedversions}<installedversions>{else}none{}' -C $category -e $package | head -n 1`
        available_versions=`eix --format '<availableversions>' -C $category -e $package | head -n 1`

        if [[ "$installed_version" == "" ]]; then
                echo "$category/$package: Package does not exist (or a problem occured)"                                                                                                    
                continue
        fi

        if [[ "$installed_version" == "none" ]]; then
                echo "$category/$package: Package is not installed"
                continue
        fi

        if [[ $(echo $available_versions | grep -P "$installed_version(\s|\[)") == "" ]]; then
                echo "$category/$package: $installed_version is no longer in Portage"       
        fi

        if [[ $(echo $available_versions | grep -P "\s$installed_version(\s|\[)") != "" ]]; then
                echo "$category/$package has become stable"
        fi

done < /etc/portage/package.keywords

echo -e "\n## Showing useless entries in package.unmask..."

while read line; do
        if [[ $(echo $line | grep ^[^\#$]) == "" ]]; then
                continue
        fi
        
        category=`echo $line | cut -d" " -f1 | sed -e 's/^[<>=]*//' -e 's/\/.*//'`
        package=`echo $line | cut -d" " -f1 | sed  -e 's/^[<>=]*[a-z]*\-[a-z]*\///' -e 's/\-[0-9].*$//'`
        installed_version=`eix --format '{installedversions}<installedversions>{else}none{}' -C $category -e $package | head -n 1`
        available_versions=`eix --format '<availableversions>' -C $category -e $package | head -n 1`

        if [[ "$installed_version" == "" ]]; then
                echo "$category/$package: Package does not exist (or a problem occured)"
                continue
        fi
        
        if [[ "$installed_version" == "none" ]]; then
                echo "$category/$package: Package is not installed"
                continue
        fi

        if [[ $(echo $available_versions | grep -P "$installed_version(\s|\[)") == "" ]]; then
                echo "$category/$package: $installed_version is no longer in portage"
                continue
        fi
        
        if [[  $(echo $available_versions | grep -P "\[M\]$installed_version(\s|\[)") == "" ]]; then
                echo "$category/$package is no longer masked"                                                               
        fi                                                                                                                  
                                                                                                                            
done < /etc/portage/package.unmask

Personal tools