123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247 |
- #! /bin/bash
- # Install files in current directory to $HOME in various ways.
- #
- # By default, create a directory in $HOME with the same name
- # as the current directory, then symlink all files in this
- # directory into the target directory
- #
- # Default directories are:
- # base directory - $HOME
- # target directory - $HOME/`basename $PWD`
- # source directory - $PWD
- ##
- # Usage: ${PROG} [options]
- #
- # options
- #
- # Modify the paths used
- #
- # -p|--path=PATH use PATH as base directory (defalt $HOME)
- # -t|--tobase link/copy files directly to base directory
- #
- # Modify the copy/link behavior
- #
- # -l|--linkdir symlink this directory itself to base directory
- # -c|--copy copy directory to target directory#
- # -r|--remove remove old files
- #
- # Change debugging and output
- #
- # -d|--debug debug output
- # -v|--verbose verbose output
- #
- # - create a directory in $HOME with the same name as this directory
- # - link all files in this directory in the new directory
- # - exclude files listed in .link2home.ignore
- set -e -u
- # Helper functions
- PROG=`basename "$0" | tr -d '\n'`
- function info() { echo ${PROG}\: info: "$@" 1>&2; }
- function warn() { echo ${PROG}\: warning: "$@" 1>&2; }
- function error() { echo ${PROG}\: error: "$@" 1>&2; }
- function debug() { [[ -v DEBUG ]] && echo ${PROG}\: debug: "$@" 1>&2 || true ; }
- function die() { echo ${PROG}\: fatal: "$@" 1>&2 && exit 1; }
- #
- # Command line parsing
- #
- function usage() {
- debug "in ${FUNCNAME[0]}"
- if [[ "$#" -gt 0 ]]; then
- warn $@
- fi
- cat <<END 1>&2
- Usage: ${PROG} [options]
- options
- -c|--copy copy directory to target directory
- -l|--linkdir symlink this directory itself to base directory
- -p|--path=PATH use PATH as base directory (defalt $HOME)
- -r|--remove remove old files
- -t|--tobase link files directly to base directory
- -d|--debug debug output
- -v|--verbose verbose output
- END
- exit 1
- }
- # globals variables
- declare -A EXCLUSIONS
- # parse global options
- for i in "$@"
- do
- case $i in
- -d|--debug)
- DEBUG=1
- d_flag="-d"
- shift # past argument with no value
- ;;
- -c|--copy)
- COPYDIR=1
- d_flag="-d"
- shift # past argument with no value
- ;;
- -l|--linkdir)
- LINKDIR=1
- d_flag="-d"
- shift # past argument with no value
- ;;
- -p=*|--PATH=*)
- TOPATH=1
- TO_PATH="${i#*=}"
- p_flag="-d"
- shift # past argument=value
- ;;
- -r|--remove)
- REMOVE=1
- # remove old files
- shift # past argument with no value
- ;;
- -t|--tobase)
- TOBASE=1
- d_flag="-d"
- shift # past argument with no value
- ;;
- -v|--verbose)
- VERBOSE=1
- v_flag="-v"
- shift # past argument with no value
- ;;
- -*|--*)
- usage "Unknown state option: $i"
- ;;
- esac
- done
- # Pull off command line args
- if [ "$#" -ge 1 ]; then
- usage "No arguments expected"
- fi
- # Get abolute path to directory of current file
- #REALDIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
- # use current directory
- WHERE_AM_I=`pwd`
- # Extract the directory name of this file
- CURRENT_BASEDIR=`basename $WHERE_AM_I`
- # Determine which directory to use as "HOME"
- BASEDIR="${HOME}"
- if [[ -v TOPATH ]]; then
- BASEDIR="${TO_PATH}"
- fi
- # Determine final destinaiton dir
- if [[ -v TOBASE ]]; then
- FINAL_DIR="${BASEDIR}"
- else
- FINAL_DIR="${BASEDIR}/${CURRENT_BASEDIR}"
- fi
- # if copying, just do it and stop
- if [[ -v COPYDIR ]]; then
- [[ -v DEBUG ]] && echo cp -r -p ${WHERE_AM_I} ${FINAL_DIR}
- cp -r -p ${WHERE_AM_I} ${FINAL_DIR}
- exit 0
- fi
- # Link this directory into FINAL_DIR
- if [[ -v LINKDIR ]]; then
- if [ -v REMOVE ]; then
- # never remove HOME !!!
- if [[ "${HOME}" == "${FINAL_DIR}" ]]; then
- [[ -v VERBOSE ]] && info not removing "${HOME}"
- else
- rm -f "${FINAL_DIR}"
- [[ -v VERBOSE ]] && info rm -f "${FINAL_DIR}"
- fi
- fi
- [[ -v VERBOSE ]] && info ln -s "${WHERE_AM_I}" "${FINAL_DIR}"
- ln -s "${WHERE_AM_I}" "${FINAL_DIR}" || warn "Unable to link ${WHERE_AM_I}"
- exit 0
- else
- # crate the directory name in $HOME if DNE
- mkdir -p "${FINAL_DIR}"
- fi
- #
- # Everything from here is releative to source directory
- #
- cd "${WHERE_AM_I}"
- #
- # Ignore files listed in .link2home.ignore
- #
- if [ -f '.link2home.ignore' ]; then
- for exclude in `cat .link2home.ignore`; do
- EXCLUSIONS["${exclude}"]="${exclude}"
- done
- fi
- #
- # symlink everything here to $HOME
- #
- debug linking files
- #for file in * .[a-z]*; do
- for file in * .[a-z0-9A-Z_\-]*; do
- SOURCE="${WHERE_AM_I}/${file}"
- TARGET="${FINAL_DIR}/${file}"
- [ -e "${file}" ] || continue
- if [ ${EXCLUSIONS["${file}"]+DNE} ]; then
- info skiping "${file}"
- else
- if [ -v REMOVE ]; then
- [[ -v VERBOSE ]] && info rm -f "${FINAL_DIR}/${file}"
- rm -f "${FINAL_DIR}/${file}"
- fi
- if [ -h "${TARGET}" ]; then
- [[ -v VERBOSE ]] && info "${TARGET}" already exists. Skipping.
- else
- [[ -v VERBOSE ]] && info ln -s "${SOURCE}" "${FINAL_DIR}"
- ln -s "${SOURCE}" "${FINAL_DIR}" || warn "Unable to link ${SOURCE}"
- fi
- fi
- done
|