summaryrefslogtreecommitdiff
path: root/ar/.local/bin/ghswh
blob: 3faec4836575a5e95e3af284de45f7df8e6c8e84 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
#!/bin/sh
# POSIX compliant script to switch GitHub CLI accounts using fzf

set -e

# Check if gh is installed
if ! command -v gh >/dev/null 2>&1; then
  printf "Error: gh (GitHub CLI) is not installed\n" >&2
  exit 1
fi

# Check if fzf is installed
if ! command -v fzf >/dev/null 2>&1; then
  printf "Error: fzf is not installed\n" >&2
  exit 1
fi

# Get authentication status and parse accounts with active status
# Parse the full status output to get hostname, username, login status, and active status
status_output=$(gh auth status 2>&1)

# Use awk to parse multi-line account information and get both active and inactive accounts
parsed_data=$(printf "%s\n" "$status_output" | awk '
    /Logged in to|Failed to log in to/ {
        # Extract hostname and username
        match($0, /(Logged in to|Failed to log in to) ([^ ]+) account ([^ ]+)/, arr)
        hostname = arr[2]
        username = arr[3]
        logged_status = (arr[1] == "Logged in to" ? "✓" : "✗")
        account_key = username "@" hostname
        accounts[account_key] = logged_status
        account_order[++order_count] = account_key
    }
    /Active account: true/ {
        # Mark the previous account as active
        if (account_key != "") {
            active_account = account_key
        }
    }
    END {
        # Print active account on first line
        print "ACTIVE:" active_account
        # Print other accounts
        for (i = 1; i <= order_count; i++) {
            key = account_order[i]
            # Skip the active account
            if (key == active_account) continue
            status = accounts[key]
            print key " [" status "]"
        }
    }
')

# Extract active account and other accounts
current_account=$(printf "%s\n" "$parsed_data" | grep "^ACTIVE:" | cut -d: -f2)
display_accounts=$(printf "%s\n" "$parsed_data" | grep -v "^ACTIVE:")

if [ -z "$display_accounts" ]; then
  printf "No other accounts found. You are already on the only account.\n" >&2
  exit 1
fi

# Use fzf to select account with current account in header
selected=$(printf "%s\n" "$display_accounts" | fzf --prompt="Switch to: " --header="*$current_account" --height=40% --border --reverse)

if [ -z "$selected" ]; then
  printf "No account selected\n" >&2
  exit 1
fi

# Extract hostname and username from selection
# Remove status indicator: "username@hostname [✓]" -> "username@hostname"
selected_clean=$(printf "%s" "$selected" | sed 's/ \[.*\]//')
hostname=$(printf "%s" "$selected_clean" | cut -d'@' -f2)
username=$(printf "%s" "$selected_clean" | cut -d'@' -f1)

printf "Switching to %s on %s...\n" "$username" "$hostname"

# Switch to selected account using gh auth switch
gh auth switch --hostname "$hostname" --user "$username"

printf "Successfully switched to %s@%s\n" "$username" "$hostname"