This repository has been archived on 2022-12-11. You can view files and clone it, but cannot push or open issues or pull requests.
dot-files/.bin/link-conf.sh

224 lines
6.1 KiB
Bash
Executable File

#!/bin/sh
# (C) Copyright Collin Doering 2011
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
# File: link-conf.sh
# Author: Collin J. Doering <rekahsoft@gmail.com>
# Date: Jun 4, 2011
# TODO: * add support for a 'interactive' option [ -i | --interactive ]
# * add support for a link-to option so you can link the given config-dir files to
# somewhere other then $HOME
# lnfrec takes:
# $1: the config dir in question
# $2: the current directory in the recursive call (used internally to recurse the config dir)
# $3: boolean specifying option relink
# $4: boolean specifying option clean
# $5: boolean specifying option verbose
# $6: boolean specifying option force
# $7: boolean specifying option dry
function lnfrec () {
# for each file in $1 directory do link (default), relink ($3) or clean ($4) along with options
# verbose ($5) and force ($6)
for f in `ls -aA $1/$2`; do
case "$f" in
.)
;;
..)
;;
*/.)
;;
*/..)
;;
*~)
;;
.git)
;;
.gitignore)
;;
*)
# If the current file being recursed on from the given config dir ($1) is a directory
if [[ -d "$1$2/$f" ]]; then
# If the file currently being recursed on from the config dir ($1) in $HOME is not a directory
# (that is $HOME$2/$f); then create the directory $HOME$2/$f
if [[ ! -d "$HOME$2/$f" ]]; then
$5 && echo "Creating dir $HOME$2/$f"
! $7 && mkdir "$HOME$2/$f"
fi
# recurse further into config dir to $1$2/$f
lnfrec "$1" "$2/$f" $3 $4 $5 $6 $7
# If the current file being recursed on from the given config dir ($1) in $HOME is not a directory
# and is not a file or a link, then create a hardlink from $1$2/$f to $HOME$2/$f
elif [[ ! -e "$HOME$2/$f" && ! -L "$HOME$2/$f" ]]; then
$5 && echo "Linked $1$2/$f -> $HOME$2/$f"
! $7 && ln "$1$2/$f" "$HOME$2/$f"
# Otherwise: the file exists ($HOME$2/$f)
else
NUM_LINKS=$(ls -al "$HOME$2/$f" | cut -d' ' -f2)
# If the relink option is set
if $3; then
# check if the config file $HOME$2/$f has more then one hardlink; if so then relink
if [[ $NUM_LINKS -gt 1 ]]; then
$5 && echo "Re-linking $1$2/$f -> $HOME$2/$f"
! $7 && rm "$HOME$2/$f"
! $7 && ln "$1$2/$f" "$HOME$2/$f"
# if the force option is set (along with the relink option)
elif $6; then
echo "Warning! Removing regular file $HOME$2/$f"
! $7 && rm "$HOME$2/$f"
$5 && echo "Re-linking $1$2/$f -> $HOME$2/$f"
! $7 && ln "$1$2/$f" "$HOME$2/$f"
else
$5 && echo "$HOME$2/$f only has one file reference! Skipping.."
fi
# If the clean option is set
elif $4; then
# Check if the config file $HOME$2/$f has more then one hardlink; if so then clean the file from home
if [[ $NUM_LINKS -gt 1 ]]; then
$5 && echo "Cleaning $HOME$2/$f"
! $7 && rm "$HOME$2/$f"
# If the force option is set (along with clean)
elif $6; then
echo "Warning! Forcing removal of $HOME$2/$f"
$5 && echo "Cleaning $HOME$2/$f"
! $7 && rm "$HOME$2/$f"
else
$5 && echo "$HOME$2/$f only has one file reference! Skipping.."
fi
else
$5 && echo "$HOME$2/$f already linked! Skipping.."
fi # will fault if not given proper arguments! Internal usage only!
fi
;;
esac
done
}
function displayHelp () {
echo "Usage: link-conf [-r|--relink] [-f|--force] [-c|--clean] [-v|--verbose] [-d|--dry] [-h|--help] config-dir"
}
# Option variables set when parsing cli parameters
RELINK=false
CLEAN=false
VERBOSE=false
FORCE=false
DRY=false
CONFIG_DIR=""
# Use getopt to parse given cli arguments
args=`getopt -n link-conf -o rcfvdh -l relink,clean,force,verbose,dry,help -- $*`
if [ ! $? ]; then
echo "Failed to parse arguments!"
displayHelp
exit 1
fi
# Set arguments to the new ones done by using getopt
set -- $args
while true; do
case "$1" in
-r | --relink)
if $CLEAN; then
echo "Error! Cannot specify relink and clean at once!"
exit 1
elif [ !$RELINK ]; then
RELINK=true
else
echo "Error! -r | --relink used more then once!"
exit 1
fi
;;
-c | --clean)
if $RELINK; then
echo "Error! Cannot specify relink and clean at once!"
exit 1
elif [ !$CLEAN ]; then
CLEAN=true
else
echo "Error! -c | --clean used more then once!"
exit 1
fi
;;
-v | --verbose)
if [ !$VERBOSE ]; then
VERBOSE=true
else
echo "Error! -v | --verbose used more then once!"
exit 1
fi
;;
-f | --force)
if [ !$FORCE ]; then
FORCE=true
else
echo "Error! -f | --force used more then once!"
exit 1
fi
;;
-d | --dry)
if [ !$DRY ]; then
DRY=true
else
echo "Error! -d | --dry used more then once!"
exit 1
fi
;;
-h | --help)
displayHelp
exit 0
;;
--)
shift
for arg; do
maybe_dir=$(echo $arg | sed "s/^\([\']\)\(.*\)\1\$/\2/g")
if [ "$CONFIG_DIR" == "" ]; then
if [[ -d "$maybe_dir" ]]; then
CONFIG_DIR="$maybe_dir"
else
echo "Error! The path given \"$maybe_dir\" is not a valid directory!"
exit 1
fi
else
echo "Error! More then one config dir was given!"
displayHelp
exit 1
fi
done
break
;;
*)
echo "Internal error!"
exit 1
;;
esac
shift
done
# Notify the user if it is a dry run
if $DRY; then
echo "Dry run.."
fi
# Run the recursive hard linking algorithm
lnfrec "$CONFIG_DIR" "" $RELINK $CLEAN $VERBOSE $FORCE $DRY
# exit gracefully
exit 0