You are not logged in.

#1 2009-11-01 19:14:11

xduugu
Member
Registered: 2008-10-16
Posts: 292

optdepsmeta: creating metapackages for managing optional dependencies

I have several optional dependencies of miscellaneous packages installed, explicitly because I often clean up orphaned packages, but it is quite hard to keep track of them. For that reason, I decided to write something to address this issue and as long as pacman cannot handle optional dependencies, metapackages are the simplest and cleanest solution in my opinion.

My script generates a PKGBUILD for installed packages having any optional dependency, opens it in your editor of choice and afterwards builds and installs the metapackage.

The PKGBUILD for git's optional dependencies, for example, looks currently like this (of course you can remove any dependency you don't like; therefore the editor step):

pkgname=git-optdepends
pkgver=20110519
pkgrel=1
pkgdesc="Optional dependencies for git"
arch=('any')
license=('WTFPL')
depends=('git'
'tk'                            # gitk and git gui
'perl-libwww'                   # git svn
'perl-term-readkey'             # git svn
'subversion'                    # git svn
'cvsps'                         # git cvsimport 
)

And that's my mentioned script. There is some usage output, so it should not be necessary to explain it here. Just run the script without any argument.

Have fun!

#!/bin/bash

PACMAN=/usr/bin/pacman

## escape sequences
ALL_OFF=$(tput sgr0)
BOLD=$(tput bold)
GREEN=$(tput setaf 2)
RED=$(tput setaf 1)
YELLOW=$(tput setaf 3)

msg() {
    echo >&2 "${BOLD}${GREEN}==> ${ALL_OFF}${BOLD}$@${ALL_OFF}"
}

error() {
    echo >&2 "${BOLD}${RED}==> ERROR: ${ALL_OFF}${BOLD}$@${ALL_OFF}"
    exit 1
}

warn() {
    echo >&2 "${BOLD}${YELLOW}==> WARNING: ${ALL_OFF}${BOLD}$@${ALL_OFF}"
}

usage() {
    echo "Usage: ${0##*/} [package]..."
    echo "           Generate and install optdepends metapackages for the specified packages"
    echo
    echo "       ${0##*/} [-a|--all]"
    echo "           Generate and install optdepends metapackages for all installed packages having optional dependencies"
    echo
    echo "       ${0##*/} [-u|--update]"
    echo "           Regenerate and reinstall all installed optdepends metapackages"
    exit 1
}

# main start

if [[ -z $EDITOR ]]; then
    error "Environment variable EDITOR is not set"
fi
if ! type $EDITOR &>/dev/null; then
    error "The configured editor cannot be found: $EDITOR"
fi
if (( ! $# )); then
    usage
fi

# parse commandline options
CONFIRM_INSTALL=0
case "$1" in
    -a|--all)
        PKGS=($(LC_ALL=C $PACMAN -Qi | grep -P '^(Name\s|Optional Deps\s+:\s+.+:.+)' \
                | grep -B1 "^Optional Deps" | grep "^Name" | sed 's/^.\+:\s\+//'))
        CONFIRM_INSTALL=1 ;;
    -u|--update)
        PKGS=($($PACMAN -Qqs '.-optdepends$' | sed 's/-optdepends$//'))
        CONFIRM_INSTALL=1 ;;
    -*) usage ;;
    *) ;;
esac
(( ! ${#PKGS[@]} )) && PKGS=("$@")

if (( ${#PKGS[@]} > 1 )); then
    CONFIRM_INSTALL=1
fi

TMP_DIR=$(mktemp -d --tmpdir "${0##*/}.XXXXXX")
trap "rm -rf -- $TMP_DIR" EXIT

for pkg in "${PKGS[@]}"; do
    echo
    msg "$pkg"
    if ! $PACMAN -Qq -- $pkg &>/dev/null; then
        warn "$pkg is not installed. Skipping..."
        continue
    fi

    # get optional dependencies
    OLD_IFS=$IFS
    IFS=$'\n'
    opt_deps=($(LC_ALL=C $PACMAN -Qi -- $pkg | sed -nr '/^Optional Deps\s+:/, /^.+\s+:/ { p }' \
                | sed -r '$d; s/^(\s+|[^ ][^:]+:\s*)//'))
    IFS=$OLD_IFS

    if (( ! ${#opt_deps[@]} )); then
        warn "$pkg has no optional dependencies. Skipping..."
        #continue
    fi

    # generate to PKGBUILD
    PKGBUILD="$TMP_DIR/PKGBUILD-$pkg"
    cat > "$PKGBUILD" <<EOF
pkgname=$pkg-optdepends
pkgver=$(date +%Y%m%d)
pkgrel=1
pkgdesc="Optional dependencies for $pkg"
arch=('any')
license=('WTFPL')
depends=('$pkg'
EOF

    # add optional dependencies to depends array
    for dep in "${opt_deps[@]}"; do
        depname=${dep%%:*}
        echo -e "'$depname'$(for ((i=0; i<((30 - ${#depname})); i++)); do echo -n " "; done)#${dep#*:}" >> "$PKGBUILD"
    done

    echo -e "\n)" >> "$PKGBUILD"

    # edit, build and install metapackage
    $EDITOR "$PKGBUILD"
    if (( CONFIRM_INSTALL )); then
        read -en 1 -p "Do you want to install this metapackage? [Y/n] " key

        [[ -z $key ]] && key=y
        case "${key,,}" in
            y) ;;
            n|*) continue ;;
        esac
    fi
    cd "$TMP_DIR"
    export PKGDEST=$TMP_DIR
    makepkg -scfi -p "$PKGBUILD"
done

20110519: fixed optional dependencies detection code

Last edited by xduugu (2011-05-19 20:22:55)

Offline

#2 2009-11-01 23:39:48

Allan
Pacman
From: Brisbane, AU
Registered: 2007-06-09
Posts: 11,503
Website

Re: optdepsmeta: creating metapackages for managing optional dependencies

This is a future plan for pacman: http://wiki.archlinux.org/index.php/Use … OptDepends

Offline

#3 2009-11-01 23:53:42

xduugu
Member
Registered: 2008-10-16
Posts: 292

Re: optdepsmeta: creating metapackages for managing optional dependencies

Right, that's definitely the way to go. This script will be obsolete some day, but it's imo the best option for the time being.

Offline

#4 2011-05-19 20:24:30

xduugu
Member
Registered: 2008-10-16
Posts: 292

Re: optdepsmeta: creating metapackages for managing optional dependencies

Fixed optional dependencies detection code and use some new pacman features.

Offline

Board footer

Powered by FluxBB