rewrite install script to posix sh compatible
This commit is contained in:
parent
0fc4f945bc
commit
1706e7bda9
41
TARGETS.sh
41
TARGETS.sh
@ -1,21 +1,20 @@
|
|||||||
declare -r -A TARGETS=(
|
readonly TARGETS="\
|
||||||
["colors"]=".config/terminal-colors.d"
|
colors:.config/terminal-colors.d
|
||||||
["tmux"]=".config/tmux .tmux .config/systemd/user/tmux.service .local/bin/tmux_start_session.sh .local/bin/tmux_list_sessions.sh .local/bin/tmux_attach_session.sh .local/bin/tmux_kill_sessions.sh"
|
tmux:.config/tmux .tmux .config/systemd/user/tmux.service .local/bin/tmux_start_session.sh .local/bin/tmux_list_sessions.sh .local/bin/tmux_attach_session.sh .local/bin/tmux_kill_sessions.sh
|
||||||
["zsh"]=".config/zsh .zshenv .inputrc %colors"
|
zsh:.config/zsh .zshenv .inputrc %colors
|
||||||
["alacritty"]=".config/alacritty"
|
alacritty:.config/alacritty
|
||||||
["nvim"]=".config/nvim .editorconfig .inputrc .editrc .local/bin/vim_askpass_helper"
|
nvim:.config/nvim .editorconfig .inputrc .editrc .local/bin/vim_askpass_helper
|
||||||
["ssh"]=""
|
ssh:
|
||||||
["less"]=".lesskey"
|
less:.lesskey
|
||||||
["git"]=".config/git"
|
git:.config/git
|
||||||
["ranger"]=".config/ranger"
|
ranger:.config/ranger
|
||||||
["gpg"]=""
|
gpg:
|
||||||
["i3"]=".xinitrc .xprofile .Xresources .config/i3 .config/i3status .local/bin/i3status_wrapper .config/rofi .config/picom .local/bin/slm .local/bin/slm_rofi.sh .local/bin/power_rofi.sh .local/bin/wifi .local/bin/bluetooth .local/bin/i3_switch_workspace.sh"
|
i3:.xinitrc .xprofile .Xresources .config/i3 .config/i3status .local/bin/i3status_wrapper .config/rofi .config/picom .local/bin/slm .local/bin/slm_rofi.sh .local/bin/power_rofi.sh .local/bin/wifi .local/bin/bluetooth .local/bin/i3_switch_workspace.sh
|
||||||
["bat"]=".config/bat"
|
bat:.config/bat
|
||||||
["font"]=""
|
font:
|
||||||
["termux"]=".termux"
|
termux:.termux
|
||||||
["arch"]=""
|
arch:
|
||||||
["psql"]=".psqlrc"
|
psql:.psqlrc
|
||||||
["docker"]=".docker/cli-plugins"
|
docker:.docker/cli-plugins
|
||||||
["ipython"]=".ipython/profile_default/ipython_config.py"
|
ipython:.ipython/profile_default/ipython_config.py
|
||||||
["gdb"]=".config/gdb"
|
gdb:.config/gdb"
|
||||||
)
|
|
||||||
242
install
242
install
@ -1,132 +1,163 @@
|
|||||||
#!/usr/bin/env bash
|
#!/bin/sh
|
||||||
|
|
||||||
set -ueo pipefail
|
set -ue
|
||||||
shopt -s nullglob
|
|
||||||
|
|
||||||
declare -r TARGET_PATH="$HOME"
|
readonly TARGET_PATH="$HOME"
|
||||||
|
|
||||||
|
|
||||||
_detect_current_script_real_directory() {
|
_detect_current_script_real_directory() {
|
||||||
realpath -e -- "$(dirname -- "$(readlink -e -- "${BASH_SOURCE[0]:-$0}")")"
|
realpath -e -- "$(dirname -- "$(readlink -e -- "${0}")")"
|
||||||
}
|
}
|
||||||
|
|
||||||
declare DOTFILES_ROOT
|
|
||||||
DOTFILES_ROOT="$(_detect_current_script_real_directory)"
|
DOTFILES_ROOT="$(_detect_current_script_real_directory)"
|
||||||
readonly DOTFILES_ROOT
|
readonly DOTFILES_ROOT
|
||||||
|
|
||||||
declare -xr SUB="${DOTFILES_ROOT}/home/user"
|
readonly SUB="${DOTFILES_ROOT}/home/user"
|
||||||
|
export SUB
|
||||||
|
|
||||||
source "${DOTFILES_ROOT}/TARGETS.sh"
|
. "${DOTFILES_ROOT}/TARGETS.sh"
|
||||||
|
|
||||||
|
|
||||||
_die() {
|
_die() {
|
||||||
echo "${0}: ${1}" >&2
|
echo "$(basename "${0}"): ${1}" >&2
|
||||||
exit $2
|
exit "${2}"
|
||||||
}
|
}
|
||||||
|
|
||||||
_link_files_in_sandbox() {
|
string_get_first_char() (
|
||||||
local targetfile
|
printf %.1s "${1}"
|
||||||
|
)
|
||||||
|
|
||||||
|
string_exclude_first_char() (
|
||||||
|
echo "${1}" | tail -c+2
|
||||||
|
)
|
||||||
|
|
||||||
|
map_get_value() (
|
||||||
|
map="${1}"
|
||||||
|
key="${2}"
|
||||||
|
|
||||||
|
echo "${map}" | grep "${key}:" | cut -d ':' -f2
|
||||||
|
)
|
||||||
|
|
||||||
|
map_get_keys() (
|
||||||
|
map="${1}"
|
||||||
|
|
||||||
|
echo "${map}" | cut -d ':' -f1
|
||||||
|
)
|
||||||
|
|
||||||
|
map_key_exists() (
|
||||||
|
map="${1}"
|
||||||
|
key="${2}"
|
||||||
|
|
||||||
|
map_get_keys "${map}" | grep "${2}" 1>/dev/null
|
||||||
|
)
|
||||||
|
|
||||||
|
_link_files_in_sandbox() (
|
||||||
for targetfile in "$@"
|
for targetfile in "$@"
|
||||||
do
|
do
|
||||||
echo "installing: ${targetfile}"
|
echo "installing: ${targetfile}"
|
||||||
if [[ "${targetfile::1}" = "%" ]]; then
|
if [ "$(string_get_first_char "${targetfile}")" = "%" ]; then
|
||||||
_link_files_in_sandbox ${TARGETS["${targetfile:1}"]}
|
files="$(map_get_value "${TARGETS}" "$(string_exclude_first_char "${targetfile}")")"
|
||||||
|
_link_files_in_sandbox ${files}
|
||||||
else
|
else
|
||||||
if [[ ! "$(dirname "$targetfile")" = "." ]]; then
|
if [ ! "$(dirname "$targetfile")" = "." ]; then
|
||||||
mkdir -p "${SANDBOX_PATH}/$(dirname "$targetfile")"
|
mkdir -p "${SANDBOX_PATH}/$(dirname "$targetfile")"
|
||||||
fi
|
fi
|
||||||
ln -sT "${SUB}/${targetfile}" "${SANDBOX_PATH}/${targetfile}"
|
ln -sT "${SUB}/${targetfile}" "${SANDBOX_PATH}/${targetfile}"
|
||||||
fi
|
fi
|
||||||
done
|
done
|
||||||
}
|
)
|
||||||
|
|
||||||
_compare_sandbox_to_home() {
|
_compare_sandbox_to_home() (
|
||||||
local comparisons
|
comparisons="$(diff -rq "$SANDBOX_PATH" "$TARGET_PATH")" || true
|
||||||
comparisons="$(diff -rq "$SANDBOX_PATH" "$TARGET_PATH")"
|
echo "${comparisons}" | grep -vE "^Only in .+" || true
|
||||||
echo "$comparisons" | grep -vE "^Only in .+" || true
|
)
|
||||||
}
|
|
||||||
|
|
||||||
_merge_sandbox_to_home() {
|
_merge_sandbox_to_home() (
|
||||||
cp -RTnP "$SANDBOX_PATH" "$TARGET_PATH" || true
|
cp -RTnP "${SANDBOX_PATH}" "${TARGET_PATH}" || true
|
||||||
}
|
)
|
||||||
|
|
||||||
__install_from_sandbox() {
|
__install_from_sandbox() (
|
||||||
local comparisons
|
|
||||||
comparisons="$(_compare_sandbox_to_home)"
|
comparisons="$(_compare_sandbox_to_home)"
|
||||||
|
|
||||||
if [[ -n "$comparisons" ]]; then
|
if [ -n "${comparisons}" ]; then
|
||||||
echo "$comparisons" >&2
|
echo "${comparisons}" >&2
|
||||||
_die "Found conflicting files. Exiting" 1
|
_die "Found conflicting files. Exiting" 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
echo "Merging to home..."
|
echo "Merging to home..."
|
||||||
_merge_sandbox_to_home
|
_merge_sandbox_to_home
|
||||||
echo "Successfully installed"
|
echo "Successfully installed"
|
||||||
}
|
)
|
||||||
|
|
||||||
_execute_hook_if_executable() {
|
_execute_hook_if_executable() (
|
||||||
# all hooks gets SUB and SANDBOX_PATH env variables
|
# all hooks gets SUB and SANDBOX_PATH env variables
|
||||||
local -r target="$1"
|
target="$1"
|
||||||
local -r hook_name="$2"
|
hook_name="$2"
|
||||||
|
|
||||||
local hook_path="${DOTFILES_ROOT}/install-hooks/${target}/${hook_name}"
|
hook_path="${DOTFILES_ROOT}/install-hooks/${target}/${hook_name}"
|
||||||
if [[ -x "$hook_path" ]]; then
|
if [ -x "${hook_path}" ]; then
|
||||||
echo "Executing ${hook_name} for target '${target}'"
|
echo "Executing ${hook_name} for target '${target}'"
|
||||||
"$hook_path"
|
"${hook_path}"
|
||||||
fi
|
fi
|
||||||
}
|
)
|
||||||
|
|
||||||
execute_pre_hook() {
|
execute_pre_hook() (
|
||||||
_execute_hook_if_executable "$1" "pre-install"
|
_execute_hook_if_executable "${1}" "pre-install"
|
||||||
}
|
)
|
||||||
|
|
||||||
recursive_execute_pre_hooks() {
|
recursive_execute_pre_hooks() (
|
||||||
local targetfile
|
files="$(map_get_value "${TARGETS}" "${1}")"
|
||||||
for targetfile in ${TARGETS["$1"]}
|
|
||||||
|
for targetfile in ${files}
|
||||||
do
|
do
|
||||||
if [[ "${targetfile::1}" = "%" ]]; then
|
if [ "$(string_get_first_char "${targetfile}")" = "%" ]; then
|
||||||
recursive_execute_pre_hooks "${targetfile:1}"
|
recursive_execute_pre_hooks "$(string_exclude_first_char "${targetfile}")"
|
||||||
execute_pre_hook "${targetfile:1}"
|
execute_pre_hook "$(string_exclude_first_char "${targetfile}")"
|
||||||
fi
|
fi
|
||||||
done
|
done
|
||||||
}
|
)
|
||||||
|
|
||||||
execute_post_hook() {
|
execute_post_hook() (
|
||||||
_execute_hook_if_executable "$1" "post-install"
|
_execute_hook_if_executable "$1" "post-install"
|
||||||
}
|
)
|
||||||
|
|
||||||
recursive_execute_post_hooks() {
|
recursive_execute_post_hooks() (
|
||||||
local targetfile
|
files="$(map_get_value "${TARGETS}" "${1}")"
|
||||||
for targetfile in ${TARGETS["$1"]}
|
|
||||||
|
for targetfile in ${files}
|
||||||
do
|
do
|
||||||
if [[ "${targetfile::1}" = "%" ]]; then
|
if [ "$(string_get_first_char "${targetfile}")" = "%" ]; then
|
||||||
recursive_execute_post_hooks "${targetfile:1}"
|
recursive_execute_post_hooks "$(string_exclude_first_char "${targetfile}")"
|
||||||
execute_post_hook "${targetfile:1}"
|
execute_post_hook "$(string_exclude_first_char "${targetfile}")"
|
||||||
fi
|
fi
|
||||||
done
|
done
|
||||||
}
|
)
|
||||||
|
|
||||||
install_target() {
|
install_target() (
|
||||||
local -r target="$1"
|
target="${1}"
|
||||||
|
|
||||||
execute_pre_hook "$target"
|
files="$(map_get_value "${TARGETS}" "${target}")"
|
||||||
recursive_execute_pre_hooks "$target"
|
|
||||||
_link_files_in_sandbox ${TARGETS["$target"]}
|
execute_pre_hook "${target}"
|
||||||
|
recursive_execute_pre_hooks "${target}"
|
||||||
|
_link_files_in_sandbox ${files}
|
||||||
__install_from_sandbox
|
__install_from_sandbox
|
||||||
recursive_execute_post_hooks "$target"
|
recursive_execute_post_hooks "${target}"
|
||||||
execute_post_hook "$target"
|
execute_post_hook "${target}"
|
||||||
}
|
)
|
||||||
|
|
||||||
is_target_installed() {
|
is_target_installed() (
|
||||||
local not_fully_installed=false
|
target="${1}"
|
||||||
|
not_fully_installed=false
|
||||||
|
|
||||||
local targetfile
|
files="$(map_get_value "${TARGETS}" "${target}")"
|
||||||
for targetfile in ${TARGETS["$1"]}
|
|
||||||
|
for targetfile in ${files}
|
||||||
do
|
do
|
||||||
if [[ "${targetfile::1}" = "%" ]]; then
|
if [ "$(string_get_first_char "${targetfile}")" = "%" ]; then
|
||||||
is_target_installed "${targetfile:1}" || not_fully_installed=true
|
is_target_installed "$(string_exclude_first_char "${targetfile}")" || not_fully_installed=true
|
||||||
else
|
else
|
||||||
if [[ ! -e "$TARGET_PATH/$targetfile" ]]; then
|
if [ ! -e "${TARGET_PATH}/${targetfile}" ]; then
|
||||||
echo "${targetfile} not linked"
|
echo "${targetfile} not linked"
|
||||||
not_fully_installed=true
|
not_fully_installed=true
|
||||||
fi
|
fi
|
||||||
@ -138,86 +169,85 @@ is_target_installed() {
|
|||||||
return 1
|
return 1
|
||||||
fi
|
fi
|
||||||
return 0
|
return 0
|
||||||
}
|
)
|
||||||
|
|
||||||
find_targets_that_depend_on() {
|
find_targets_that_depend_on() (
|
||||||
local target
|
for target in $(map_get_keys "${TARGETS}")
|
||||||
for target in "${!TARGETS[@]}"
|
|
||||||
do
|
do
|
||||||
if [[ " ${TARGETS["$target"]} " =~ " %${1} " ]]; then
|
files="$(map_get_value "${TARGETS}" "${target}")"
|
||||||
echo "$target"
|
|
||||||
|
if map_key_exists "${TARGETS}" "%${1}"; then
|
||||||
|
echo "${target}"
|
||||||
fi
|
fi
|
||||||
done
|
done
|
||||||
}
|
)
|
||||||
|
|
||||||
die_if_installed_targets_depend_on() {
|
die_if_installed_targets_depend_on() (
|
||||||
for reverse_dependecy in $(find_targets_that_depend_on "$1")
|
for reverse_dependecy in $(find_targets_that_depend_on "$1")
|
||||||
do
|
do
|
||||||
if is_target_installed "$reverse_dependecy" >/dev/null; then
|
if is_target_installed "${reverse_dependecy}" >/dev/null; then
|
||||||
_die "target '${reverse_dependecy}' is depends on installed target '${1}'. Exiting..." 1
|
_die "target '${reverse_dependecy}' is depends on installed target '${1}'. Exiting..." 1
|
||||||
fi
|
fi
|
||||||
done
|
done
|
||||||
}
|
)
|
||||||
|
|
||||||
cmd_unlink() {
|
cmd_unlink() (
|
||||||
local target targetfile
|
|
||||||
for target in "$@"
|
for target in "$@"
|
||||||
do
|
do
|
||||||
die_if_installed_targets_depend_on "$target"
|
die_if_installed_targets_depend_on "${target}"
|
||||||
|
|
||||||
for targetfile in ${TARGETS["$target"]}
|
files="$(map_get_value "${TARGETS}" "${target}")"
|
||||||
|
for targetfile in ${files}
|
||||||
do
|
do
|
||||||
if [[ "${targetfile::1}" = "%" ]]; then
|
if [ "$(string_get_first_char "${targetfile}")" = "%" ]; then
|
||||||
continue
|
continue
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [[ -e "${TARGET_PATH}/${targetfile}" ]]; then
|
if [ -e "${TARGET_PATH}/${targetfile}" ]; then
|
||||||
unlink "${TARGET_PATH}/${targetfile}"
|
unlink "${TARGET_PATH}/${targetfile}"
|
||||||
fi
|
fi
|
||||||
done
|
done
|
||||||
done
|
done
|
||||||
}
|
)
|
||||||
|
|
||||||
cmd_no_target() {
|
cmd_no_target() (
|
||||||
_die "TARGET not exists" 1
|
_die "TARGET not exists" 1
|
||||||
}
|
)
|
||||||
|
|
||||||
cmd_list() {
|
cmd_list() (
|
||||||
echo "${!TARGETS[@]}"
|
map_get_keys "${TARGETS}"
|
||||||
}
|
)
|
||||||
|
|
||||||
target_exists() {
|
target_exists() (
|
||||||
local -r target="$1"
|
target="$1"
|
||||||
[[ " ${!TARGETS[*]} " =~ " ${target} " ]]
|
map_key_exists "${TARGETS}" "${target}"
|
||||||
}
|
)
|
||||||
|
|
||||||
cmd_install() {
|
cmd_install() (
|
||||||
local target
|
|
||||||
for target in "$@"
|
for target in "$@"
|
||||||
do
|
do
|
||||||
if target_exists "$target"; then
|
if target_exists "${target}"; then
|
||||||
SANDBOX_PATH="$(mktemp -td "${USER:-user}.dotfiles_XXXXXXX")"
|
SANDBOX_PATH="$(mktemp -td "${USER:-user}.dotfiles_XXXXXXX")"
|
||||||
export SANDBOX_PATH
|
export SANDBOX_PATH
|
||||||
install_target "$target"
|
install_target "${target}"
|
||||||
rm -rf "$SANDBOX_PATH"
|
rm -rf "$SANDBOX_PATH"
|
||||||
else
|
else
|
||||||
cmd_no_target
|
cmd_no_target
|
||||||
fi
|
fi
|
||||||
done
|
done
|
||||||
}
|
)
|
||||||
|
|
||||||
cmd_help() {
|
cmd_help() (
|
||||||
echo "Dotfiles installation script:
|
echo "Dotfiles installation script:
|
||||||
Usage: ./install TARGET...
|
Usage: ./install TARGET...
|
||||||
Usage: ./install unlink TARGET...
|
Usage: ./install unlink TARGET...
|
||||||
Usage: ./install check TARGET
|
Usage: ./install check TARGET
|
||||||
Usage: ./install list"
|
Usage: ./install list"
|
||||||
}
|
)
|
||||||
|
|
||||||
unset executed_command
|
readonly executed_command="${1}"
|
||||||
readonly executed_command="$1"
|
|
||||||
|
|
||||||
case "$executed_command" in
|
case "${executed_command}" in
|
||||||
unlink) shift; cmd_unlink "$@" ;;
|
unlink) shift; cmd_unlink "$@" ;;
|
||||||
check) shift; is_target_installed "$@" ;;
|
check) shift; is_target_installed "$@" ;;
|
||||||
list) shift; cmd_list "$@" ;;
|
list) shift; cmd_list "$@" ;;
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user