#!/usr/bin/env zsh PDIR="$HOME/packages" PKG_ROOT="ssh://derf.homelinux.org/var/packages_root" VCS_CMD="hg" VCS_OPTIONS="--quiet" VCS_ADD="clone" VCS_INCOMING="incoming" VCS_STATUS="status" VCS_UPDATE="pull" VCS_UPDATE_OPTIONS="--update" CL_OPTIONS="-q" info=$'\e[0;36m' error=$'\e[1;31m' reset=$'\e[0m' info () { echo "${info}$*${reset}" } warn () { echo "${error}$*${reset}" } die () { echo "${error}$*${reset}" exit 100 } if [ -f $HOME/.pkg.conf ]; then . $HOME/.pkg.conf fi if [ ! -d $PDIR ]; then die "$PDIR not found!!" fi check_deps () { [ -r $PDIR/$1/.deps ] || return 0 DEPS=($(cat $PDIR/$1/.deps)) INSTALL=() for dep in $DEPS; { if [ "$dep" = "$1" ]; then warn "This package depends on itself. Therefore, I'm considering it borked. Not installing." return 100 fi if [ ! -d $PDIR/$dep ]; then echo -n "$1 depends on $dep. Install dependency? [Y/n] " read if [ ! "$REPLY" = 'n' ]; then INSTALL+="$dep" fi fi } if [ -n "$INSTALL" ]; then for pkg in $INSTALL; { pkg_add "$pkg" } fi } pkg_add () { if [ -d $PDIR/$1 ]; then info "Package '$1' is already installed!" return 100 fi cd $PDIR || return 255 info "Retrieving package $1..." $VCS_CMD $VCS_OPTIONS $VCS_ADD $PKG_ROOT/$1 || return 255 if [ -f $PDIR/$1/hooks/post-add ]; then info 'Executing post-add hook' . $PDIR/$1/hooks/post-add fi check_deps "$1" info 'Checking symlinks...' cd $PDIR/$1 checklinks $CL_OPTIONS return 0 } pkg_remove () { if [ ! -d $PDIR/$1 ]; then info "Package '$1' is not installed!" return 100 fi if [ -f $PDIR/$1/hooks/pre-remove ]; then info 'Executing pre-remove hook' . $PDIR/$1/hooks/pre-remove fi rm -r $PDIR/$1 info "Package removed." } pkg_update () { cd $PDIR/$1 if $VCS_CMD $VCS_OPTIONS $VCS_INCOMING; then info "Updating package $1" $VCS_CMD $VCS_OPTIONS $VCS_UPDATE $VCS_UPDATE_OPTIONS checklinks $CL_OPTIONS if [ -f hooks/post-update ]; then info 'Executing post-update hook' . hooks/post-update fi else info "up-to-date: $1" fi cd $PDIR } pkg_update_wrapper () { if [ -n "$1" ]; then pkg_update "$1" else cd $PDIR for i in *(/); { pkg_update "$i" } fi } pkg_changesrc () { cd $PDIR for i in *(/); { if [ -f $i/.hg/hgrc ]; then sed -ri "s!(default = )[^:]*://.*\$!\1$1/$i!" $i/.hg/hgrc fi } } pkg_list_installed () { =ls -1 $PDIR } pkg_list_available () { if grep "^ssh" <<< "$PKG_ROOT" &> /dev/null; then ssh -q $(sed 's!^ssh://!!' <<< "$PKG_ROOT" | sed -r 's!^([^/]*)/.*$!\1!') 'ls -1 packages' fi } pkg_status () { cd $PDIR/$1 info "Checking $1 status..." check_deps $1 $VCS_CMD $VCS_STATUS } pkg_status_wrapper () { if [ -n "$1" ]; then pkg_status "$1" else cd $PDIR for i in *(/); { pkg_status "$i" } fi } case "$1" in add) pkg_add "$2" ;; changeroot) pkg_changesrc "$2" ;; delete) pkg_remove "$2" ;; install) pkg_add "$2" ;; list) pkg_list_installed ;; list-all) pkg_list_available ;; remove) pkg_remove "$2" ;; status) pkg_status_wrapper "$2" ;; update) pkg_update_wrapper "$2" ;; esac