#!/bin/bash # Includes . $(miniade) || { echo "${0##*/}: ERROR: miniade failed (hint: run 'miniade' to see error)" >&2; exit 1; } # Configurable stuff DFLT_OPT_DIR=$HOME/opt DFLT_BIN_DIR=$HOME/bin DFLT_LIB_DIR=$HOME/lib DFLT_MAN_DIR=$HOME/man # Other globals main() { local MY_ARGS local UNAMEN PKG_NAMES MODE # Defaults for options OSID_CMD=osid MODE=normal # Process options special_opts_handler() { case $1 in --os) MODE=reportos ;; --edit|-e) MODE=edit ;; --osid-cmd=*) OSID_CMD="${1#*=}" ;; *) return 1 ;; esac } miniade_process_options --help-handler=help --special-opts-handler=special_opts_handler MY_ARGS "$@" && set -- "${MY_ARGS[@]}" # Process arguments [ $# = 0 ] || miniade_bad_usage # Sanity checks and derivations miniade_get_progname PROGNAME RCFILE=$HOME/.$PROGNAME/$(uname -n) OPT_DIR=${MATRIX_OPT_DIR:-$DFLT_OPT_DIR} BIN_DIR=${MATRIX_BIN_DIR:-$DFLT_BIN_DIR} LIB_DIR=${MATRIX_LIB_DIR:-$DFLT_LIB_DIR} MAN_DIR=${MATRIX_MAN_DIR:-$DFLT_MAN_DIR} UNAMEN=$(uname -n | tr '[A-Z]' '[a-z]') OSID=$($OSID_CMD 2>/dev/null) || miniade_error "$OSID_CMD: couldn't execute (hint: maybe you need to use '--osid-cmd=' ?)" # Guts case $MODE in normal) matrix_normal "$@" ;; reportos) matrix_reportos "$@" ;; edit) matrix_edit "$@" ;; esac } help() { local PROGNAME miniade_get_progname PROGNAME echo "Usage: $PROGNAME [ ] [ --osid-cmd= ] { | --os | --edit }" exit 0 } matrix_normal() { local PROGNAME miniade_get_progname PROGNAME # # Get list of all packages available for this OS. # ls -d $OPT_DIR/$OSID/* $OPT_DIR/OSI/* 2> /dev/null | sed 's/.*\///' | sort > /tmp/$PROGNAME.$$.all # # Get list of packages user wants on this machine. # [ -f $RCFILE ] || miniade_error "$RCFILE: no such file" sed -e '/^[ ]*#/d' -e '/^[ ]*$/d' -e 's/[ ].*//' $RCFILE | sort > /tmp/$PROGNAME.$$.des DIFF_OUTPUT=$(diff /tmp/$PROGNAME.$$.des <(sort -u /tmp/$PROGNAME.$$.des) || true) [ "X$DIFF_OUTPUT" = X ] || miniade_error "$RCFILE: contains duplicates!" # # Check for packages which user wants but which are not available. # while read PKG_NAME; do OSS=$(ls -1d $OPT_DIR/*/$PKG_NAME 2>/dev/null | sed 's/.*\/\([^\/]*\)\/[^\/]*$/\1/') APPLICABLE_OSS=0 for OS in $OSS; do [ $OS = $OSID -o $OS = OSI ] && APPLICABLE_OSS=$(expr $APPLICABLE_OSS + 1) done [ $APPLICABLE_OSS = 0 ] && miniade_error "$PKG_NAME: no version applicable to this OS found" done < /tmp/$PROGNAME.$$.des # # Do it all from scratch. Except if we're on Cygwin; # the Start menu creates .lnk files to the programs to # execute, but it cannot create them to the .lnk # symlinks created by *this* program when *it* calls # Cygwin's ln. The only option is to create *unix* # symlinks here, but that cannot be done under Cygwin; # it would have to be manually done. And if it was done # manually on a previous occassion then we do not want # to wipe those links out by now removing the host-specific # bin directory! # if expr "$OSID" : 'CYGWIN.*' > /dev/null; then miniade_warning "not wiping old directories 'cos of OS limitations in creating symlinks" else miniade_evaler "rm -fr $BIN_DIR/$UNAMEN" miniade_evaler "rm -fr $LIB_DIR/$UNAMEN" miniade_evaler "rm -fr $MAN_DIR/$UNAMEN" fi # -p needed to prevent error on Cygwin where the directory may # already exist 'cos (if it did exist) it wasn't wiped out above. miniade_evaler "mkdir -p $BIN_DIR/$UNAMEN" miniade_evaler "mkdir -p $LIB_DIR/$UNAMEN" miniade_evaler "mkdir -p $MAN_DIR/$UNAMEN/man{1,2,3,4,5,6,7,8}" # # Symlink all the commands, man pages libraries in. # while read PKG_NAME; do OSS=$(ls -1d $OPT_DIR/*/$PKG_NAME | sed 's/.*\/\([^\/]*\)\/[^\/]*$/\1/') for OS in $OSS; do # Ignore versions of package for inappropriate OSs [ "$OS" = OSI -o "$OS" = "$OSID" ] || continue miniade_info "processing $PKG_NAME ..." PKG_SUBDIR=bin miniade_debug 10 "main: processing $PKG_NAME (PKG_SUBDIR=$PKG_SUBDIR) ..." GLOBBER='*' TEST_CMD="test -x" LEAVE_GLOBBED_DIR="" USERTREE_SUBDIR=$BIN_DIR WARNING_TEXT="no commands" if [ -d $OPT_DIR/$OS/$PKG_NAME/$PKG_SUBDIR ]; then ( cd $OPT_DIR/$OS/$PKG_NAME/$PKG_SUBDIR && eval ls -d $GLOBBER ) | while read CMD; do miniade_evaler "cd $USERTREE_SUBDIR/$UNAMEN" SYMLINK_TARGET=$(realpath --no-symlinks --relative-to=$USERTREE_SUBDIR/$UNAMEN $OPT_DIR/$OS/$PKG_NAME/$PKG_SUBDIR/$CMD) # Make sure the thing is valid before symlinking it eval "$TEST_CMD $SYMLINK_TARGET" || { miniade_warning "$CMD: failed test; skipping (hint '$TEST_CMD $SYMLINK_TARGET' failed)"; continue; } # test is only for Cygwin which may have left # Unix symlinks which it cannot recreate. [ ! -f $CMD ] || { miniade_warning "$CMD: leaving, as it may be a windows shortcut ($OPT_DIR/$OS/$PKG_NAME/$PKG_SUBDIR exists; GLOBBER=$GLOBBER; CMD=$CMD; that CMD is not a file)"; continue; } miniade_evaler "ln -s $SYMLINK_TARGET $CMD" done else miniade_warning "$PKG_NAME: $WARNING_TEXT" fi PKG_SUBDIR=lib miniade_debug 10 "main: processing $PKG_NAME (PKG_SUBDIR=$PKG_SUBDIR) ..." GLOBBER='*' TEST_CMD="test -d" LEAVE_GLOBBED_DIR="" USERTREE_SUBDIR=$LIB_DIR WARNING_TEXT="no libraries" if [ -d $OPT_DIR/$OS/$PKG_NAME/$PKG_SUBDIR ]; then miniade_evaler "cd $USERTREE_SUBDIR/$UNAMEN" SYMLINK_TARGET=$(realpath --no-symlinks --relative-to=$USERTREE_SUBDIR/$UNAMEN $OPT_DIR/$OS/$PKG_NAME/$PKG_SUBDIR) miniade_evaler "ln -s $SYMLINK_TARGET $PKG_NAME" else : miniade_warning "$PKG_NAME: $WARNING_TEXT" fi PKG_SUBDIR=man miniade_debug 10 "main: processing $PKG_NAME (PKG_SUBDIR=$PKG_SUBDIR) ..." GLOBBER='*/*' TEST_CMD="sh -c 'expr \"\$1\" : \".*/man[1-8]/[-a-z0-9_]*\.[0-9]\$\" >/dev/null || expr \"\$1\" : \".*/man3/[-a-zA-Z0-9_:]*\.3pm\$\" >/dev/null' DUMMY" LEAVE_GLOBBED_DIR="../" USERTREE_SUBDIR=$MAN_DIR WARNING_TEXT="no man pages" if [ -d $OPT_DIR/$OS/$PKG_NAME/$PKG_SUBDIR ]; then ( cd $OPT_DIR/$OS/$PKG_NAME/$PKG_SUBDIR && ls -d $GLOBBER ) | while read CMD; do miniade_debug 10 "main: \"ls $GLOBBER\" evaluated, this look got: $CMD" miniade_evaler "cd $USERTREE_SUBDIR/$UNAMEN" SYMLINK_TARGET=$(realpath --no-symlinks --relative-to=$USERTREE_SUBDIR/$UNAMEN $OPT_DIR/$OS/$PKG_NAME/$PKG_SUBDIR)/$CMD # Make sure the thing is valid before symlinking it miniade_debug 10 "main: running test command: $TEST_CMD $SYMLINK_TARGET ..." eval "$TEST_CMD $SYMLINK_TARGET" || { miniade_warning "$CMD: failed test; skipping (hint '$TEST_CMD $SYMLINK_TARGET' failed)"; continue; } # test is only for Cygwin which may have left # Unix symlinks which it cannot recreate. [ ! -f $CMD ] || { miniade_warning "$CMD: leaving, as it may be a windows shortcut"; continue; } miniade_evaler "ln -s $SYMLINK_TARGET $CMD" done # Mon Nov 20 09:56:21 CET 2006 - Alexis Huxley # Previously we had emitted a warning if man pages were # not present but this just happens for too much stuff. #else # miniade_warning "$PKG_NAME: $WARNING_TEXT" fi done done < /tmp/$PROGNAME.$$.des rm -f /tmp/$PROGNAME.$$.des /tmp/$PROGNAME.$$.all } matrix_reportos() { echo "$OSID" } matrix_edit() { ${EDITOR:-vi} $RCFILE matrix_normal } main "$@"