From 30e09856846e482d1bc805645956d2cfe202e0cc Mon Sep 17 00:00:00 2001 From: Mike Burns Date: Wed, 10 Jul 2013 23:50:11 +0200 Subject: Add lsrc The `lsrc` command works just like the `rcup` command but instead of making symlinks and directories, it just lists all the files that would be symlinks. It prints the destination (e.g. `~/.foo`) and the source (`~/.dotfiles/foo`), separated by a colon. Re-write `rcup` in terms of `lsrc`. --- bin/lsrc | 186 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 186 insertions(+) create mode 100755 bin/lsrc (limited to 'bin/lsrc') 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 -- cgit v1.2.3