You are not logged in.

#1 2010-02-18 13:38:34

drsjlazar
Member
From: Kasama
Registered: 2009-10-01
Posts: 133
Website

Pacleanup: A script to clean up package bloat

Hi all!

Here is my first real contribution to the Arch community! w00t!

Do you install packages just to try them out and never end up using them? Do you forget about them and do they just add to the bloat on your system? Do you want to review the packages installed on your system and remove the packages you don't need/want anymore? I do, so I wrote a small script to do just that.

There may already be a better way to do this that I don't know of. If there is, please do let me know.

Basically, the script goes through the packages marked as 'explicitly installed' and queries the user whether they want to keep or remove the packages. It does some basic dependency checking that will not remove a package if it is required by a package you want to keep. It stores a list of packages that you have previously selected to keep, so that you don't have to select them every time you run the script. An option to review the list of packages to remove is provided. It also, removes unused dependencies.

After the script has done its stuff, pacman will display packages to be removed and it will prompt you to accept the changes to be made. So it is pretty safe. You won't end up removing critical packages unless you explicitly allow pacman to do so.

Suggestions and corrections are most welcome!

Here it is!

#!/bin/bash

#--VARIABLES--
WDIR="$HOME/.pacleanup"
EXPLINST="$WDIR/explicitly-installed"
WRKLIST="$WDIR/working-list"
DEPLIST="$WDIR/dep-list"
KEEPS="$WDIR/keep-pkgs"
REMS="$WDIR/rm-pkgs"
SAFEREMS="$WDIR/rm-safe"
TMPREMS="$SAFEREMS.tmp"
TMPEXPL="$EXPLINST.tmp"
TMPDEPLIST="$DEPLIST.tmp"
#/VARIABLES

set -u

#--FUNCTIONS--
#SYSTEM CHECKS
checks () {
echo "==> Running checks..."

#Check user
guy=`whoami`

if [ "$guy" = "root" ]
then
  echo
  echo "==> Please run as normal user with sudo privileges"
  exit 1
fi

#Check working directory
if [ -d $WDIR ]
then
  echo
  echo "==> $WDIR exists"
else
  mkdir -p $WDIR
  echo
  echo "==> $WDIR created"
fi

#Check working files
fileCheck $EXPLINST
fileCheck $REMS
fileCheck $SAFEREMS
fileCheck $WRKLIST
fileCheck $DEPLIST

#Get list of explicitly installed packages
getExplInst

#Process existing list of packages to keep or ceate new file
if [ -f $KEEPS ]
then
  keepCheck=`cat $KEEPS`
  if [ -n "$keepCheck" ]
  then
    echo
    echo "==> Old $KEEPS detected!"
    echo "==> You can use this list to automatically keep these packages"
    echo "==> Do you want to keep your old list? [y/n]"
    read ans
    case $ans in
      y)
    touch $KEEPS
    cp $EXPLINST $TMPEXPL
    for keeper in `cat $KEEPS`
    do
      cat $TMPEXPL | sed -e "/^$keeper$/d" > $WRKLIST
      rm $TMPEXPL
      cp $WRKLIST $TMPEXPL
    done
    rm $TMPEXPL
      ;;
      n)
    rm $KEEPS
    touch $KEEPS
    cp $EXPLINST $WRKLIST
      ;;
      *)
    echo "==> You must choose y or n"
    echo "==> Exiting."
    exit 1
      ;;
    esac
  else
    fileCheck $KEEPS
    cp $EXPLINST $WRKLIST
  fi
else
  fileCheck $KEEPS
  cp $EXPLINST $WRKLIST
fi
echo
}

#WORKING FILE CREATOR
fileCheck () {
if [ -f $1 ]
then
  rm $1
fi
touch $1
}

#EXPLICITY INSTALLED LIST GENERATOR
getExplInst () {
pacman -Qe | cut -d " " -f1 > $EXPLINST
}

#QUERY PACKAGE
queryKeep () {
for pkg in `cat $WRKLIST`
do
  echo -e "==> Do you want to keep \033[1m$pkg\033[0m [y/n/i/q/d]"
  read action
  queryAction $action
  echo
done
}

#PROCESS QUERY RESPONSE
queryAction () {
case $action in
  y)
    echo "==> Keeping $pkg"
    echo $pkg >> $KEEPS
  ;;
  n)
    echo "==> Removing $pkg"
    echo $pkg >> $REMS
  ;;
  i)
    echo "==> $1 Info"
    pacman -Qi $pkg
    echo -e "==> Do you want to keep \033[1m$pkg\033[0m [y/n/i/q/d]"
    read action
    queryAction $action
  ;;
  q)
    echo "==> Exiting"
    exit 0
  ;;
  d)
    echo "==> Done with selection"
    break
  ;;
  *|"")
    echo "==> y=yes n=no i=info q=quit d=done with selection"
    echo "==> Choose y/n/i/q/d"
    read action
    queryAction $action
  ;;
esac
}

#CHECK FOR DEPENDENCIES
depCheck () {
echo
echo "==> Checking dependencies..."
cp $REMS $SAFEREMS
cp $EXPLINST $DEPLIST
for rmpkg in `cat $SAFEREMS`
do
  cat $DEPLIST | sed -e "/^$rmpkg$/d" > $TMPDEPLIST
  rm $DEPLIST
  mv $TMPDEPLIST $DEPLIST
done

for pkg in `cat $DEPLIST`
do
  deps=`cat /var/lib/pacman/local/$pkg-*/depends | sed '0,/%OPTDEPENDS%/!d' | grep -v "^%\|^$" | sed ':a;N;$!ba;s/\n/ /g'`
  for dirtydep in $deps
  do
    cleandep=`echo $dirtydep | cut -d "<" -f1 | cut -d ">" -f1 | cut -d "=" -f1`
    cat $SAFEREMS | sed -e "/^$cleandep$/d" > $TMPREMS
    rm $SAFEREMS
    mv $TMPREMS $SAFEREMS
  done
done
echo "==> Dependency check completed."
}

#REVIEW PACKAGES TO REMOVE
review () {
queue=`cat $SAFEREMS`

if [ -z "$queue" ]
then 
  echo "==> No packages selected for removal"
  echo "==> Exiting"
else
  echo
  echo "==> The following packages are selected for removal:"
  echo "$queue"
  echo "==> Do you wish to modify this selection? [y/n/q]"
  read review
  case $review in
    y)
      rm $WRKLIST
      rm $REMS
      mv $SAFEREMS $WRKLIST
      queryKeep
      depCheck
      review
    ;;
    n)
      echo "==> Proceeding to remove packages and orphans..."
      sudo pacman -Rsn `cat $SAFEREMS`
    ;;
    q)
      echo "==> Exiting."
    ;;
    *)
      echo "==> You must choose y/n/q"
      review
    ;;
  esac
fi
}

#CLEAN UP WORKING FILES
cleanUp () {
rm $EXPLINST
rm $REMS
rm $SAFEREMS
rm $WRKLIST
rm $DEPLIST
}
#/FUNCTIONS

#--RUN--
set -e
checks
queryKeep
depCheck
review
cleanUp
#/RUN

Changelog:
25 March 2010
- Changed dependency checking to use /var/lib/pacman/local/*/depends instead of pacman

Last edited by drsjlazar (2010-03-25 20:43:03)

Offline

#2 2010-02-18 21:43:23

cesura
Package Maintainer (PM)
From: Tallinn, Estonia
Registered: 2010-01-23
Posts: 1,867

Re: Pacleanup: A script to clean up package bloat

well done sir. You should add an option to skip to the end though

Offline

#3 2010-02-18 22:01:20

drsjlazar
Member
From: Kasama
Registered: 2009-10-01
Posts: 133
Website

Re: Pacleanup: A script to clean up package bloat

itsbrad212 wrote:

well done sir. You should add an option to skip to the end though

Thank you.

If you mean to skip going through the selection of whether to keep or remove packages, there is an option. Inputting 'd' (for 'Done' tongue ) will skip the rest of the selection process and go right to dependency checking.

Did you mean something else?

Offline

#4 2010-02-18 22:28:59

Arm-the-Homeless
Member
Registered: 2008-12-22
Posts: 273

Re: Pacleanup: A script to clean up package bloat

Ooh. I like that code. It looks nice. I like your style. tongue

And the script is good, been looking for something like this.

Offline

#5 2010-02-18 23:17:50

drsjlazar
Member
From: Kasama
Registered: 2009-10-01
Posts: 133
Website

Re: Pacleanup: A script to clean up package bloat

Why, thank you smile

Offline

#6 2010-02-18 23:43:41

keenerd
Package Maintainer (PM)
Registered: 2007-02-22
Posts: 647
Website

Re: Pacleanup: A script to clean up package bloat

A similar app with a slightly different take on this is pacgraph.  Running "pacgraph -c" produces a list of your installed packages, sorted by size, including unshared dependencies.

Offline

Board footer

Powered by FluxBB