From 0ed3373f1c2d47aba769aa67439e05350c2792e9 Mon Sep 17 00:00:00 2001 From: Aaron LI Date: Wed, 6 Jan 2016 22:12:33 +0800 Subject: Add scripts `enable.sh` & `disable.sh` * `enable.sh`: to enable a dotfile or directory * `disable.sh`: to disable a dotfile or directory * `relpath.sh`: helper script to determine the relative path --- _bin/disable.sh | 114 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ _bin/enable.sh | 111 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ _bin/relpath.sh | 69 ++++++++++++++++++++++++++++++++++ 3 files changed, 294 insertions(+) create mode 100755 _bin/disable.sh create mode 100755 _bin/enable.sh create mode 100755 _bin/relpath.sh (limited to '_bin') diff --git a/_bin/disable.sh b/_bin/disable.sh new file mode 100755 index 0000000..eb4549f --- /dev/null +++ b/_bin/disable.sh @@ -0,0 +1,114 @@ +#!/bin/sh +# +# Disable specified dotfiles by removing the symbolic links of the dotfiles +# from home directory. +# +# Aaron LI +# Created: 2015-01-06 +# Updated: 2015-01-06 +# + +usage() { + echo "Usage:" + echo " `basename $0` [ -fhknv ] [ -H ] ..." + echo "" + echo " -h: show this help" + echo " -f: force remove target link even it is not the link to the source dotfile" + echo " -H: use the specified target home instead of $HOME" + echo " -k: keep the beginning underscore '_'" + echo " -n: dry-run" + echo " -v: verbose" + echo " df*: dotfiles or directory; NOTE: dot not use '.' or '..'" +} + +disable_dotfile() { + df="$1" + home="$2" + df_abs=`realpath ${df}` + if [ "x${arg_keep_us}" = "xyes" ]; then + target_df="${df}" + else + target_df=`echo "${df}" | sed 's|^_|.|'` + fi + ( cd ${home}; target_df_abs=`realpath "${target_df}"`; \ + if [ ! -e "${target_df}" ]; then \ + echo "WARNING: target file do NOT exist"; \ + elif [ "x${arg_force}" = "xyes" ] || [ "x${target_df_abs}" = "x${df_abs}" ]; then \ + eval ${disable_cmd} "${target_df}"; \ + else \ + echo "WARNING: target is NOT a link to source dotfile"; \ + fi; \ + ) +} + + +this=`realpath $0` +this_dir=`dirname ${this}` + +# default arguments +arg_force=no +arg_home="$HOME" +arg_keep_us=no +arg_dry=no +arg_verbose=no + +# should NOT use "$@" here +args=`getopt fhH:knv $*` +if [ $? != 0 ]; then + usage + exit 1 +fi +set -- ${args} +for i; do + case "$i" in + -h) + usage + exit 0;; + -f) + arg_force=yes + shift;; + -H) + arg_home="$2"; shift; + shift;; + -k) + arg_keep_us=yes + shift;; + -n) + arg_dry=yes + shift;; + -v) + arg_verbose=yes + shift;; + --) + shift; break;; + esac +done + +if [ $# -eq 0 ]; then + usage + exit 2 +fi + +echo "force: ${arg_force}" +echo "target_home: ${arg_home}" +echo "keep_underscore: ${arg_keep_us}" +echo "dry_run: ${arg_dry}" +#echo "dotfiles: $@" + +[ "x${arg_force}" = "xyes" ] && arg_rm="-f" +[ "x${arg_verbose}" = "xyes" ] && arg_rm="${arg_rm} -v" +disable_cmd="rm ${arg_rm}" +if [ "x${arg_dry}" = "xyes" ]; then + disable_cmd="echo DRY_RUN: ${disable_cmd}" +fi + +for dotfile in $@; do + for df in `find "${dotfile}" \( -type f -o -type l \)`; do + # strip the beginning './' + df=`echo "${df}" | sed 's|^\./||'` + echo "disabling: '${df}'" + disable_dotfile "${df}" "${arg_home}" + done +done + +# vim: set ts=8 sw=4 tw=0 fenc=utf-8 ft=sh: # diff --git a/_bin/enable.sh b/_bin/enable.sh new file mode 100755 index 0000000..da29421 --- /dev/null +++ b/_bin/enable.sh @@ -0,0 +1,111 @@ +#!/bin/sh +# +# Enalbe specified dotfiles by linking the dotfiles to home directory. +# +# Aaron LI +# Created: 2015-01-06 +# Updated: 2015-01-06 +# + +usage() { + echo "Usage:" + echo " `basename $0` [ -fhknv ] [ -H ] ..." + echo "" + echo " -h: show this help" + echo " -f: overwrite target links of already exists" + echo " -H: use the specified target home instead of $HOME" + echo " -k: keep the beginning underscore '_'" + echo " -n: dry-run" + echo " -v: verbose" + echo " df*: dotfiles or directory; NOTE: dot not use '.' or '..'" +} + +enable_dotfile() { + df="$1" + home="$2" + df_abs=`realpath ${df}` + if [ "x${arg_keep_us}" = "xyes" ]; then + df_dir=`dirname ${df}` + df_base=`basename ${df}` + else + df_dir=`dirname ${df} | sed 's|^_|.|'` + df_base=`basename ${df} | sed 's|^_|.|'` + fi + ( cd ${home}; curdir=`realpath .`; \ + df_rel=`${this_dir}/relpath.sh "${curdir}" "${df_abs}"`; \ + if [ ! -d "${df_dir}" ]; then mkdir -p "${df_dir}"; fi; \ + eval ${enable_cmd} "${df_rel}" "${df_dir}/${df_base}"; \ + ) +} + + +this=`realpath $0` +this_dir=`dirname ${this}` + +# default arguments +arg_force=no +arg_home="$HOME" +arg_keep_us=no +arg_dry=no +arg_verbose=no + +# should NOT use "$@" here +args=`getopt fhH:knv $*` +if [ $? != 0 ]; then + usage + exit 1 +fi +set -- ${args} +for i; do + case "$i" in + -h) + usage + exit 0;; + -f) + arg_force=yes + shift;; + -H) + arg_home="$2"; shift; + shift;; + -k) + arg_keep_us=yes + shift;; + -n) + arg_dry=yes + shift;; + -v) + arg_verbose=yes + shift;; + --) + shift; break;; + esac +done + +if [ $# -eq 0 ]; then + usage + exit 2 +fi + +echo "force: ${arg_force}" +echo "target_home: ${arg_home}" +echo "keep_underscore: ${arg_keep_us}" +echo "dry_run: ${arg_dry}" +#echo "dotfiles: $@" + +[ "x${arg_force}" = "xyes" ] && arg_ln="-f" +[ "x${arg_verbose}" = "xyes" ] && arg_ln="${arg_ln} -v" +enable_cmd="ln -s ${arg_ln}" +if [ "x${arg_dry}" = "xyes" ]; then + enable_cmd="echo DRY_RUN: ${enable_cmd}" +fi + +for dotfile in $@; do + for df in `find "${dotfile}" \( -type f -o -type l \)`; do + # strip the beginning './' + df=`echo "${df}" | sed 's|^\./||'` + echo "enabling: '${df}'" + enable_dotfile "${df}" "${arg_home}" + done +done + +# vim: set ts=8 sw=4 tw=0 fenc=utf-8 ft=sh: # diff --git a/_bin/relpath.sh b/_bin/relpath.sh new file mode 100755 index 0000000..42bde1f --- /dev/null +++ b/_bin/relpath.sh @@ -0,0 +1,69 @@ +#!/bin/sh +# +# Get the relative path to $target from $source +# +# Credits: +# [1] Getting relative links between two paths +# http://unix.stackexchange.com/a/85068 +# [2] Convert absolute path into relative path given a current directory using Bash +# http://stackoverflow.com/a/12498485 +# +# +# Aaron LI +# Created: 2015-01-06 +# Updated: 2015-01-06 +# + +relpath() { + # both $1 and $2 are absolute paths beginning with / + # $1 must be a canonical path; that is none of its directory + # components may be ".", ".." or a symbolic link + # + # returns relative path to $2/$target from $1/$source + source=$1 + target=$2 + + common_part=$source + result= + + while [ "${target#"$common_part"}" = "$target" ]; do + # no match, means that candidate common part is not correct + # go up one level (reduce common part) + common_part=$(dirname "$common_part") + # and record that we went back, with correct / handling + if [ -z "$result" ]; then + result=.. + else + result=../$result + fi + done + + if [ "$common_part" = / ]; then + # special case for root (no common path) + result=$result/ + fi + + # since we now have identified the common part, + # compute the non-common part + forward_part=${target#"$common_part"} + + # and now stick all parts together + if [ -n "$result" ] && [ -n "$forward_part" ]; then + result=$result$forward_part + elif [ -n "$forward_part" ]; then + # extra slash removal + result=${forward_part#?} + fi + + printf '%s\n' "$result" +} + + +if [ $# -ne 2 ]; then + echo "Usage:" + echo " `basename $0` " + exit 1 +fi + +relpath "$1" "$2" + -- cgit v1.2.2