From 63b50643b0ffd287d0070e494625056a05081ce8 Mon Sep 17 00:00:00 2001 From: Mike Burns Date: Sun, 4 Aug 2013 10:35:14 -0400 Subject: Introduce exclusion patterns The lsrc(1), rcup(1), and rcdn(1) commands now take any number of `-e` flags, used to specify an exclusion pattern. This can also be controlled via rcrc(5), the `EXCLUDES` variable. An exclusion pattern specifies a file glob to skip. In the case of lsrc(1), any file matching the glob is not listed; in rcup(1) it is not symlinked; and in rcdn(1) it is not removed. The file glob can be preceded by the name of a dotfiles directory (separated from the file glob by a colon) to increase the specificity. Useful for: rcdn -e rcrc rcup -d work-dotfiles -e bashrc rcup -d ~/.dotfiles -d wife-dotfiles -d sys-dotfiles -e wife-dotfiles:tigrc --- bin/Makefile.in | 4 +-- bin/lsrc | 86 +++++++++++++++++++++++++++++++++++++++++++++++---------- bin/rcdn | 7 ++++- bin/rcup | 7 ++++- 4 files changed, 85 insertions(+), 19 deletions(-) (limited to 'bin') diff --git a/bin/Makefile.in b/bin/Makefile.in index cdf3377..42d9875 100644 --- a/bin/Makefile.in +++ b/bin/Makefile.in @@ -180,9 +180,9 @@ $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) exit 1;; \ esac; \ done; \ - echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign bin/Makefile'; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu bin/Makefile'; \ $(am__cd) $(top_srcdir) && \ - $(AUTOMAKE) --foreign bin/Makefile + $(AUTOMAKE) --gnu bin/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ diff --git a/bin/lsrc b/bin/lsrc index a7eca40..6267f03 100755 --- a/bin/lsrc +++ b/bin/lsrc @@ -34,13 +34,16 @@ link_dir() { local dest_dir=$2 local dotfiles_dir=$3 local dotted=$4 + local exclude_file_globs="$5" local dest_path=`build_path $dest_dir $dir $dotted` + $DEBUG "link_dir $1 $2 $3 $4 $5" + $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 + handle_file $f $dest_path $dotfiles_dir/$dir 1 "$exclude_file_globs" done popdir } @@ -64,21 +67,68 @@ handle_file() { local dest_dir=$2 local dotfiles_dir=$3 local dotted=$4 + local exclude_file_globs="$5" - $DEBUG handle_file $1 $2 $3 $4 + $DEBUG "handle_file $1 $2 $3 $4 $5" if [ ! -e $file ]; then $VERBOSE "skipping non-existent file $file" + elif is_excluded $file "$exclude_file_globs"; then + $VERBOSE "skipping excluded file $file" elif [ -d $file ]; then - link_dir $file $dest_dir $dotfiles_dir $dotted + link_dir $file $dest_dir $dotfiles_dir $dotted "$exclude_file_globs" 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-' ] +is_metafile() { + host_portion=`echo $1 | sed -e 's/host-.*/host-/'` + tag_portion=`echo $1 | sed -e 's/tag-.*/tag-/'` + + [ x$host_portion = 'xhost-' -o x$tag_portion = 'xtag-' ] +} + +dotfiles_dir_excludes() { + local dotfiles_dir=$1 + + $DEBUG "dotfiles_dir_excludes $dotfiles_dir" + $DEBUG " with EXCLUDES: $EXCLUDES" + + for exclude in $EXCLUDES; do + if echo $exclude | grep -q :; then + dotfiles_dir_pat=`echo $exclude | sed 's/:.*//'` + file_glob=`echo $exclude | sed 's/.*://'` + + if [ "x$dotfiles_dir_pat" != "x*" ] && is_relative $dotfiles_dir_pat; then + dotfiles_dir_pat=$PWD/$dotfiles_dir_pat + fi + + if [ "x$dotfiles_dir_pat" = "x*" -o "x$dotfiles_dir_pat" = "x$dotfiles_dir" ]; then + echo $file_glob + fi + else + echo $exclude + fi + done +} + +is_excluded() { + local file=$1 + local exclude_file_globs="$2" + + $DEBUG "is_excluded $file $exclude_file_globs" + + for file_glob in $exclude_file_globs; do + $DEBUG "file_glob: $file_glob" + $DEBUG "file: $file" + + case $file in + $file_glob) return 0;; + esac + done + + return 1 } handle_command_line() { @@ -86,9 +136,11 @@ handle_command_line() { local verbosity=0 local version=0 local dotfiles_dirs= + local excludes= - while getopts Vqvt:d: opt; do + while getopts Vqve:t:d: opt; do case "$opt" in + e) excludes="$excludes $OPTARG";; t) arg_tags="$arg_tags $OPTARG";; v) verbosity=$(($verbosity + 1));; q) verbosity=$(($verbosity - 1));; @@ -101,6 +153,7 @@ handle_command_line() { handle_common_flags lsrc $version $verbosity TAGS=${arg_tags:-$TAGS} DOTFILES_DIRS=${dotfiles_dirs:-$DOTFILES_DIRS} + EXCLUDES=${excludes:-$EXCLUDES} FILES=$@ $DEBUG "TAGS: $TAGS" @@ -119,8 +172,7 @@ handle_command_line $* $DEBUG "DOTFILES_DIRS: $DOTFILES_DIRS" for DOTFILES_DIR in $DOTFILES_DIRS; do - - if echo $DOTFILES_DIR | grep -vq '^/'; then + if is_relative $DOTFILES_DIR; then DOTFILES_DIR=$PWD/$DOTFILES_DIR fi @@ -129,15 +181,18 @@ for DOTFILES_DIR in $DOTFILES_DIRS; do continue fi + exclude_file_globs=`dotfiles_dir_excludes $DOTFILES_DIR` + $DEBUG "exclude_file_globs: $exclude_file_globs" + 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 + if is_metafile $file; then + continue fi + + handle_file $file $DEST_DIR $DOTFILES_DIR 0 "$exclude_file_globs" done cd $DOTFILES_DIR @@ -146,7 +201,7 @@ for DOTFILES_DIR in $DOTFILES_DIRS; do if [ -d $host_files ]; then pushdir `basename $host_files` for file in ${FILES:-*}; do - handle_file $file $DEST_DIR $host_files 0 + handle_file $file $DEST_DIR $host_files 0 "$exclude_file_globs" done popdir fi @@ -157,7 +212,8 @@ for DOTFILES_DIR in $DOTFILES_DIRS; 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 + $DEBUG "TAG: $tag, exclude_file_globs: $exclude_file_globs" + handle_file $file $DEST_DIR $DOTFILES_DIR/tag-$tag 0 "$exclude_file_globs" done popdir fi diff --git a/bin/rcdn b/bin/rcdn index 8695c63..66e064f 100755 --- a/bin/rcdn +++ b/bin/rcdn @@ -9,9 +9,11 @@ handle_command_line() { local version=0 local dotfiles_dirs= local files= + local excludes= - while getopts Vqvt:d: opt; do + while getopts Vqve:t:d: opt; do case "$opt" in + e) excludes="$excludes $OPTARG";; t) arg_tags="$arg_tags $OPTARG" ;; v) verbosity=$(($verbosity + 1));; q) verbosity=$(($verbosity - 1));; @@ -33,6 +35,9 @@ handle_command_line() { for dotfiles_dir in $dotfiles_dirs; do LS_ARGS="$LS_ARGS -d $dotfiles_dir" done + for exclude in $excludes; do + LS_ARGS="$LS_ARGS -e $exclude" + done LS_ARGS="$LS_ARGS $files" $DEBUG "LS_ARGS: $LS_ARGS" diff --git a/bin/rcup b/bin/rcup index 3aa5fa6..7c1cf16 100755 --- a/bin/rcup +++ b/bin/rcup @@ -76,11 +76,13 @@ handle_command_line() { local version=0 local dotfiles_dirs= local files= + local excludes= REPLACE_ALL=0 - while getopts Vqvfit:d: opt; do + while getopts Vqvfie:t:d: opt; do case "$opt" in + e) excludes="$excludes $OPTARG";; f) REPLACE_ALL=1 ;; i) REPLACE_ALL=0 ;; t) arg_tags="$arg_tags $OPTARG" ;; @@ -104,6 +106,9 @@ handle_command_line() { for dotfiles_dir in $dotfiles_dirs; do LS_ARGS="$LS_ARGS -d $dotfiles_dir" done + for exclude in $excludes; do + LS_ARGS="$LS_ARGS -e $exclude" + done LS_ARGS="$LS_ARGS $files" $DEBUG "LS_ARGS: $LS_ARGS" -- cgit v1.2.3