Shell script to uninstall ports with dependents

April 30, 2009

Before we begin, I seem to be getting a lot of people visiting this post when searching for “uninstall macports”. Read 2.5 Uninstall from the MacPorts Guide you want to uninstall MacPorts itself.

EDIT: steve k wrote in and opened my eyes to:

sudo port uninstall --follow-dependents portname

So use that instead, and read on only if you like bash.

(I have another script that does the inverse—traverses up the dependency chain removing ‘leaf’ nodes—that is, ports with no further dependencies. Maybe I’ll make a new post on that one—after making sure it’s also not already available as some hidden option. :p )

If you use MacPorts, then at some point you’ve probably tried to uninstall a port that had other ports as dependents. (If you’re a developer on OS X and you don’t use MacPorts, then you probably should.)

Even when using a friendly GUI like, say, Porticus, you’re prevented from uninstalling a port with dependents. Of course, you can force uninstall a port but MacPorts themselves warn us that doing so might cause problems later on (when rebuilding the dependents).

So, I used to manually traverse down the dependency tree and uninstall the leaf nodes (ports with no dependents) one by one until I could uninstall the ‘root’ port that I wanted to uninstall in the first place.

If you like doing that, then by all means keep doing so.

If, like me, you’re tired of having to do it by hand, then here’s a short shell script I wrote that can do all that for you.

Note that the script will fail if you have more than one installed version of any port. MacPorts itself will helpfully tell you which ports in the dependency tree have multiple versions installed. Maybe one of these days I’ll get motivated and challenged enough to update this script to handle (and uninstall) multiple versions properly.

I initially thought of writing this in Ruby, but since I used MacPorts to install Ruby itself I realized I very well couldn’t use the same script to uninstall anything up the Ruby dependency chain. Fortunately, I found that simple shell scripting (plus common tools like awk) was more than adequate for the task.

With that out of the way, here’s my deport.sh script:

#!/bin/sh

function deport {
  port="$1"

  if port dependents "$port"|grep "depends on $port"; then
    # depth-first traversal of dependents
    port dependents "$port"|awk ‘/depends on/ {print $1}’|while read dependent; do  
        deport "$dependent"
    done
  fi
  # make sure no more dependents
  if port dependents "$port"|grep "$port has no dependents\!"; then
    echo "port uninstall $port"
    port uninstall "$port"
  fi
}

if [ -z "$1" ]; then
  echo "Usage:"
  echo "  deport.sh <portname>"
else
  deport "$1"
fi

If you find this useful, then you’re welcome! If it doesn’t work for you, please drop me a line. :)g

Advertisements

6 Responses to “Shell script to uninstall ports with dependents”

  1. steve k Says:

    Does your script yield different results than the built-in command:

    sudo port uninstall –follow-dependents your-port-name

    Thanks

  2. Alistair Says:

    You’re right! I never knew about that option until you mentioned it.

    Well, this basically makes my script useful only for academic purposes, doesn’t it? :p

  3. Shareef Says:

    The uninstall flag should actually be –follow-dependents

  4. Shareef Says:

    Apparently two dashes are being converted to a long dash character in the comment text

  5. Alistair Says:

    Thanks. I noticed I also had to use a <span>…<span> trick to have two dashes show up properly in the post.


  6. Giga thanx to Steve K (8 also thanx Alistair as well…


Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: