LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Gentoo (http://www.linuxquestions.org/questions/gentoo-87/)
-   -   Script to generate package.use from currently installed packages (http://www.linuxquestions.org/questions/gentoo-87/script-to-generate-package-use-from-currently-installed-packages-810482/)

mcolangelo 05-27-2010 11:18 AM

Script to generate package.use from currently installed packages
 
This script will examine use flags for every package currently installed on a system and generate an appropriate "package.use" file.

Notes:
  • The final package.use file is written to "/tmp/package.use". I would recommend at least some examination prior to moving it to /etc/portage
  • Although the file shouldn't contain duplicates maybe double check it or pipe it through sort before moving it to /etc/portage
    Code:

    cat /tmp/package.use | sort -u > /etc/portage
  • The script isn't perfect but it's a lot better than doing it by hand :)

Any improvements, suggestions, and feedback is welcome.

Code:

#!/bin/bash
# Matt Colangelo
# Generate a package.use file based on currently installed packages

IFS=$'\n'

#check if the list has already been created
if [ -e /tmp/installed_packages ]
then
    echo "Installed package list already exists skipping generation of installed package list"
else
    echo "Generating list of installed packages"
    equery list > /tmp/pkglst.tmp
fi


#sanitize installed packages list by stripping the version numbers
for line in `cat /tmp/pkglst.tmp`
do
    PKGNAME=`echo ${line} | sed 's/-[r].*$//;s/.[^-]*$//'`
    echo ${PKGNAME} >> /tmp/installed_packages
done

# remove duplicates from the list
mv /tmp/installed_packages /tmp/pkglst.tmp
cat /tmp/pkglst.tmp | sort -u > /tmp/installed_packages

# loop through the list of packages and use equery to generate list of +/- use flags
for x in `cat /tmp/installed_packages`
do

    equery u ${x} > /tmp/useFlags.tmp
    # sanitize use flags by removing plus symbols
    # translates -flag1 +flag2 -flag3 +flag4  into  -flag1 flag2 -flag3 flag4
    cat /tmp/useFlags.tmp | sed 's/\+//g' > /tmp/uses.tmp
   
    ## if you don't want to include -flags in your package.use then use this command instead
    # cat /tmp/useFlags.tmp | grep -Ev '\-{1}[a-zA-Z]+' | sed 's/\+//g' > /tmp/uses.tmp


    #count the number of use flags for the package - no need to include packages without any flags
    NUMFLAGS=`wc -l /tmp/uses.tmp | grep -E -o '[0-9]*'`   
    echo "${x} has ${NUMFLAGS} use flags"

    #if use flags exists than create a line to be appended to the temporary package.use file
    if [ $NUMFLAGS -gt 0 ]
    then
        PKGFLAGS="${x}"
        for uflag in `cat /tmp/uses.tmp`
        do
            PKGFLAGS="${PKGFLAGS} ${uflag}"
        done
        echo $PKGFLAGS
        echo $PKGFLAGS >> /tmp/package.use
        # reset flag count to 0 - and proceed to next package in list
        NUMFLAGS=0
    fi
done

**update**

the list USE flags generated by equery is incorrect when the output is piped to a file, not sure how I missed it. Either way I've figured out a solution to the problem and will be updating the above code. Sorry :(

mcolangelo 05-27-2010 02:01 PM

Fixed
 
I left the original script in case there is anyone who might know how to change equery's piped output.

This one is ugly but it DOES work. There are some issues with the preg_replace patterns but it only affected a small number of packages. It's also significantly slower than the previous bash script since I decided to use php.

Again double check the output and pipe it through sort to get a new package.use file.

Script still beats doing it by hand, especially when you're dealing with a ton of packages and use flags that have always been set on the command line.


Code:


#!/usr/bin/php
<?php

set_time_limit(480);

// generate list of installed packages
exec('equery list > /tmp/pkglist.tmp');
//load the package list into an array
$packages = file('/tmp/pkglst.tmp');

// open the file where we will write our final output for package.use
$packageUse = fopen('/tmp/package.use','w+');


// create an array of clean package names and equery that package
foreach($packages as $indx=>$package)
{
  //strip the version numbers leaving only a package name
  $pat = "/-[r].*$/";
  $package = preg_replace($pat,"",$package);
  $pat = "/.[^-]*$/";
  $package = trim(preg_replace($pat,"",$package));
 
 
  // check for empty line, useless to run equery against nothing
  if("$package" != "")
    {
     
      // get the flags from equery and output to a temporary file
      exec("equery -N uses $package > /tmp/pkg.uses");
      // load flags into an array for examination
      $flags = file('/tmp/pkg.uses');
     
      // size of the array - The first 6 lines of the output is useless
      // and if the size is less than 6 lines then there are no use flags
      $arySize = sizeof($flags);
      if($arySize > 5)
        {
          // start reading from line 6
          for($k=6; $k<=$arySize; $k++)
            {
              // format the line into something more useful
              $fields = explode(' ',$flags[$k]);
             
              // field 2 indicates the current use flags state (field 0 is the system wide setting for that flag)
              $isSet = $fields[2];
              // remove the plus symbol
              $isSet = preg_replace("/\+/","",$isSet);
             
              // get the use flag's name
              $flagName = $fields[3];
             
              // put it all back together again  ie: -flag or flag
              $pkgFlags .= " " . trim($isSet) . trim($flagName);
             
            }
          // put it back together  ie: some-class/packageName flag1 -flag2 flag3
          $outp = trim("$package $pkgFlags")."\n";
          // output so we can watch what's happening
          echo $outp;
          //write it to the file
          fwrite($packageUse,$outp);
          unset($pkgFlags);
        }
    }
  //remove the temporary file
  unlink("/tmp/pkg.uses");
 
  // proceed to next package in list
 
}

?>

at least it's something right?? Start the script, go eat a sandwich and return to examine your use list.


All times are GMT -5. The time now is 06:14 AM.