summaryrefslogtreecommitdiff
path: root/bin/lsrc
diff options
context:
space:
mode:
Diffstat (limited to 'bin/lsrc')
-rwxr-xr-xbin/lsrc186
1 files changed, 186 insertions, 0 deletions
diff --git a/bin/lsrc b/bin/lsrc
new file mode 100755
index 0000000..2a1a9e0
--- /dev/null
+++ b/bin/lsrc
@@ -0,0 +1,186 @@
+#!/bin/sh
+
+#set -x
+
+DEST_DIR=$HOME
+DEFAULT_DOTFILES_DIR=$HOME/.dotfiles
+HOSTNAME=`hostname -s`
+DEBUG=:
+PRINT=echo
+VERBOSE=:
+
+pushdir() {
+ DIR_STACK="$DIR_STACK:$PWD/$1"
+ $DEBUG "cd'ing to $1 from `pwd` with stack $DIR_STACK"
+ cd $1
+}
+
+popdir() {
+ current=`echo $DIR_STACK | sed -e 's/.*://g'`
+ prior=`echo $DIR_STACK | sed -e "s|:$current$||" | sed -e 's/.*://g'`
+ DIR_STACK=`echo $DIR_STACK | sed -e 's/:[^:]*$//'`
+ $DEBUG "cd'ing to $prior from `pwd` with stack $DIR_STACK"
+ cd $prior
+}
+
+build_path() {
+ local dest=$1
+ local file=$2
+ local dotted=$3
+
+ if [ $dotted -eq 1 ]; then
+ echo $dest/$file
+ else
+ echo $dest/.$file
+ fi
+}
+
+link_dir() {
+ local dir=$1
+ local dest_dir=$2
+ local dotfiles_dir=$3
+ local dotted=$4
+ local dest_path=`build_path $dest_dir $dir $dotted`
+
+ $VERBOSE "recurring on $dest_path"
+ pushdir $dir
+ for f in *; do
+ $DEBUG "handling the file $f"
+ handle_file $f $dest_path $dotfiles_dir/$dir 1
+ done
+ popdir
+}
+
+link_file() {
+ local file=$1
+ local dest_dir=$2
+ local dotfiles_dir=$3
+ local dotted=$4
+ local dest_file=`build_path $dest_dir $file $dotted`
+
+ $PRINT $dest_file:$dotfiles_dir/$file
+}
+
+handle_file() {
+ local file=$1
+ local dest_dir=$2
+ local dotfiles_dir=$3
+ local dotted=$4
+
+ $DEBUG handle_file $1 $2 $3 $4
+
+ if [ ! -e $file ]; then
+ $VERBOSE "skipping non-existent file $file"
+ elif [ -d $file ]; then
+ link_dir $file $dest_dir $dotfiles_dir $dotted
+ else
+ dest_file=`build_path $dest_dir $file $dotted`
+ link_file $file $dest_dir $dotfiles_dir $dotted
+ fi
+}
+
+metafile() {
+ [ x$2 = 'xhost-' -o x$3 = 'xtag-' -o x$1 = "xRakefile" -o x$1 = "xinstall" ]
+}
+
+handle_command_line() {
+ arg_tags=""
+ verbosity=0
+ version=0
+ dotfiles_dirs=
+ while getopts Vqvt:d: opt; do
+ case "$opt" in
+ t) arg_tags="$arg_tags $OPTARG";;
+ v) verbosity=$(($verbosity + 1));;
+ q) verbosity=$(($verbosity - 1));;
+ d) dotfiles_dirs="$dotfiles_dirs $OPTARG";;
+ V) version=1
+ esac
+ done
+ shift $(($OPTIND-1))
+
+ if [ $version -eq 1 ]; then
+ version rcup
+ exit 0
+ elif [ $verbosity -ge 2 ]; then
+ DEBUG=echo
+ VERBOSE=echo
+ PRINT=echo
+ elif [ $verbosity -eq 1 ]; then
+ DEBUG=:
+ VERBOSE=echo
+ PRINT=echo
+ elif [ $verbosity -eq 0 ]; then
+ DEBUG=:
+ VERBOSE=:
+ PRINT=echo
+ else
+ DEBUG=:
+ VERBOSE=:
+ PRINT=:
+ fi
+
+ if [ "x$arg_tags" != "x" ]; then
+ TAGS=$arg_tags
+ fi
+
+ if [ "x$dotfiles_dirs" != "x" ]; then
+ DOTFILES_DIRS=$dotfiles_dirs
+ fi
+
+ FILES=$@
+}
+
+if [ -e $HOME/.rcrc ]; then
+ . $HOME/.rcrc
+fi
+
+. `dirname $0`/../libexec/rcm/rcm.sh
+handle_command_line $*
+
+if [ "x$DOTFILES_DIRS" = "x" ]; then
+ DOTFILES_DIRS="$DOTFILES_DIRS $DEFAULT_DOTFILES_DIR"
+fi
+
+for DOTFILES_DIR in $DOTFILES_DIRS; do
+
+ if [ ! -d $DOTFILES_DIR ]; then
+ $VERBOSE "skipping non-existent directory: $DOTFILES_DIR"
+ continue
+ fi
+
+ cd $DOTFILES_DIR
+ DIR_STACK=":$DOTFILES_DIR"
+
+ for file in ${FILES:-*}; do
+ host_portion=`echo $file | sed -e 's/host-.*/host-/'`
+ tag_portion=`echo $file | sed -e 's/tag-.*/tag-/'`
+ if ! metafile $file $host_portion $tag_portion; then
+ handle_file $file $DEST_DIR $DOTFILES_DIR 0
+ fi
+ done
+
+ cd $DOTFILES_DIR
+
+ host_files=$DOTFILES_DIR/host-$HOSTNAME
+ if [ -d $host_files ]; then
+ pushdir `basename $host_files`
+ for file in ${FILES:-*}; do
+ handle_file $file $DEST_DIR $host_files 0
+ done
+ popdir
+ fi
+
+ cd $DOTFILES_DIR
+
+ for tag in $TAGS; do
+ if [ -d tag-$tag ]; then
+ pushdir `basename tag-$tag`
+ for file in ${FILES:-*}; do
+ handle_file $file $DEST_DIR $DOTFILES_DIR/tag-$tag 0
+ done
+ popdir
+ fi
+ done
+
+done