summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar Mike Burns <mike@mike-burns.com>2013-07-10 23:50:11 +0200
committerGravatar Mike Burns <mike@mike-burns.com>2013-07-12 21:53:07 +0200
commit30e09856846e482d1bc805645956d2cfe202e0cc (patch)
treeabe89042ab5df3af14faf1a203dfda81d095bd18
parent75586ddbd84bbce167ae981a674d60743acb857b (diff)
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`.
-rw-r--r--Makefile2
-rw-r--r--README.md4
-rwxr-xr-xbin/lsrc186
-rwxr-xr-xbin/rcup206
-rw-r--r--man/man1/lsrc.150
-rw-r--r--man/man1/mkrc.12
-rw-r--r--man/man1/rcup.12
-rw-r--r--man/man5/rcrc.52
8 files changed, 309 insertions, 145 deletions
diff --git a/Makefile b/Makefile
index f4c2b5c..5a05334 100644
--- a/Makefile
+++ b/Makefile
@@ -7,8 +7,10 @@ install:
install -dm 0755 $(PREFIX)/libexec/rcm
install -m 0755 bin/mkrc $(PREFIX)/bin
install -m 0755 bin/rcup $(PREFIX)/bin
+ install -m 0755 bin/lsrc $(PREFIX)/bin
install -m 0644 man/man1/rcup.1 $(PREFIX)/share/man/man1
install -m 0644 man/man1/mkrc.1 $(PREFIX)/share/man/man1
+ install -m 0644 man/man1/lsrc.1 $(PREFIX)/share/man/man1
install -m 0644 man/man5/rcrc.5 $(PREFIX)/share/man/man5
install -m 0644 libexec/rcm/rcm.sh $(PREFIX)/libexec/rcm
diff --git a/README.md b/README.md
index 5d5e61b..f75f57b 100644
--- a/README.md
+++ b/README.md
@@ -6,7 +6,7 @@ This is a management suite for dotfiles.
It assumes that you have a separate dotfiles directory, or are
interested in creating one.
-The programs provided are `rcup` and `mkrc`.
+The programs provided are `rcup`, `mkrc`, and `lsrc`.
Installation
------------
@@ -27,6 +27,8 @@ Programs
directories.
* `mkrc` is for introducing a dotfile into your dotfiles directory, with
support for tags and multiple source directories.
+* `lsrc` shows you all your dotfiles and where they would be symlinked
+ to. It is used by `rcup` but is provided for your own use, too.
Support
-------
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
diff --git a/bin/rcup b/bin/rcup
index 64626b3..22f699d 100755
--- a/bin/rcup
+++ b/bin/rcup
@@ -5,144 +5,103 @@
REPLACE_ALL=0
DEST_DIR=$HOME
-DEFAULT_DOTFILES_DIR=$HOME/.dotfiles
-HOSTNAME=`hostname -s`
DEBUG=:
PRINT=echo
+PROMPT=echo_n
VERBOSE=:
-PROMPT=echo
MKDIR=mkdir
LN=ln
RM=rm
-pushdir() {
- DIR_STACK="$DIR_STACK:$PWD/$1"
- $DEBUG "cd'ing to $1 from `pwd` with stack $DIR_STACK"
- cd $1
+echo_n() {
+ printf "%s " "$*"
}
-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
+link_file() {
+ local src=$1
+ local dest=$2
- if [ $dotted -eq 1 ]; then
- echo $dest/$file
- else
- echo $dest/.$file
+ $PRINT "linking $dest"
+ if [ -h $dest ]; then
+ rm -f $dest
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"
- $MKDIR -p $dest_path
- pushdir $dir
- for f in *; do
- $DEBUG "handling the file $f"
- handle_file $f $dest_path $3/$1 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 "linking $dest_file"
- if [ -h $dest_file ]; then
- rm -f $dest_file
- fi
- $LN -s $dotfiles_dir/$file $dest_file
+ $LN -s $src $dest
}
replace_file() {
- local file=$1
- local dest_dir=$2
- local dotfiles_dir=$3
- local dotted=$4
- local dest_file=`build_path $dest_dir $file $dotted`
+ local src=$1
+ local dest=$2
+
+ $DEBUG replace_file $1 $2
- $RM -rf $dest_file
- link_file $file $dest_dir $dotfiles_dir $dotted
+ $RM -rf $dest
+ link_file $src $dest
+}
+
+is_nested() {
+ echo $1 | sed "s:$DEST_DIR/::" | grep -q /
+ return $?
}
is_identical() {
diff -q -s $1 $2 > /dev/null
}
+handle_dir() {
+ local dest=$1
+
+ $DEBUG handle_dir $1
+
+ dirname $dest | xargs $MKDIR -p
+}
+
handle_file() {
- local file=$1
- local dest_dir=$2
- local dotfiles_dir=$3
- local dotted=$4
+ local src=$1
+ local dest=$2
- $DEBUG handle_file $1 $2 $3 $4
+ $DEBUG handle_file $1 $2
- 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`
- if [ -e "$dest_file" ]; then
- if is_identical $file $dest_file; then
- $VERBOSE "identical $dest_file"
- elif [ $REPLACE_ALL -eq 1 ]; then
- replace_file $file $dest_dir $dotfiles_dir $dotted
- else
- $PROMPT "overwrite ${dest_file}? [ynaq]"
- read overwrite
- case $overwrite in
- a)
- REPLACE_ALL=1
- replace_file $file $dest_dir $dotfiles_dir $dotted
- ;;
- y) replace_file $file $dest_dir $dotfiles_dir $dotted
- ;;
- q) exit 1
- ;;
- *) $VERBOSE "skipping $dest_file"
- ;;
- esac
- fi
+ if [ -e "$dest" ]; then
+ if is_identical $src $dest; then
+ $VERBOSE "identical $dest"
+ elif [ $REPLACE_ALL -eq 1 ]; then
+ replace_file $src $dest
else
- link_file $file $dest_dir $dotfiles_dir $dotted
+ $PROMPT "overwrite ${dest}? [ynaq]"
+ read overwrite
+ case $overwrite in
+ a) REPLACE_ALL=1
+ replace_file $src $dest
+ ;;
+ y) replace_file $src $dest ;;
+ q) exit 1 ;;
+ *) $VERBOSE "skipping $dest" ;;
+ esac
fi
+ else
+ link_file $src $dest
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=
+ LS_ARGS=
while getopts Vqvt:d: opt; do
case "$opt" in
- t) arg_tags="$arg_tags $OPTARG";;
+ t)
+ arg_tags="$arg_tags $OPTARG"
+ LS_ARGS="$LS_ARGS -t $OPTARG"
+ ;;
v) verbosity=$(($verbosity + 1));;
q) verbosity=$(($verbosity - 1));;
- d) dotfiles_dirs="$dotfiles_dirs $OPTARG";;
+ d)
+ dotfiles_dirs="$dotfiles_dirs $OPTARG"
+ LS_ARGS="$LS_ARGS -d $OPTARG"
+ ;;
V) version=1
esac
done
@@ -178,6 +137,7 @@ handle_command_line() {
fi
FILES=$@
+ LS_ARGS="$LS_ARGS $FILES"
}
if [ -e $HOME/.rcrc ]; then
@@ -187,49 +147,13 @@ 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
+for dest_and_src in `lsrc $LS_ARGS`; do
+ dest=`echo $dest_and_src | sed 's/:.*//'`
+ src=`echo $dest_and_src | sed 's/.*://'`
- 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
+ if is_nested $dest; then
+ handle_dir $dest
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
-
+ handle_file $src $dest
done
diff --git a/man/man1/lsrc.1 b/man/man1/lsrc.1
new file mode 100644
index 0000000..50642a6
--- /dev/null
+++ b/man/man1/lsrc.1
@@ -0,0 +1,50 @@
+.TH lsrc "1" "July 2013" "rcm"
+
+.SH NAME
+lsrc \- show configuration files
+
+.SH SYNOPSIS
+.B lsrc [-v] [-q] [-t \fItag\fR] [-d \fIdir\fR] [\fIfiles...\fR]
+
+.SH DESCRIPTION
+
+This program lists all configuration files, both the sources in the
+dotfiles directories and the destinations in your home directory.
+
+See \fIrcup\fR\|(1), the \fBDIRECTORY LAYOUT\fR section, for details on
+the directory layout.
+
+It supports these options:
+
+.TP
+\fB-v\fR
+increase verbosity. This can be repeated for extra verbosity.
+
+.TP
+\fB-q\fR
+decrease verbosity
+
+.TP
+\fB-t\fR \fITAG\fR
+list dotfiles according to TAG
+
+.TP
+\fB-d\fR \fIDIR\fR
+list dotfiles from the DIR. This can be specified multiple times.
+
+.TP
+\fIfiles...\fR
+only list the specified file(s)
+
+
+.SH AUTHOR
+
+Written by Mike Burns.
+
+.SH FILES
+.I ~/.dotfiles
+.I ~/.rcrc
+
+.SH SEE ALSO
+
+\&\fIrcrc\fR\|(5), \fImkrc\fR\|(1), \fIrcup\fR\|(1)
diff --git a/man/man1/mkrc.1 b/man/man1/mkrc.1
index b241e6b..b8b555f 100644
--- a/man/man1/mkrc.1
+++ b/man/man1/mkrc.1
@@ -42,4 +42,4 @@ Written by Mike Burns.
.SH SEE ALSO
-\&\fIrcrc\fR\|(5), \fIrcup\fR\|(1)
+\&\fIrcrc\fR\|(5), \fIrcup\fR\|(1), \fIlsrc\fR\|(1)
diff --git a/man/man1/rcup.1 b/man/man1/rcup.1
index f68cc87..c24753c 100644
--- a/man/man1/rcup.1
+++ b/man/man1/rcup.1
@@ -67,4 +67,4 @@ Written by Mike Burns.
.SH SEE ALSO
-\&\fIrcrc\fR\|(5), \fImkrc\fR\|(1)
+\&\fIrcrc\fR\|(5), \fImkrc\fR\|(1), \fIlsrc\fR\|(1)
diff --git a/man/man5/rcrc.5 b/man/man5/rcrc.5
index 67dc2a3..6f28e06 100644
--- a/man/man5/rcrc.5
+++ b/man/man5/rcrc.5
@@ -37,4 +37,4 @@ Written by Mike Burns.
.SH SEE ALSO
-\&\fImkrc\fR\|(5), \fIrcup\fR\|(1)
+\&\fImkrc\fR\|(5), \fIrcup\fR\|(1), \fIlsrc\fR\|(1)