fix(install): исправлено владение каталогом .config

Зачем:
- GNU Stow сворачивал весь ~/.config в пакет zed и помещал рабочие настройки в репозиторий.

Что:
- добавлена ограниченная миграция старой ссылки с возвратом данных в домашний каталог;
- предотвращено повторное сворачивание ~/.config на свежей установке;
- добавлены проверки сохранности профиля, повторного запуска и чужих ссылок.

Проверка:
- bash tests/test_install.sh
- bash -n install.sh tests/test_install.sh
- git diff --check
This commit is contained in:
ddadmin committed 2026-07-21 08:29:52 -04:00
1 parent fd8210db71
commit e5323284a8
3 files changed
+231 -48

No files matched your search

+115 -1
View File
@@ -94,7 +94,7 @@ test_fresh_install_uses_home_target() {
home_dir="$fixture/home"
mkdir -p "$home_dir"
run_install "$repo_root" "$home_dir" env WSL_DISTRO_NAME= INSTALL_INTERACTIVE_MODE=never >/tmp/test-install.out
run_install "$repo_root" "$home_dir" env WSL_DISTRO_NAME= INSTALL_INTERACTIVE_MODE=never >"$fixture/install.out"
[ -L "$home_dir/.bash_custom" ] || fail "Expected .bash_custom symlink in HOME"
[ -x "$home_dir/.local/bin/xray-proxy" ] || fail "Expected executable xray-proxy CLI in HOME"
@@ -105,6 +105,116 @@ test_fresh_install_uses_home_target() {
assert_not_exists "$fixture/.bash_custom"
}
test_fresh_install_does_not_fold_config_into_zed() {
local fixture repo_root home_dir target expected
fixture="$(setup_fixture)"
repo_root="$fixture/repo"
home_dir="$fixture/home"
mkdir -p "$home_dir"
# Неполный клон: zed остаётся единственным stow-пакетом с каталогом .config.
mv "$repo_root/xray-proxy" "$fixture/xray-proxy-disabled"
run_install "$repo_root" "$home_dir" env WSL_DISTRO_NAME= INSTALL_INTERACTIVE_MODE=never >"$fixture/install.out"
[ -d "$home_dir/.config" ] || fail "Expected ~/.config directory"
[ ! -L "$home_dir/.config" ] || fail "Expected ~/.config to stay a real directory"
[ -L "$home_dir/.config/zed" ] || fail "Expected ~/.config/zed symlink"
target="$(readlink -f "$home_dir/.config/zed")"
expected="$(readlink -f "$repo_root/zed/.config/zed")"
[ "$target" = "$expected" ] || fail "~/.config/zed points to $target, expected $expected"
}
test_migrates_legacy_zed_config_symlink() {
local fixture repo_root home_dir legacy_config output mode
fixture="$(setup_fixture)"
repo_root="$fixture/repo"
home_dir="$fixture/home"
legacy_config="$repo_root/zed/.config"
mkdir -p "$home_dir" "$legacy_config/btop" "$legacy_config/xray-proxy"
printf '%s\n' 'btop settings' > "$legacy_config/btop/btop.conf"
printf '%s\n' 'VLESS_PROFILE_SENTINEL' > "$legacy_config/xray-proxy/default.url"
chmod 600 "$legacy_config/xray-proxy/default.url"
ln -s "$legacy_config" "$home_dir/.config"
if ! output="$(
run_install "$repo_root" "$home_dir" \
env WSL_DISTRO_NAME= INSTALL_INTERACTIVE_MODE=never
)"; then
fail "Expected legacy ~/.config migration to complete"
fi
[ -d "$home_dir/.config" ] || fail "Expected migrated ~/.config directory"
[ ! -L "$home_dir/.config" ] || fail "Expected migrated ~/.config to stop being a symlink"
[ -L "$home_dir/.config/zed" ] || fail "Expected managed ~/.config/zed symlink"
[ -d "$home_dir/.config/btop" ] || fail "Expected btop config to be migrated"
[ ! -L "$home_dir/.config/btop" ] || fail "Expected btop config outside the repository"
[ -f "$home_dir/.config/xray-proxy/default.url" ] || fail "Expected profile to be migrated"
[ ! -L "$home_dir/.config/xray-proxy/default.url" ] || fail "Expected profile outside the repository"
mode="$(stat -c '%a' "$home_dir/.config/xray-proxy/default.url")"
[ "$mode" = "600" ] || fail "Expected profile mode 600, got $mode"
assert_file_contains "$home_dir/.config/xray-proxy/default.url" "VLESS_PROFILE_SENTINEL"
assert_not_exists "$legacy_config/btop"
assert_not_exists "$legacy_config/xray-proxy"
if printf '%s' "$output" | grep -Fq 'VLESS_PROFILE_SENTINEL'; then
fail "Secret profile leaked into install output"
fi
run_install "$repo_root" "$home_dir" env WSL_DISTRO_NAME= INSTALL_INTERACTIVE_MODE=never >"$fixture/install.out"
assert_file_contains "$home_dir/.config/xray-proxy/default.url" "VLESS_PROFILE_SENTINEL"
}
test_stops_legacy_migration_when_listing_fails() {
local fixture repo_root home_dir legacy_config target expected
fixture="$(setup_fixture)"
repo_root="$fixture/repo"
home_dir="$fixture/home"
legacy_config="$repo_root/zed/.config"
mkdir -p "$home_dir" "$legacy_config/xray-proxy"
printf '%s\n' 'VLESS_PROFILE_SENTINEL' > "$legacy_config/xray-proxy/default.url"
ln -s "$legacy_config" "$home_dir/.config"
cat > "$fixture/bin/find" <<'EOF'
#!/usr/bin/env bash
exit 7
EOF
chmod +x "$fixture/bin/find"
if run_install "$repo_root" "$home_dir" \
env PATH="$fixture/bin:$PATH" WSL_DISTRO_NAME= INSTALL_INTERACTIVE_MODE=never \
>"$fixture/install.out" 2>&1; then
fail "Expected migration to stop when legacy config listing fails"
fi
[ -L "$home_dir/.config" ] || fail "Expected legacy ~/.config symlink after listing failure"
target="$(readlink -f "$home_dir/.config")"
expected="$(readlink -f "$legacy_config")"
[ "$target" = "$expected" ] || fail "Legacy ~/.config target changed after listing failure"
assert_file_contains "$legacy_config/xray-proxy/default.url" "VLESS_PROFILE_SENTINEL"
}
test_does_not_migrate_unrelated_config_symlink() {
local fixture repo_root home_dir unrelated_config target expected
fixture="$(setup_fixture)"
repo_root="$fixture/repo"
home_dir="$fixture/home"
unrelated_config="$fixture/unrelated-config"
mkdir -p "$home_dir" "$unrelated_config"
printf '%s\n' 'keep me' > "$unrelated_config/local.conf"
ln -s "$unrelated_config" "$home_dir/.config"
# Stow вправе сообщить о конфликте, но установщик не должен раскрывать
# произвольную ссылку и переносить чужие данные.
run_install "$repo_root" "$home_dir" \
env WSL_DISTRO_NAME= INSTALL_INTERACTIVE_MODE=never >"$fixture/install.out" 2>&1 || true
[ -L "$home_dir/.config" ] || fail "Expected unrelated ~/.config symlink to be preserved"
target="$(readlink -f "$home_dir/.config")"
expected="$(readlink -f "$unrelated_config")"
[ "$target" = "$expected" ] || fail "Unrelated ~/.config symlink target changed"
assert_file_contains "$unrelated_config/local.conf" "keep me"
}
test_settings_local_is_symlinked_to_repo() {
local fixture repo_root home_dir
fixture="$(setup_fixture)"
@@ -385,6 +495,10 @@ main() {
command -v stow >/dev/null 2>&1 || fail "stow is required for tests"
test_fresh_install_uses_home_target
test_fresh_install_does_not_fold_config_into_zed
test_migrates_legacy_zed_config_symlink
test_stops_legacy_migration_when_listing_fails
test_does_not_migrate_unrelated_config_symlink
test_settings_local_is_symlinked_to_repo
test_settings_local_backup_on_existing_file
test_settings_local_dir_is_skipped