refactor, better var names, remove dup code
[lnf] / lnf
diff --git a/lnf b/lnf
index b4701dff636fad888363677ddac4d716dfdea61d..1ab1cdf95689cdb5b754d6cc7e25559ca106baf1 100755 (executable)
--- a/lnf
+++ b/lnf
@@ -1,23 +1,26 @@
 #!/bin/bash
-# Copyright (C) 2014 Ian Kelling
+# Copyright (C) 2014-2016 Ian Kelling
 # This program is under GPL v. 3 or later, see <http://www.gnu.org/licenses/>
 
 lnf() {
-    local help="lnf - Create symlinks conveniently and forcefully.
-Usage:
+    local help="Usage:
        lnf -T TARGET LINK_NAME     (1st form)
        lnf TARGET                  (2nd form)
        lnf TARGET... DIRECTORY     (3rd form)
+Create symlinks forcefully
 
-Remove existing file in the using trash-put or rm -rf if it is not available,
-or trash-put fails due to a cross-filesystem link.
+Removes existing files using trash-put or rm -rf if it is not available,
+or trash-put fails due to a limitation such as a cross-filesystem link.
 Create directory if needed. Slightly more restrictive arguments than ln.
 
 In the 1st form, create a link to TARGET with the name LINK_NAME.  In the 2nd
 form, create a link to TARGET in the current directory.  In the 3rd form, create
-links to each TARGET in DIRECTORY."
+links to each TARGET in DIRECTORY.
 
-    if [[ $1 == --help || $# -eq 0 ]]; then
+Do export LNF_VERBOSE=true for verbose output
+"
+
+    if [[ $1 == --help || $1 == -h || $# -eq 0 ]]; then
         echo "$help"
         return 0
     fi
@@ -32,30 +35,31 @@ links to each TARGET in DIRECTORY."
         fi
     fi
 
+
     local reset_extglob=false
     ! shopt extglob >/dev/null && reset_extglob=true
     shopt -s extglob
 
 
     local x ret prefix dir to_remove
+    local mkdir=false
 
     to_remove=()
     if [[ $nodir ]]; then
-        dir="$(dirname "$2")"
-        if [[ -e $2 || -L $2 ]]; then
-            to_remove+=("$2")
-        elif [[ ! -d $dir ]]; then
-            if [[ -e $dir || -L $dir ]]; then
+        dest_file="$2"
+        dest_dir="$(dirname "$dest_file")"
+        if [[ -e $dest_file || -L $dest_file ]]; then
+            to_remove+=("$dest_file")
+        elif [[ ! -d $dest_dir ]]; then
+            mkdir=true
+            if [[ -e $dest_dir || -L $dest_dir ]]; then
                 to_remove+=("$dir")
             fi
-            if ! mkdir -p "$(dirname "$2")"; then
-                echo "lnf error: failed to make directory $(dirname "$2")"
-                return 1
-            fi
         fi
     elif (( $# >= 2 )); then
-        if [[ -d ${!#} ]]; then
-            prefix="${!#}/" # last arg
+        dest_dir="${!#}"
+        if [[ -d $dest_dir ]]; then
+            prefix="$dest_dir/" # last arg
             for x in "${@:1:$(( $# - 1 ))}"; do # all but last arg
                 # Remove 1 or more trailing slashes, using.
                 x="${x%%+(/)}"
@@ -64,16 +68,16 @@ links to each TARGET in DIRECTORY."
                 [[ -e "$x" || -L "$x" ]] && to_remove+=("$x")
             done
         else
-            if ! mkdir -p "${!#}"; then
-                echo "lnf error: failed to make directory ${!#}"
-                return 1
-            fi
+            mkdir=true
         fi
     elif  [[ $# -eq 1 ]]; then
         [[ -e "${1##*/}" || -L "${1##*/}" ]] && to_remove+=("${1##*/}")
     fi
     if (( ${#to_remove[@]} >= 1 )); then
         if type -P trash-put >/dev/null; then
+            if [[ $LNF_VERBOSE == true ]]; then
+                echo "lnf: trash-put -- ${to_remove[*]}"
+            fi
             trash-put -- "${to_remove[@]}" || ret=$?
             # trash-put will fail to trash a link that goes across filesystems (72),
             # and for empty files (74)
@@ -82,17 +86,28 @@ links to each TARGET in DIRECTORY."
                 echo "$0: using rm -rf to overcome cross filesystem trash-put limitation"
                 rm -rf -- "${to_remove[@]}"
             elif [[ $ret == 74 ]]; then
-                echo "$0: using rm -rf to overcome empty file/dir trash-put limitation"
+                echo "$0: using rm -rf to overcome empty file & hardlink trash-put limitation"
                 rm -rf -- "${to_remove[@]}"
             elif [[ $ret && $ret != 0 ]]; then
                 return $x
             fi
         else
+            if [[ $LNF_VERBOSE == true ]]; then
+                echo "lnf: rm -rf -- ${to_remove[*]}"
+            fi
             rm -rf -- "${to_remove[@]}"
         fi
     fi
 
     $reset_extglob && shopt -u extglob
+
+    if $mkdir; then
+        if ! mkdir -p "$dest_dir"; then
+            echo "lnf error: failed to make directory $dest_dir"
+            return 1
+        fi
+    fi
+
     ln -s $nodir -- "$@"
 }
 lnf "$@"