diff options
author | Mike Burns <mike@mike-burns.com> | 2013-08-11 17:29:01 +0200 |
---|---|---|
committer | Mike Burns <mike@mike-burns.com> | 2013-08-11 21:18:53 +0200 |
commit | 8d7f6c94a3458328b339b6582592b6c1fecec950 (patch) | |
tree | ff9ea4a2a83fafb910d0c604435d648bf01cedbf /bin | |
parent | 0fbc27dbe296e03b4001586a7e29780328cbc657 (diff) |
Add the COPY_ALWAYS option
The suite now honors the `COPY_ALWAYS` option in rcrc(5). This can be
set to a space-separated list of file globs. Any file matching a glob is
copied instead of symlinked. This is handy both for secure programs
(`netrc`, `ssh/id_*`) and for programs that oddly re-write files
(`weechat/*`).
To always copy everything, use the `*` glob.
This is reflected throughout the suite as follows:
* lsrc now has a `-F` option which shows a symbol to indicate whether it
is a symlink (`@`) or a copy (`X`).
* rcdn only removes symlinks unless the file under question matches a
`COPY_ALWAYS` glob, in which case it is removed regardless of whether
it is a symlink.
* rcup will copy instead of symlinking any file that matches any
`COPY_ALWAYS` glob.
Diffstat (limited to 'bin')
-rwxr-xr-x | bin/lsrc | 96 | ||||
-rwxr-xr-x | bin/rcdn | 15 | ||||
-rwxr-xr-x | bin/rcup | 47 |
3 files changed, 123 insertions, 35 deletions
@@ -29,37 +29,88 @@ build_path() { fi } -link_dir() { +file_join() { + local result= + + for file; do + if [ "x$file" != "x." ]; then + if [ "x$result" = "x" ]; then + result=$file + else + result="$result/$file" + fi + fi + done + + echo $result +} + +show_dir() { local dir=$1 local dest_dir=$2 local dotfiles_dir=$3 - local dotted=$4 - local exclude_file_globs="$5" - local include_file_globs="$6" + local dotfiles_subdir=$4 + local dotted=$5 + local exclude_file_globs="$6" + local include_file_globs="$7" local dest_path=`build_path $dest_dir $dir $dotted` - $DEBUG "link_dir $1 $2 $3 $4 $5 $6" + $DEBUG "show_dir $1 $2 $3 $4 $5 $6 $7" $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 "$exclude_file_globs" "$include_file_globs" + next_dir=`file_join $dotfiles_subdir $dir` + handle_file $f $dest_path $dotfiles_dir $next_dir 1 "$exclude_file_globs" "$include_file_globs" done popdir } -link_file() { +sigil_for() { + local file=$1 + local copy_always=0 + + for copy_file in $COPY_ALWAYS; do + $DEBUG "copy_file: $copy_file" + $DEBUG "file: $file" + + case $file in + $copy_file) + copy_always=1 + break + ;; + esac + done + + if [ $copy_always -eq 1 ]; then + echo 'X' + else + echo '@' + fi +} + +show_file() { local file=$1 local dest_dir=$2 local dotfiles_dir=$3 - local dotted=$4 + local dotfiles_subdir=$4 + local dotted=$5 local dest_file=`build_path $dest_dir $file $dotted` if echo $DEST_STACK | grep -vq ":$dest_file"; then DEST_STACK="$DEST_STACK:$dest_file" - $PRINT $dest_file:$dotfiles_dir/$file + src_file=`file_join $dotfiles_subdir $file` + abs_src_file=`file_join $dotfiles_dir $src_file` + output=$dest_file:$abs_src_file + + if [ $SHOW_SIGILS -eq 1 ]; then + sigil=`sigil_for $src_file` + output="$output:$sigil" + fi + + $PRINT $output fi } @@ -67,20 +118,21 @@ handle_file() { local file=$1 local dest_dir=$2 local dotfiles_dir=$3 - local dotted=$4 - local exclude_file_globs="$5" - local include_file_globs="$6" + local dotfiles_subdir=$4 + local dotted=$5 + local exclude_file_globs="$6" + local include_file_globs="$7" - $DEBUG "handle_file $1 $2 $3 $4 $5 $6" + $DEBUG "handle_file $1 $2 $3 $4 $5 $6 $7" 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 ]; then - link_dir $file $dest_dir $dotfiles_dir $dotted "$exclude_file_globs" "$include_file_globs" + show_dir $file $dest_dir $dotfiles_dir $dotfiles_subdir $dotted "$exclude_file_globs" "$include_file_globs" else - link_file $file $dest_dir $dotfiles_dir $dotted + show_file $file $dest_dir $dotfiles_dir $dotfiles_subdir $dotted fi } @@ -147,12 +199,14 @@ handle_command_line() { local arg_tags= local verbosity=0 local version=0 + local show_sigils=0 local dotfiles_dirs= local excludes= local includes= - while getopts VqvI:x:t:d: opt; do + while getopts FVqvI:x:t:d: opt; do case "$opt" in + F) show_sigils=1;; I) includes="$includes $OPTARG";; t) arg_tags="$arg_tags $OPTARG";; v) verbosity=$(($verbosity + 1));; @@ -165,6 +219,7 @@ handle_command_line() { shift $(($OPTIND-1)) handle_common_flags lsrc $version $verbosity + SHOW_SIGILS=$show_sigils TAGS=${arg_tags:-$TAGS} DOTFILES_DIRS=${dotfiles_dirs:-$DOTFILES_DIRS} EXCLUDES=${excludes:-$EXCLUDES} @@ -186,6 +241,9 @@ handle_command_line $* : ${DOTFILES_DIRS:=$DOTFILES_DIRS $DEFAULT_DOTFILES_DIR} $DEBUG "DOTFILES_DIRS: $DOTFILES_DIRS" +: ${COPY_ALWAYS:=""} +$DEBUG "COPY_ALWAYS: $COPY_ALWAYS" + for DOTFILES_DIR in $DOTFILES_DIRS; do if is_relative $DOTFILES_DIR; then DOTFILES_DIR=$PWD/$DOTFILES_DIR @@ -208,7 +266,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" done cd $DOTFILES_DIR @@ -217,7 +275,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 "$exclude_file_globs" "$include_file_globs" + handle_file $file $DEST_DIR $host_files . 0 "$exclude_file_globs" "$include_file_globs" done popdir fi @@ -229,7 +287,7 @@ for DOTFILES_DIR in $DOTFILES_DIRS; do pushdir `basename tag-$tag` for file in ${FILES:-*}; do $DEBUG "TAG: $tag, exclude_file_globs: $exclude_file_globs" - handle_file $file $DEST_DIR $DOTFILES_DIR/tag-$tag 0 "$exclude_file_globs" "$include_file_globs" + handle_file $file $DEST_DIR $DOTFILES_DIR/tag-$tag . 0 "$exclude_file_globs" "$include_file_globs" done popdir fi @@ -6,10 +6,11 @@ remove_link() { local dest=$1 local original=$2 + local sigil=$3 if [ x$dest = "x/" ]; then $VERBOSE "not a symlink, skipping: $original" - elif [ -L $dest ]; then + elif [ -L $dest -o "x$sigil" = "xX" ]; then $RM -rf $dest rmdir -p `dirname $original` 2>/dev/null else @@ -62,6 +63,8 @@ handle_command_line() { $DEBUG "LS_ARGS: $LS_ARGS" } +LS_ARGS=-F + if [ -e $HOME/.rcrc ]; then . $HOME/.rcrc fi @@ -69,8 +72,12 @@ fi handle_command_line $* for dest_and_src in `lsrc $LS_ARGS`; do - dest=`echo $dest_and_src | sed 's/:.*//'` - src=`echo $dest_and_src | sed 's/.*://'` + saved_ifs=$IFS + IFS=: + set $dest_and_src + IFS=$saved_ifs + dest=$1 + sigil=$3 - remove_link $dest $dest + remove_link $dest $dest $sigil done @@ -3,25 +3,40 @@ : ${RCM_LIB:=`dirname $0`/../share/rcm} . $RCM_LIB/rcm.sh +link_or_copy() { + $DEBUG "link_or_copy $1" + local sigil=$1 + + if [ "x$sigil" = "xX" ]; then + echo $CP + else + echo $LN + fi +} + link_file() { local src=$1 local dest=$2 + local sigil=$3 if [ -h $dest ]; then $RM -f $dest fi - $LN $src $dest + action=`link_or_copy $sigil` + $DEBUG "$action $src $dest" + $action $src $dest } replace_file() { local src=$1 local dest=$2 + local sigil=$3 - $DEBUG replace_file $1 $2 + $DEBUG replace_file $1 $2 $3 $RM -rf $dest - link_file $src $dest + link_file $src $dest $sigil } is_nested() { @@ -44,28 +59,29 @@ handle_dir() { handle_file() { local src=$1 local dest=$2 + local sigil=$3 - $DEBUG handle_file $1 $2 + $DEBUG handle_file $1 $2 $3 if [ -e "$dest" ]; then if is_identical $src $dest; then $VERBOSE "identical $dest" elif [ $REPLACE_ALL -eq 1 ]; then - replace_file $src $dest + replace_file $src $dest $sigil else $PROMPT "overwrite ${dest}? [ynaq]" read overwrite case $overwrite in a) REPLACE_ALL=1 - replace_file $src $dest + replace_file $src $dest $sigil ;; - y) replace_file $src $dest ;; + y) replace_file $src $dest $sigil ;; q) exit 1 ;; *) $VERBOSE "skipping $dest" ;; esac fi else - link_file $src $dest + link_file $src $dest $sigil fi } @@ -97,7 +113,7 @@ handle_command_line() { shift $(($OPTIND-1)) if [ $always_copy -eq 1 ]; then - LN=cp + LN=$CP fi handle_common_flags rcup $version $verbosity @@ -123,6 +139,8 @@ handle_command_line() { $DEBUG "LS_ARGS: $LS_ARGS" } +LS_ARGS=-F + if [ -e $HOME/.rcrc ]; then . $HOME/.rcrc fi @@ -130,12 +148,17 @@ fi handle_command_line $* for dest_and_src in `lsrc $LS_ARGS`; do - dest=`echo $dest_and_src | sed 's/:.*//'` - src=`echo $dest_and_src | sed 's/.*://'` + saved_ifs=$IFS + IFS=: + set $dest_and_src + IFS=$saved_ifs + dest=$1 + src=$2 + sigil=$3 if is_nested $dest; then handle_dir $dest fi - handle_file $src $dest + handle_file $src $dest $sigil done |