From 3700be9ce6802653df30c413179d93316bf0b291 Mon Sep 17 00:00:00 2001 From: Pablo Olmos de Aguilera Corradini and Mike Burns Date: Sun, 27 Oct 2013 17:16:30 -0300 Subject: Force some directories to be symlinks Typically a directory structure is copied instead of symlinked, while files are symlinked. However, some cases require symlinked dirs: git submodules, vim plugins, and so on. This introduces a `SYMLINK_DIRS` option for rcrc(5) that takes a space-separated list of "exclude patterns". Any directory matching these patterns is symlinked. This also introduces a `-S` argument for lsrc(1), rcup(1), and rcdn(1). This argument takes a pattern, for one-off directory symlinking. It can be repeated. This also introduces `-S` and `-s` for mkrc(1). `-S` will re-install the files as symlinks, and `-s` will not. This does work with `-C`, though perhaps unintuitively - we don't know what the user means in this case. However, it will not crash. Bug: `-s` does not work right if `SYMLINK_DIRS` is set. Bug #36 addresses this. --- bin/lsrc | 30 ++++++++++++++++++++++-------- bin/mkrc | 14 ++++++++++++-- bin/rcdn | 7 ++++++- bin/rcup | 7 ++++++- 4 files changed, 46 insertions(+), 12 deletions(-) (limited to 'bin') diff --git a/bin/lsrc b/bin/lsrc index 3496a17..d8a36b5 100755 --- a/bin/lsrc +++ b/bin/lsrc @@ -53,16 +53,18 @@ show_dir() { local dotted=$5 local exclude_file_globs="$6" local include_file_globs="$7" + local symlink_dirs_file_globs="$8" local dest_path=`build_path $dest_dir $dir $dotted` - $DEBUG "show_dir $1 $2 $3 $4 $5 $6 $7" + $DEBUG "show_dir $1 $2 $3 $4 $5 $6 $7 $8" $VERBOSE "recurring on $dest_path" + pushdir $dir for f in *; do $DEBUG "handling the file $f" next_dir=`file_join $dotfiles_subdir $dir` - handle_file $f $dest_path $dotfiles_dir $next_dir 1 "$exclude_file_globs" "$include_file_globs" + handle_file $f $dest_path $dotfiles_dir $next_dir 1 "$exclude_file_globs" "$include_file_globs" "$symlink_dirs_file_globs" done popdir } @@ -96,6 +98,7 @@ show_file() { local dotfiles_dir=$3 local dotfiles_subdir=$4 local dotted=$5 + local symlink_dirs_file_globs=$6 local dest_file=`build_path $dest_dir $file $dotted` if echo $DEST_STACK | grep -vq ":$dest_file"; then @@ -122,15 +125,18 @@ handle_file() { local dotted=$5 local exclude_file_globs="$6" local include_file_globs="$7" + local symlink_dirs_file_globs="$8" - $DEBUG "handle_file $1 $2 $3 $4 $5 $6 $7" + $DEBUG "handle_file $1 $2 $3 $4 $5 $6 $7 $8" if [ ! -e $file ]; then $VERBOSE "skipping non-existent file $file" elif is_excluded $file "$exclude_file_globs" "$include_file_globs"; then $VERBOSE "skipping excluded file $file" + elif [ -d $file ] && is_excluded $file "$symlink_dirs_file_globs"; then + show_file $file $dest_dir $dotfiles_dir $dotfiles_subdir $dotted "$symlink_dirs_file_globs" elif [ -d $file ]; then - show_dir $file $dest_dir $dotfiles_dir $dotfiles_subdir $dotted "$exclude_file_globs" "$include_file_globs" + show_dir $file $dest_dir $dotfiles_dir $dotfiles_subdir $dotted "$exclude_file_globs" "$include_file_globs" "$symlink_dirs_file_globs" else show_file $file $dest_dir $dotfiles_dir $dotfiles_subdir $dotted fi @@ -198,7 +204,7 @@ is_excluded() { show_help() { local exit_code=${1:-0} - $PRINT "Usage: lsrc [-FVqvh] [-I EXCL_PAT] [-x EXCL_PAT] [-t TAG] [-d DOT_DIR]" + $PRINT "Usage: lsrc [-FVqvh] [-I EXCL_PAT] [-x EXCL_PAT] [-N EXCL_PAT ] [-t TAG] [-d DOT_DIR]" $PRINT "see lsrc(1) and rcm(5) for more details" exit $exit_code @@ -212,8 +218,9 @@ handle_command_line() { local dotfiles_dirs= local excludes= local includes= + local symlink_dirs= - while getopts FVqvhI:x:t:d: opt; do + while getopts FVqvhI:x:S:t:d: opt; do case "$opt" in F) show_sigils=1;; h) show_help ;; @@ -224,6 +231,7 @@ handle_command_line() { d) dotfiles_dirs="$dotfiles_dirs $OPTARG";; V) version=1;; x) excludes="$excludes $OPTARG";; + S) symlink_dirs="$symlink_dirs $OPTARG";; esac done shift $(($OPTIND-1)) @@ -234,6 +242,7 @@ handle_command_line() { DOTFILES_DIRS=${dotfiles_dirs:-$DOTFILES_DIRS} EXCLUDES=${excludes:-$EXCLUDES} INCLUDES=${includes:-$INCLUDES} + SYMLINK_DIRS=${symlink_dirs:-$SYMLINK_DIRS} FILES=$@ $DEBUG "TAGS: $TAGS" @@ -250,19 +259,24 @@ $DEBUG "DOTFILES_DIRS: $DOTFILES_DIRS" : ${COPY_ALWAYS:=""} $DEBUG "COPY_ALWAYS: $COPY_ALWAYS" +: ${SYMLINK_DIRS:=""} +$DEBUG "SYMLINK_DIRS: $SYMLINK_DIRS" + for DOTFILES_DIR in $DOTFILES_DIRS; do if is_relative $DOTFILES_DIR; then DOTFILES_DIR=$PWD/$DOTFILES_DIR fi if [ ! -d $DOTFILES_DIR ]; then - $VERBOSE "skipping non-existent directory: $DOTFILES_DIR" + $VERBOSE "skipping non-existent directory: $DOTFILES_DIR" continue fi exclude_file_globs=`dotfiles_dir_excludes $DOTFILES_DIR "$EXCLUDES"` $DEBUG "exclude_file_globs: $exclude_file_globs" include_file_globs=`dotfiles_dir_excludes $DOTFILES_DIR "$INCLUDES"` + symlink_dirs_file_globs=`dotfiles_dir_excludes $DOTFILES_DIR "$SYMLINK_DIRS"` + $DEBUG "symlink_dirs_file_globs: $symlink_dirs_file_globs" cd $DOTFILES_DIR DIR_STACK=":$DOTFILES_DIR" @@ -272,7 +286,7 @@ for DOTFILES_DIR in $DOTFILES_DIRS; do continue fi - handle_file $file $DEST_DIR $DOTFILES_DIR . 0 "$exclude_file_globs" "$include_file_globs" + handle_file $file $DEST_DIR $DOTFILES_DIR . 0 "$exclude_file_globs" "$include_file_globs" "$symlink_dirs_file_globs" done cd $DOTFILES_DIR diff --git a/bin/mkrc b/bin/mkrc index c78d10b..f44cadb 100755 --- a/bin/mkrc +++ b/bin/mkrc @@ -40,8 +40,9 @@ verbosity=0 in_host=0 version=0 always_copy=0 +force_symlink=0 -while getopts ChVvqot:d: opt; do +while getopts ChSsVvqot:d: opt; do case "$opt" in C) always_copy=1 ;; h) show_help ;; @@ -51,6 +52,8 @@ while getopts ChVvqot:d: opt; do o) in_host=1 ;; d) DOTFILES_DIR=$OPTARG ;; V) version=1 ;; + S) force_symlink=1 ;; + s) force_symlink=0 ;; esac done shift $(($OPTIND-1)) @@ -67,8 +70,15 @@ fi files=$@ +if [ $force_symlink -eq 1 ]; then + for file in $files; do + dedotted=`de_dot $file` + INSTALL="$INSTALL -S $dedotted" + done +fi + for file in $files; do - dotless=`echo $file | sed -e "s|$DEST_DIR/||" | sed -e 's/^\.//'` + dotless=`de_dot $file` dest=`destination $DOTFILES_DIR $dotless $in_host $tag` mkdir -p $dest/`dirname $dotless` $PRINT "Moving..." diff --git a/bin/rcdn b/bin/rcdn index ebd5dea..064a541 100755 --- a/bin/rcdn +++ b/bin/rcdn @@ -36,14 +36,16 @@ handle_command_line() { local files= local excludes= local includes= + local symlink_dirs= - while getopts VqvhI:x:t:d: opt; do + while getopts VqvhI:x:S:t:d: opt; do case "$opt" in h) show_help ;; I) includes="$includes $OPTARG";; k) run_hooks=1 ;; K) run_hooks=0 ;; t) arg_tags="$arg_tags $OPTARG" ;; + S) symlink_dirs="$symlink_dirs $OPTARG";; v) verbosity=$(($verbosity + 1));; q) verbosity=$(($verbosity - 1));; d) dotfiles_dirs="$dotfiles_dirs $OPTARG" ;; @@ -72,6 +74,9 @@ handle_command_line() { for include in $includes; do LS_ARGS="$LS_ARGS -I $include" done + for symlink_dir in $symlink_dirs; do + LS_ARGS="$LS_ARGS -S $symlink_dir" + done LS_ARGS="$LS_ARGS $files" $DEBUG "LS_ARGS: $LS_ARGS" diff --git a/bin/rcup b/bin/rcup index f5c9459..5ba4822 100755 --- a/bin/rcup +++ b/bin/rcup @@ -104,9 +104,10 @@ handle_command_line() { local excludes= local includes= local always_copy=0 + local symlink_dirs= REPLACE_ALL=0 - while getopts CVqvfhikKI:x:t:d: opt; do + while getopts CVqvfhikKI:x:S:t:d: opt; do case "$opt" in C) always_copy=1 ;; d) dotfiles_dirs="$dotfiles_dirs $OPTARG" ;; @@ -118,6 +119,7 @@ handle_command_line() { K) run_hooks=0 ;; q) verbosity=$(($verbosity - 1)) ;; t) arg_tags="$arg_tags $OPTARG" ;; + S) symlink_dirs="$symlink_dirs $OPTARG";; v) verbosity=$(($verbosity + 1)) ;; V) version=1 ;; x) excludes="$excludes $OPTARG" ;; @@ -148,6 +150,9 @@ handle_command_line() { for include in $includes; do LS_ARGS="$LS_ARGS -I $include" done + for symlink_dir in $symlink_dirs; do + LS_ARGS="$LS_ARGS -S $symlink_dir" + done LS_ARGS="$LS_ARGS $files" $DEBUG "LS_ARGS: $LS_ARGS" -- cgit v1.2.3