fix: macOS install — bash 3.2, remotes и awk для SSH config
setup-git-ssh.sh работает без declare -A; Set-GitRemotes не дублирует .git и не падает на пустом legacy; shell-скрипты executable.
This commit is contained in:
@@ -0,0 +1,2 @@
|
|||||||
|
.cursor/
|
||||||
|
.cursorignore
|
||||||
Regular → Executable
Regular → Executable
@@ -16,9 +16,11 @@ if ! git rev-parse --is-inside-work-tree >/dev/null 2>&1; then
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
repo_name_from_url() {
|
repo_name_from_url() {
|
||||||
local url="$1"
|
local url="$1" name=""
|
||||||
if [[ "$url" =~ /([^/]+)(\.git)?/?$ ]]; then
|
if [[ "$url" =~ /([^/]+)/?$ ]]; then
|
||||||
echo "${BASH_REMATCH[1]}"
|
name="${BASH_REMATCH[1]}"
|
||||||
|
name="${name%.git}"
|
||||||
|
printf '%s\n' "$name"
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -32,6 +34,7 @@ if [[ -z "$repo_name" ]]; then
|
|||||||
done
|
done
|
||||||
fi
|
fi
|
||||||
repo_name="${repo_name:-$(basename "$(git rev-parse --show-toplevel)")}"
|
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"
|
home_url="ssh://git@git.papatramp.ru:2222/${OWNER}/${repo_name}.git"
|
||||||
kalinamall_url="ssh://git@git.kalinamall.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"
|
github_url="git@github.com:${GITHUB_ORG}/${repo_name}.git"
|
||||||
@@ -83,6 +86,7 @@ set_remote() {
|
|||||||
*) legacy=() ;;
|
*) legacy=() ;;
|
||||||
esac
|
esac
|
||||||
|
|
||||||
|
if ((${#legacy[@]} > 0)); then
|
||||||
for old in "${legacy[@]}"; do
|
for old in "${legacy[@]}"; do
|
||||||
if git remote | grep -Fxq "$old"; then
|
if git remote | grep -Fxq "$old"; then
|
||||||
git remote rename "$old" "$name"
|
git remote rename "$old" "$name"
|
||||||
@@ -91,6 +95,7 @@ set_remote() {
|
|||||||
return 0
|
return 0
|
||||||
fi
|
fi
|
||||||
done
|
done
|
||||||
|
fi
|
||||||
|
|
||||||
git remote add "$name" "$url"
|
git remote add "$name" "$url"
|
||||||
log_ok "remote $name added -> $url"
|
log_ok "remote $name added -> $url"
|
||||||
|
|||||||
Regular → Executable
Regular → Executable
+68
-30
@@ -1,5 +1,6 @@
|
|||||||
#!/usr/bin/env bash
|
#!/usr/bin/env bash
|
||||||
# Генерирует SSH-ключи и ~/.ssh/config для Git-хостов из local/git-ssh-hosts.conf.
|
# Генерирует SSH-ключи и ~/.ssh/config для Git-хостов из local/git-ssh-hosts.conf.
|
||||||
|
# Совместим с macOS bash 3.2 (без declare -A).
|
||||||
set -euo pipefail
|
set -euo pipefail
|
||||||
|
|
||||||
CONFIG_DIR="${CONFIG_DIR:-$HOME/CursorRules/local}"
|
CONFIG_DIR="${CONFIG_DIR:-$HOME/CursorRules/local}"
|
||||||
@@ -10,6 +11,28 @@ log_step() { printf '[*] %s\n' "$1"; }
|
|||||||
log_ok() { printf '[+] %s\n' "$1"; }
|
log_ok() { printf '[+] %s\n' "$1"; }
|
||||||
log_warn() { 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
|
if [[ ! -f "$HOSTS_CONFIG" ]]; then
|
||||||
echo "Config not found: $HOSTS_CONFIG" >&2
|
echo "Config not found: $HOSTS_CONFIG" >&2
|
||||||
exit 1
|
exit 1
|
||||||
@@ -20,9 +43,8 @@ SSH_CONFIG="$SSH_DIR/config"
|
|||||||
mkdir -p "$SSH_DIR"
|
mkdir -p "$SSH_DIR"
|
||||||
chmod 700 "$SSH_DIR"
|
chmod 700 "$SSH_DIR"
|
||||||
|
|
||||||
declare -A PROFILE_KEYNAME PROFILE_COMMENT PROFILE_GITEA
|
PROFILE_LIST=()
|
||||||
declare -A HOST_HOSTNAME HOST_PORT HOST_USER HOST_PROFILE
|
HOST_LIST=()
|
||||||
|
|
||||||
current_section=''
|
current_section=''
|
||||||
current_name=''
|
current_name=''
|
||||||
|
|
||||||
@@ -34,12 +56,14 @@ while IFS= read -r line || [[ -n "$line" ]]; do
|
|||||||
if [[ "$line" =~ ^\[profile:(.+)\]$ ]]; then
|
if [[ "$line" =~ ^\[profile:(.+)\]$ ]]; then
|
||||||
current_section='profile'
|
current_section='profile'
|
||||||
current_name="${BASH_REMATCH[1]}"
|
current_name="${BASH_REMATCH[1]}"
|
||||||
|
PROFILE_LIST+=("$current_name")
|
||||||
continue
|
continue
|
||||||
fi
|
fi
|
||||||
if [[ "$line" =~ ^\[host:(.+)\]$ ]]; then
|
if [[ "$line" =~ ^\[host:(.+)\]$ ]]; then
|
||||||
current_section='host'
|
current_section='host'
|
||||||
current_name="${BASH_REMATCH[1]}"
|
current_name="${BASH_REMATCH[1]}"
|
||||||
HOST_HOSTNAME["$current_name"]=''
|
HOST_LIST+=("$current_name")
|
||||||
|
set_host_field "$current_name" HostName ''
|
||||||
continue
|
continue
|
||||||
fi
|
fi
|
||||||
if [[ "$line" != *=* ]]; then
|
if [[ "$line" != *=* ]]; then
|
||||||
@@ -53,29 +77,31 @@ while IFS= read -r line || [[ -n "$line" ]]; do
|
|||||||
|
|
||||||
if [[ "$current_section" == 'profile' ]]; then
|
if [[ "$current_section" == 'profile' ]]; then
|
||||||
case "$key" in
|
case "$key" in
|
||||||
KeyName) PROFILE_KEYNAME["$current_name"]="$value" ;;
|
KeyName|KeyComment|GiteaConfig) set_profile_field "$current_name" "$key" "$value" ;;
|
||||||
KeyComment) PROFILE_COMMENT["$current_name"]="$value" ;;
|
|
||||||
GiteaConfig) PROFILE_GITEA["$current_name"]="$value" ;;
|
|
||||||
esac
|
esac
|
||||||
elif [[ "$current_section" == 'host' ]]; then
|
elif [[ "$current_section" == 'host' ]]; then
|
||||||
case "$key" in
|
case "$key" in
|
||||||
HostName) HOST_HOSTNAME["$current_name"]="$value" ;;
|
HostName|Port|User|Profile) set_host_field "$current_name" "$key" "$value" ;;
|
||||||
Port) HOST_PORT["$current_name"]="$value" ;;
|
|
||||||
User) HOST_USER["$current_name"]="$value" ;;
|
|
||||||
Profile) HOST_PROFILE["$current_name"]="$value" ;;
|
|
||||||
esac
|
esac
|
||||||
fi
|
fi
|
||||||
done < "$HOSTS_CONFIG"
|
done < "$HOSTS_CONFIG"
|
||||||
|
|
||||||
declare -A SEEN_KEYS
|
KEYS_SEEN=()
|
||||||
|
|
||||||
for profile in "${!PROFILE_KEYNAME[@]}"; do
|
for profile in "${PROFILE_LIST[@]}"; do
|
||||||
key_name="${PROFILE_KEYNAME[$profile]}"
|
key_name="$(get_profile_field "$profile" KeyName)"
|
||||||
[[ -z "$key_name" || -n "${SEEN_KEYS[$key_name]:-}" ]] && continue
|
[[ -z "$key_name" ]] && continue
|
||||||
SEEN_KEYS["$key_name"]=1
|
|
||||||
|
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"
|
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
|
if [[ ! -f "$key_path" ]]; then
|
||||||
log_step "Generating $key_name"
|
log_step "Generating $key_name"
|
||||||
@@ -96,25 +122,33 @@ update_ssh_block() {
|
|||||||
local block="$2"
|
local block="$2"
|
||||||
local begin="# BEGIN Setup-SshAccess:$host_alias"
|
local begin="# BEGIN Setup-SshAccess:$host_alias"
|
||||||
local end="# END Setup-SshAccess:$host_alias"
|
local end="# END Setup-SshAccess:$host_alias"
|
||||||
local tmp
|
local tmp block_file
|
||||||
tmp="$(mktemp)"
|
tmp="$(mktemp)"
|
||||||
|
block_file="$(mktemp)"
|
||||||
|
|
||||||
|
printf '%s\n' "$block" > "$block_file"
|
||||||
|
|
||||||
if [[ -f "$SSH_CONFIG" ]]; then
|
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 == begin { skip=1; next }
|
||||||
$0 == end { skip=0; next }
|
$0 == end { skip=0; next }
|
||||||
skip { next }
|
skip { next }
|
||||||
{ print }
|
{ print }
|
||||||
END {
|
END {
|
||||||
if (block != "") {
|
if (blockfile != "") {
|
||||||
print block
|
while ((getline line < blockfile) > 0) {
|
||||||
|
print line
|
||||||
|
}
|
||||||
|
close(blockfile)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
' block="$block" "$SSH_CONFIG" > "$tmp"
|
' "$SSH_CONFIG" > "$tmp"
|
||||||
else
|
else
|
||||||
printf '%s\n' "$block" > "$tmp"
|
cp "$block_file" "$tmp"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
rm -f "$block_file"
|
||||||
|
|
||||||
if [[ "$WHAT_IF" != '1' ]]; then
|
if [[ "$WHAT_IF" != '1' ]]; then
|
||||||
mv "$tmp" "$SSH_CONFIG"
|
mv "$tmp" "$SSH_CONFIG"
|
||||||
chmod 600 "$SSH_CONFIG"
|
chmod 600 "$SSH_CONFIG"
|
||||||
@@ -123,9 +157,13 @@ update_ssh_block() {
|
|||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
for host_alias in $(printf '%s\n' "${!HOST_HOSTNAME[@]}" | sort); do
|
IFS=$'\n'
|
||||||
profile="${HOST_PROFILE[$host_alias]:-}"
|
sorted_hosts=($(printf '%s\n' "${HOST_LIST[@]}" | sort))
|
||||||
key_name="${PROFILE_KEYNAME[$profile]:-}"
|
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
|
if [[ -z "$profile" || -z "$key_name" ]]; then
|
||||||
echo "Host $host_alias: unknown profile" >&2
|
echo "Host $host_alias: unknown profile" >&2
|
||||||
exit 1
|
exit 1
|
||||||
@@ -133,9 +171,9 @@ for host_alias in $(printf '%s\n' "${!HOST_HOSTNAME[@]}" | sort); do
|
|||||||
|
|
||||||
block="# BEGIN Setup-SshAccess:$host_alias
|
block="# BEGIN Setup-SshAccess:$host_alias
|
||||||
Host $host_alias
|
Host $host_alias
|
||||||
HostName ${HOST_HOSTNAME[$host_alias]}
|
HostName $(get_host_field "$host_alias" HostName)
|
||||||
User ${HOST_USER[$host_alias]}
|
User $(get_host_field "$host_alias" User)
|
||||||
Port ${HOST_PORT[$host_alias]}
|
Port $(get_host_field "$host_alias" Port)
|
||||||
IdentityFile ~/.ssh/$key_name
|
IdentityFile ~/.ssh/$key_name
|
||||||
IdentitiesOnly yes
|
IdentitiesOnly yes
|
||||||
AddKeysToAgent yes
|
AddKeysToAgent yes
|
||||||
@@ -152,7 +190,7 @@ done
|
|||||||
|
|
||||||
if [[ "$WHAT_IF" != '1' ]]; then
|
if [[ "$WHAT_IF" != '1' ]]; then
|
||||||
eval "$(ssh-agent -s)" >/dev/null
|
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
|
[[ -f "$SSH_DIR/$key_name" ]] && ssh-add "$SSH_DIR/$key_name" >/dev/null 2>&1 || true
|
||||||
done
|
done
|
||||||
fi
|
fi
|
||||||
|
|||||||
Reference in New Issue
Block a user