From 3c111887d15bac95fbcd7b12d469f8e0817c3d26 Mon Sep 17 00:00:00 2001 From: PTah Date: Sun, 21 Jun 2026 19:46:41 +1000 Subject: [PATCH] =?UTF-8?q?fix:=20macOS=20install=20=E2=80=94=20bash=203.2?= =?UTF-8?q?,=20remotes=20=D0=B8=20awk=20=D0=B4=D0=BB=D1=8F=20SSH=20config?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit setup-git-ssh.sh работает без declare -A; Set-GitRemotes не дублирует .git и не падает на пустом legacy; shell-скрипты executable. --- .gitignore | 2 + init-cursor.sh | 0 install.sh | 0 scripts/Set-GitRemotes.sh | 27 ++++---- scripts/invoke-machine-bootstrap.sh | 0 scripts/register-gitea-ssh-keys.sh | 0 scripts/setup-git-ssh.sh | 98 ++++++++++++++++++++--------- 7 files changed, 86 insertions(+), 41 deletions(-) create mode 100644 .gitignore mode change 100644 => 100755 init-cursor.sh mode change 100644 => 100755 install.sh mode change 100644 => 100755 scripts/invoke-machine-bootstrap.sh mode change 100644 => 100755 scripts/register-gitea-ssh-keys.sh diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..bbf8145 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +.cursor/ +.cursorignore diff --git a/init-cursor.sh b/init-cursor.sh old mode 100644 new mode 100755 diff --git a/install.sh b/install.sh old mode 100644 new mode 100755 diff --git a/scripts/Set-GitRemotes.sh b/scripts/Set-GitRemotes.sh index 7492b4b..a01c874 100644 --- a/scripts/Set-GitRemotes.sh +++ b/scripts/Set-GitRemotes.sh @@ -16,9 +16,11 @@ if ! git rev-parse --is-inside-work-tree >/dev/null 2>&1; then fi repo_name_from_url() { - local url="$1" - if [[ "$url" =~ /([^/]+)(\.git)?/?$ ]]; then - echo "${BASH_REMATCH[1]}" + local url="$1" name="" + if [[ "$url" =~ /([^/]+)/?$ ]]; then + name="${BASH_REMATCH[1]}" + name="${name%.git}" + printf '%s\n' "$name" fi } @@ -32,6 +34,7 @@ if [[ -z "$repo_name" ]]; then done fi repo_name="${repo_name:-$(basename "$(git rev-parse --show-toplevel)")}" +repo_name="${repo_name%.git}" home_url="ssh://git@git.papatramp.ru:2222/${OWNER}/${repo_name}.git" kalinamall_url="ssh://git@git.kalinamall.ru:2222/${OWNER}/${repo_name}.git" github_url="git@github.com:${GITHUB_ORG}/${repo_name}.git" @@ -83,14 +86,16 @@ set_remote() { *) legacy=() ;; esac - for old in "${legacy[@]}"; do - if git remote | grep -Fxq "$old"; then - git remote rename "$old" "$name" - git remote set-url "$name" "$url" - log_ok "remote $old renamed to $name -> $url" - return 0 - fi - done + if ((${#legacy[@]} > 0)); then + for old in "${legacy[@]}"; do + if git remote | grep -Fxq "$old"; then + git remote rename "$old" "$name" + git remote set-url "$name" "$url" + log_ok "remote $old renamed to $name -> $url" + return 0 + fi + done + fi git remote add "$name" "$url" log_ok "remote $name added -> $url" diff --git a/scripts/invoke-machine-bootstrap.sh b/scripts/invoke-machine-bootstrap.sh old mode 100644 new mode 100755 diff --git a/scripts/register-gitea-ssh-keys.sh b/scripts/register-gitea-ssh-keys.sh old mode 100644 new mode 100755 diff --git a/scripts/setup-git-ssh.sh b/scripts/setup-git-ssh.sh index dc14a72..e17deb0 100644 --- a/scripts/setup-git-ssh.sh +++ b/scripts/setup-git-ssh.sh @@ -1,5 +1,6 @@ #!/usr/bin/env bash # Генерирует SSH-ключи и ~/.ssh/config для Git-хостов из local/git-ssh-hosts.conf. +# Совместим с macOS bash 3.2 (без declare -A). set -euo pipefail CONFIG_DIR="${CONFIG_DIR:-$HOME/CursorRules/local}" @@ -10,6 +11,28 @@ log_step() { printf '[*] %s\n' "$1"; } log_ok() { printf '[+] %s\n' "$1"; } log_warn() { printf '[!] %s\n' "$1"; } +cfg_key() { printf '%s' "$1" | tr '.-' '__'; } + +set_profile_field() { + local profile="$1" field="$2" value="$3" + eval "__pf_$(cfg_key "$profile")_${field}=\"\$value\"" +} + +get_profile_field() { + local profile="$1" field="$2" + eval "printf '%s' \"\${__pf_$(cfg_key "$profile")_${field}:-}\"" +} + +set_host_field() { + local host="$1" field="$2" value="$3" + eval "__hf_$(cfg_key "$host")_${field}=\"\$value\"" +} + +get_host_field() { + local host="$1" field="$2" + eval "printf '%s' \"\${__hf_$(cfg_key "$host")_${field}:-}\"" +} + if [[ ! -f "$HOSTS_CONFIG" ]]; then echo "Config not found: $HOSTS_CONFIG" >&2 exit 1 @@ -20,9 +43,8 @@ SSH_CONFIG="$SSH_DIR/config" mkdir -p "$SSH_DIR" chmod 700 "$SSH_DIR" -declare -A PROFILE_KEYNAME PROFILE_COMMENT PROFILE_GITEA -declare -A HOST_HOSTNAME HOST_PORT HOST_USER HOST_PROFILE - +PROFILE_LIST=() +HOST_LIST=() current_section='' current_name='' @@ -34,12 +56,14 @@ while IFS= read -r line || [[ -n "$line" ]]; do if [[ "$line" =~ ^\[profile:(.+)\]$ ]]; then current_section='profile' current_name="${BASH_REMATCH[1]}" + PROFILE_LIST+=("$current_name") continue fi if [[ "$line" =~ ^\[host:(.+)\]$ ]]; then current_section='host' current_name="${BASH_REMATCH[1]}" - HOST_HOSTNAME["$current_name"]='' + HOST_LIST+=("$current_name") + set_host_field "$current_name" HostName '' continue fi if [[ "$line" != *=* ]]; then @@ -53,29 +77,31 @@ while IFS= read -r line || [[ -n "$line" ]]; do if [[ "$current_section" == 'profile' ]]; then case "$key" in - KeyName) PROFILE_KEYNAME["$current_name"]="$value" ;; - KeyComment) PROFILE_COMMENT["$current_name"]="$value" ;; - GiteaConfig) PROFILE_GITEA["$current_name"]="$value" ;; + KeyName|KeyComment|GiteaConfig) set_profile_field "$current_name" "$key" "$value" ;; esac elif [[ "$current_section" == 'host' ]]; then case "$key" in - HostName) HOST_HOSTNAME["$current_name"]="$value" ;; - Port) HOST_PORT["$current_name"]="$value" ;; - User) HOST_USER["$current_name"]="$value" ;; - Profile) HOST_PROFILE["$current_name"]="$value" ;; + HostName|Port|User|Profile) set_host_field "$current_name" "$key" "$value" ;; esac fi done < "$HOSTS_CONFIG" -declare -A SEEN_KEYS +KEYS_SEEN=() -for profile in "${!PROFILE_KEYNAME[@]}"; do - key_name="${PROFILE_KEYNAME[$profile]}" - [[ -z "$key_name" || -n "${SEEN_KEYS[$key_name]:-}" ]] && continue - SEEN_KEYS["$key_name"]=1 +for profile in "${PROFILE_LIST[@]}"; do + key_name="$(get_profile_field "$profile" KeyName)" + [[ -z "$key_name" ]] && continue + + seen=0 + for existing in "${KEYS_SEEN[@]:-}"; do + [[ "$existing" == "$key_name" ]] && seen=1 && break + done + [[ "$seen" -eq 1 ]] && continue + KEYS_SEEN+=("$key_name") key_path="$SSH_DIR/$key_name" - comment="${PROFILE_COMMENT[$profile]:-$key_name}" + comment="$(get_profile_field "$profile" KeyComment)" + comment="${comment:-$key_name}" if [[ ! -f "$key_path" ]]; then log_step "Generating $key_name" @@ -96,25 +122,33 @@ update_ssh_block() { local block="$2" local begin="# BEGIN Setup-SshAccess:$host_alias" local end="# END Setup-SshAccess:$host_alias" - local tmp + local tmp block_file tmp="$(mktemp)" + block_file="$(mktemp)" + + printf '%s\n' "$block" > "$block_file" if [[ -f "$SSH_CONFIG" ]]; then - awk -v begin="$begin" -v end="$end" -v block="$block" ' + awk -v begin="$begin" -v end="$end" -v blockfile="$block_file" ' $0 == begin { skip=1; next } $0 == end { skip=0; next } skip { next } { print } END { - if (block != "") { - print block + if (blockfile != "") { + while ((getline line < blockfile) > 0) { + print line + } + close(blockfile) } } - ' block="$block" "$SSH_CONFIG" > "$tmp" + ' "$SSH_CONFIG" > "$tmp" else - printf '%s\n' "$block" > "$tmp" + cp "$block_file" "$tmp" fi + rm -f "$block_file" + if [[ "$WHAT_IF" != '1' ]]; then mv "$tmp" "$SSH_CONFIG" chmod 600 "$SSH_CONFIG" @@ -123,9 +157,13 @@ update_ssh_block() { fi } -for host_alias in $(printf '%s\n' "${!HOST_HOSTNAME[@]}" | sort); do - profile="${HOST_PROFILE[$host_alias]:-}" - key_name="${PROFILE_KEYNAME[$profile]:-}" +IFS=$'\n' +sorted_hosts=($(printf '%s\n' "${HOST_LIST[@]}" | sort)) +unset IFS + +for host_alias in "${sorted_hosts[@]}"; do + profile="$(get_host_field "$host_alias" Profile)" + key_name="$(get_profile_field "$profile" KeyName)" if [[ -z "$profile" || -z "$key_name" ]]; then echo "Host $host_alias: unknown profile" >&2 exit 1 @@ -133,9 +171,9 @@ for host_alias in $(printf '%s\n' "${!HOST_HOSTNAME[@]}" | sort); do block="# BEGIN Setup-SshAccess:$host_alias Host $host_alias - HostName ${HOST_HOSTNAME[$host_alias]} - User ${HOST_USER[$host_alias]} - Port ${HOST_PORT[$host_alias]} + HostName $(get_host_field "$host_alias" HostName) + User $(get_host_field "$host_alias" User) + Port $(get_host_field "$host_alias" Port) IdentityFile ~/.ssh/$key_name IdentitiesOnly yes AddKeysToAgent yes @@ -152,7 +190,7 @@ done if [[ "$WHAT_IF" != '1' ]]; then eval "$(ssh-agent -s)" >/dev/null - for key_name in "${!SEEN_KEYS[@]}"; do + for key_name in "${KEYS_SEEN[@]:-}"; do [[ -f "$SSH_DIR/$key_name" ]] && ssh-add "$SSH_DIR/$key_name" >/dev/null 2>&1 || true done fi