#!/usr/bin/env bash set -euo pipefail PACKAGE_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd -P)" STOW_BIN="${STOW_BIN:-stow}" SETUP_SHELL=1 usage() { cat <<'EOF' Использование: ./install.sh [--no-shell-setup] --no-shell-setup не изменять ~/.bashrc EOF } while [ "$#" -gt 0 ]; do case "$1" in --no-shell-setup) SETUP_SHELL=0 ;; -h|--help) usage exit 0 ;; *) echo "Ошибка: неизвестный параметр: $1" >&2 usage >&2 exit 2 ;; esac shift done SOURCES=( "$PACKAGE_DIR/.local/bin/proxy-client" "$PACKAGE_DIR/.config/proxy-client/shell.bash" "$PACKAGE_DIR/.config/proxy-client/examples" ) TARGETS=( "$HOME/.local/bin/proxy-client" "$HOME/.config/proxy-client/shell.bash" "$HOME/.config/proxy-client/examples" ) STOW_IGNORE_PATTERNS=( '^\.local/bin/proxy-client$' '^\.config/proxy-client/shell\.bash$' '^\.config/proxy-client/examples$' ) source_errors=() [ -x "${SOURCES[0]}" ] || source_errors+=("${SOURCES[0]}") [ -f "${SOURCES[1]}" ] || source_errors+=("${SOURCES[1]}") [ -d "${SOURCES[2]}" ] || source_errors+=("${SOURCES[2]}") if [ "${#source_errors[@]}" -gt 0 ]; then echo "Ошибка: отсутствуют обязательные файлы исходного пакета:" >&2 printf ' %s\n' "${source_errors[@]}" >&2 exit 1 fi "${SOURCES[0]}" --help >/dev/null bash -n "${SOURCES[1]}" SHELL_BLOCK_START='# >>> proxy-client >>>' SHELL_BLOCK_END='# <<< proxy-client <<<' SHELL_SETUP_NEEDED=0 BASH_CUSTOM_HAS_MODULE=0 SHELL_PATH_NEEDED=1 SHELL_SOURCE_NEEDED=1 SHELL_BLOCK_CONFLICT=0 if [ "$SETUP_SHELL" -eq 1 ]; then if [ -f "$HOME/.bash_custom" ] \ && grep -Fq 'proxy-client/shell.bash' "$HOME/.bash_custom"; then BASH_CUSTOM_HAS_MODULE=1 SHELL_SOURCE_NEEDED=0 fi bashrc_start_count=0 bashrc_end_count=0 if [ -f "$HOME/.bashrc" ]; then bashrc_start_count="$( grep -Fxc "$SHELL_BLOCK_START" "$HOME/.bashrc" || true )" bashrc_end_count="$( grep -Fxc "$SHELL_BLOCK_END" "$HOME/.bashrc" || true )" if grep -Fq 'export PATH="$HOME/.local/bin:$PATH"' "$HOME/.bashrc"; then SHELL_PATH_NEEDED=0 fi fi if [ "$bashrc_start_count" -eq 0 ] && [ "$bashrc_end_count" -eq 0 ]; then if [ "$SHELL_PATH_NEEDED" -eq 1 ] \ || [ "$SHELL_SOURCE_NEEDED" -eq 1 ]; then SHELL_SETUP_NEEDED=1 fi elif [ "$bashrc_start_count" -eq 1 ] \ && [ "$bashrc_end_count" -eq 1 ] \ && [ "$SHELL_PATH_NEEDED" -eq 0 ] \ && { [ "$BASH_CUSTOM_HAS_MODULE" -eq 1 ] \ || grep -Fq 'proxy-client/shell.bash' "$HOME/.bashrc"; }; then : else SHELL_BLOCK_CONFLICT=1 fi fi conflicts=() missing_targets=0 stow_ignore_args=() PARENT_DIRS=( "$HOME/.local" "$HOME/.local/bin" "$HOME/.config" "$HOME/.config/proxy-client" ) for parent_dir in "${PARENT_DIRS[@]}"; do if { [ -e "$parent_dir" ] || [ -L "$parent_dir" ]; } \ && { [ ! -d "$parent_dir" ] || [ -L "$parent_dir" ]; }; then conflicts+=("$parent_dir") fi done for index in "${!TARGETS[@]}"; do target="${TARGETS[$index]}" source_path="${SOURCES[$index]}" if [ -e "$target" ] || [ -L "$target" ]; then if [ ! -L "$target" ] \ || [ "$(readlink -f "$target" 2>/dev/null || true)" != "$source_path" ]; then conflicts+=("$target") else stow_ignore_args+=("--ignore=${STOW_IGNORE_PATTERNS[$index]}") fi else missing_targets=$((missing_targets + 1)) fi done if [ "$SHELL_SETUP_NEEDED" -eq 1 ] \ && { [ -e "$HOME/.bashrc" ] || [ -L "$HOME/.bashrc" ]; } \ && [ ! -f "$HOME/.bashrc" ]; then conflicts+=("$HOME/.bashrc") fi if [ "$SHELL_BLOCK_CONFLICT" -eq 1 ]; then conflicts+=("$HOME/.bashrc") fi if [ "${#conflicts[@]}" -gt 0 ]; then echo "Ошибка: найдены конфликтующие пути:" >&2 printf ' %s\n' "${conflicts[@]}" >&2 echo "Разберите их вручную и повторите установку." >&2 exit 1 fi mkdir -p "$HOME/.local/bin" "$HOME/.config/proxy-client" if command -v "$STOW_BIN" >/dev/null 2>&1; then echo "Установка с помощью Stow." if [ "$missing_targets" -gt 0 ]; then "$STOW_BIN" --dir="$(dirname "$PACKAGE_DIR")" --target="$HOME" \ "${stow_ignore_args[@]}" \ "$(basename "$PACKAGE_DIR")" fi else echo "Установка без Stow: создаю символические ссылки напрямую." for index in "${!TARGETS[@]}"; do target="${TARGETS[$index]}" source_path="${SOURCES[$index]}" if [ ! -L "$target" ]; then ln -s "$source_path" "$target" fi done fi "$HOME/.local/bin/proxy-client" --help >/dev/null bash -n "$HOME/.config/proxy-client/shell.bash" if [ "$SHELL_SETUP_NEEDED" -eq 1 ]; then cat >> "$HOME/.bashrc" <<'EOF' # >>> proxy-client >>> EOF if [ "$SHELL_PATH_NEEDED" -eq 1 ]; then cat >> "$HOME/.bashrc" <<'EOF' case ":$PATH:" in *":$HOME/.local/bin:"*) ;; *) export PATH="$HOME/.local/bin:$PATH" ;; esac EOF fi if [ "$SHELL_SOURCE_NEEDED" -eq 1 ]; then cat >> "$HOME/.bashrc" <<'EOF' [ -f "$HOME/.config/proxy-client/shell.bash" ] && source "$HOME/.config/proxy-client/shell.bash" EOF fi cat >> "$HOME/.bashrc" <<'EOF' # <<< proxy-client <<< EOF elif [ "$SETUP_SHELL" -eq 0 ]; then echo "Настройка Bash пропущена (--no-shell-setup)." fi if [ "$SETUP_SHELL" -eq 1 ]; then RELOAD_COMMAND='source ~/.bashrc' else RELOAD_COMMAND='source ~/.config/proxy-client/shell.bash' fi cat <