11#! /usr/bin/env bash
22
3+ # Color codes for better output
4+ RED=' \033[0;31m'
5+ GREEN=' \033[0;32m'
6+ YELLOW=' \033[1;33m'
7+ BLUE=' \033[0;34m'
8+ PURPLE=' \033[0;35m'
9+ CYAN=' \033[0;36m'
10+ WHITE=' \033[1;37m'
11+ NC=' \033[0m' # No Color
12+
13+ # Emojis for better visual feedback
14+ CHECK=" ✅"
15+ CROSS=" ❌"
16+ ROCKET=" 🚀"
17+ EYES=" 👀"
18+ COMMENT=" 💬"
19+ REACTION=" 😊"
20+
21+ # Function to print colored output
22+ print_status () {
23+ echo -e " ${BLUE}${CHECK}${NC} $1 "
24+ }
25+
26+ print_error () {
27+ echo -e " ${RED}${CROSS}${NC} $1 "
28+ }
29+
30+ print_info () {
31+ echo -e " ${CYAN}${EYES}${NC} $1 "
32+ }
33+
34+ print_success () {
35+ echo -e " ${GREEN}${ROCKET}${NC} $1 "
36+ }
37+
338# Check if PR number is provided
439if [ -z " $1 " ]; then
5- echo " Usage: gh react <pr_number>"
40+ echo -e " ${YELLOW} Usage:${NC} ${WHITE} gh react <pr_number>${NC} "
41+ echo " "
42+ echo " Examples:"
43+ echo " gh react 23 # React to comments in PR #23"
44+ echo " gh react 156 # React to comments in PR #156"
645 exit 1
746fi
847
948PR_NUMBER=$1
10- echo " Fetching comments for PR #$PR_NUMBER ..."
49+ echo -e " ${PURPLE}${COMMENT} GitHub PR Reaction Tool${NC} "
50+ echo " ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
51+ print_info " Fetching comments for PR #${WHITE} $PR_NUMBER ${NC} ..."
1152
1253OWNER=$( gh repo view --json owner -q " .owner.login" )
1354REPO=$( gh repo view --json name -q " .name" )
1455
56+ print_info " Repository: ${WHITE} $OWNER /$REPO ${NC} "
57+
1558# Check if PR exists first
16- echo " Checking if PR #$PR_NUMBER exists ..."
59+ print_info " Validating PR #${WHITE} $ PR_NUMBER${NC} ..."
1760PR_EXISTS=$( gh pr view $PR_NUMBER --json number 2> /dev/null)
1861if [ -z " $PR_EXISTS " ]; then
19- echo " Error: PR #$PR_NUMBER does not exist or you don't have access to it."
62+ print_error " PR #$PR_NUMBER does not exist or you don't have access to it."
63+ echo " "
64+ echo " 💡 ${YELLOW} Tip:${NC} Make sure you're in the correct repository and the PR number exists."
2065 exit 1
2166fi
67+ print_status " PR #$PR_NUMBER found!"
2268
2369# Use gh api to get raw comments for the issue/PR
24- echo " Fetching comments..."
70+ echo " "
71+ print_info " Gathering all comments and content..."
2572
2673# Get the PR description/body itself
2774PR_BODY=$( gh api repos/$OWNER /$REPO /pulls/$PR_NUMBER --jq ' select(.body != null and .body != "") | "PR_BODY|\(.number)|\(.user.login): \(.body)"' 2> /dev/null || echo " " )
@@ -37,70 +84,178 @@ REVIEW_SUMMARY_COMMENTS=$(gh api repos/$OWNER/$REPO/pulls/$PR_NUMBER/reviews --j
3784
3885# Combine all comments
3986ALL_COMMENTS=" "
87+ COMMENT_COUNT=0
88+
4089if [ ! -z " $PR_BODY " ]; then
4190 ALL_COMMENTS=" $ALL_COMMENTS$PR_BODY "
91+ COMMENT_COUNT=$(( COMMENT_COUNT + 1 ))
4292fi
4393if [ ! -z " $ISSUE_COMMENTS " ]; then
4494 if [ ! -z " $ALL_COMMENTS " ]; then
4595 ALL_COMMENTS=" $ALL_COMMENTS
4696"
4797 fi
4898 ALL_COMMENTS=" $ALL_COMMENTS$ISSUE_COMMENTS "
99+ COMMENT_COUNT=$(( COMMENT_COUNT + $(echo "$ISSUE_COMMENTS " | wc - l)) )
49100fi
50101if [ ! -z " $REVIEW_COMMENTS " ]; then
51102 if [ ! -z " $ALL_COMMENTS " ]; then
52103 ALL_COMMENTS=" $ALL_COMMENTS
53104"
54105 fi
55106 ALL_COMMENTS=" $ALL_COMMENTS$REVIEW_COMMENTS "
107+ COMMENT_COUNT=$(( COMMENT_COUNT + $(echo "$REVIEW_COMMENTS " | wc - l)) )
56108fi
57109if [ ! -z " $REVIEW_SUMMARY_COMMENTS " ]; then
58110 if [ ! -z " $ALL_COMMENTS " ]; then
59111 ALL_COMMENTS=" $ALL_COMMENTS
60112"
61113 fi
62114 ALL_COMMENTS=" $ALL_COMMENTS$REVIEW_SUMMARY_COMMENTS "
115+ COMMENT_COUNT=$(( COMMENT_COUNT + $(echo "$REVIEW_SUMMARY_COMMENTS " | wc - l)) )
63116fi
64117
65118if [ -z " $ALL_COMMENTS " ]; then
66- echo " No comments found for PR #$PR_NUMBER "
119+ print_error " No comments found for PR #$PR_NUMBER "
120+ echo " "
121+ echo " 💡 ${YELLOW} Tip:${NC} This PR doesn't have any comments yet. Try adding a comment first!"
67122 exit 0
68123fi
69124
70- echo " $ALL_COMMENTS "
125+ print_status " Found ${WHITE} $COMMENT_COUNT ${NC} items to react to!"
126+ echo " "
127+ echo -e " ${WHITE} 📋 Available Content:${NC} "
128+ echo " ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
129+
130+ # Create arrays to store comment data for easy selection
131+ declare -a COMMENT_IDS
132+ declare -a COMMENT_TYPES
133+ declare -a COMMENT_AUTHORS
134+ declare -a COMMENT_CONTENTS
135+ COUNTER=1
71136
72- echo
73- read -p " Enter comment ID to react to: " COMMENT_ID
74- echo " Pick a reaction: (+1, -1, laugh, heart, hooray, rocket, eyes)"
75- read -p " Reaction: " REACTION
137+ # Format and display comments with numbers
138+ echo " $ALL_COMMENTS " | while IFS=' |' read -r type id author_and_content; do
139+ author=$( echo " $author_and_content " | cut -d' :' -f1)
140+ content=$( echo " $author_and_content " | cut -d' :' -f2- | head -c 80)
141+
142+ case $type in
143+ " PR_BODY" )
144+ echo -e " ${WHITE} [$COUNTER ]${NC} ${PURPLE} 📄 PR Description${NC} by ${CYAN} @$author ${NC} "
145+ ;;
146+ " ISSUE" )
147+ echo -e " ${WHITE} [$COUNTER ]${NC} ${GREEN} 💬 Comment${NC} by ${CYAN} @$author ${NC} "
148+ ;;
149+ " REVIEW" )
150+ echo -e " ${WHITE} [$COUNTER ]${NC} ${YELLOW} 🔍 Code Review${NC} by ${CYAN} @$author ${NC} "
151+ ;;
152+ " REVIEW_SUMMARY" )
153+ echo -e " ${WHITE} [$COUNTER ]${NC} ${BLUE} 📝 Review Summary${NC} by ${CYAN} @$author ${NC} "
154+ ;;
155+ esac
156+ echo -e " ${WHITE} └─${NC} $( echo " $content " | tr ' \n' ' ' ) ..."
157+ echo " "
158+ COUNTER=$(( COUNTER + 1 ))
159+ done
76160
77- # Determine if it's an issue comment or review comment
78- COMMENT_TYPE= $( echo " $ALL_COMMENTS " | grep " | $COMMENT_ID | " | cut -d ' | ' -f1 )
161+ # Store the comment data in temporary file for later retrieval
162+ echo " $ALL_COMMENTS " > /tmp/gh_react_comments_ $$
79163
80- echo " Sending reaction..."
164+ echo " ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
165+ echo " "
166+ echo -e " ${WHITE}${REACTION} Choose what to react to:${NC} "
167+ read -p " � Enter number (1-$COMMENT_COUNT ): " SELECTION
168+
169+ # Validate selection is a number and in range
170+ if ! [[ " $SELECTION " =~ ^[0-9]+$ ]] || [ " $SELECTION " -lt 1 ] || [ " $SELECTION " -gt " $COMMENT_COUNT " ]; then
171+ print_error " Invalid selection: $SELECTION "
172+ echo " "
173+ echo " 💡 ${YELLOW} Tip:${NC} Please enter a number between 1 and $COMMENT_COUNT "
174+ rm -f /tmp/gh_react_comments_$$
175+ exit 1
176+ fi
177+
178+ # Get the selected comment data
179+ SELECTED_LINE=$( sed -n " ${SELECTION} p" /tmp/gh_react_comments_$$ )
180+ COMMENT_TYPE=$( echo " $SELECTED_LINE " | cut -d' |' -f1)
181+ COMMENT_ID=$( echo " $SELECTED_LINE " | cut -d' |' -f2)
182+ SELECTED_AUTHOR=$( echo " $SELECTED_LINE " | cut -d' |' -f3 | cut -d' :' -f1)
183+
184+ # Clean up temp file
185+ rm -f /tmp/gh_react_comments_$$
186+
187+ echo " "
188+ print_info " Selected: ${WHITE} $COMMENT_TYPE ${NC} by ${CYAN} @$SELECTED_AUTHOR ${NC} "
189+
190+ echo " "
191+ echo -e " ${WHITE} 😊 Available reactions:${NC} "
192+ echo " 👍 +1 👎 -1 😄 laugh"
193+ echo " ❤️ heart 🎉 hooray 🚀 rocket 👀 eyes"
194+ echo " "
195+ read -p " 🎯 Pick a reaction: " REACTION
196+
197+ # Validate reaction
198+ case $REACTION in
199+ " +1" |" -1" |" laugh" |" heart" |" hooray" |" rocket" |" eyes" )
200+ ;;
201+ * )
202+ print_error " Invalid reaction: $REACTION "
203+ echo " "
204+ echo " 💡 ${YELLOW} Valid options:${NC} +1, -1, laugh, heart, hooray, rocket, eyes"
205+ exit 1
206+ ;;
207+ esac
208+
209+ echo " "
210+ print_info " Sending ${WHITE} $REACTION ${NC} reaction to comment ${WHITE} $COMMENT_ID ${NC} ..."
81211if [ " $COMMENT_TYPE " = " PR_BODY" ]; then
82212 # React to PR description/body
83- gh api --method POST repos/$OWNER /$REPO /issues/$PR_NUMBER /reactions \
213+ RESPONSE= $( gh api --method POST repos/$OWNER /$REPO /issues/$PR_NUMBER /reactions \
84214 -f " content=$REACTION " \
85- -H " Accept: application/vnd.github+json"
215+ -H " Accept: application/vnd.github+json" 2>&1 )
86216elif [ " $COMMENT_TYPE " = " ISSUE" ]; then
87217 # React to issue comment
88- gh api --method POST repos/$OWNER /$REPO /issues/comments/$COMMENT_ID /reactions \
218+ RESPONSE= $( gh api --method POST repos/$OWNER /$REPO /issues/comments/$COMMENT_ID /reactions \
89219 -f " content=$REACTION " \
90- -H " Accept: application/vnd.github+json"
220+ -H " Accept: application/vnd.github+json" 2>&1 )
91221elif [ " $COMMENT_TYPE " = " REVIEW" ]; then
92222 # React to review comment (inline code comment)
93- gh api --method POST repos/$OWNER /$REPO /pulls/comments/$COMMENT_ID /reactions \
223+ RESPONSE= $( gh api --method POST repos/$OWNER /$REPO /pulls/comments/$COMMENT_ID /reactions \
94224 -f " content=$REACTION " \
95- -H " Accept: application/vnd.github+json"
225+ -H " Accept: application/vnd.github+json" 2>&1 )
96226elif [ " $COMMENT_TYPE " = " REVIEW_SUMMARY" ]; then
97227 # React to review summary comment
98- gh api --method POST repos/$OWNER /$REPO /pulls/reviews/$COMMENT_ID /reactions \
228+ RESPONSE= $( gh api --method POST repos/$OWNER /$REPO /pulls/reviews/$COMMENT_ID /reactions \
99229 -f " content=$REACTION " \
100- -H " Accept: application/vnd.github+json"
230+ -H " Accept: application/vnd.github+json" 2>&1 )
101231else
102- echo " Error: Could not determine comment type for ID $COMMENT_ID "
232+ print_error " Could not determine comment type for ID $COMMENT_ID "
103233 exit 1
104234fi
105235
106- echo " Done! 👍"
236+ # Check if the reaction was successful
237+ if [ $? -eq 0 ]; then
238+ echo " "
239+ print_success " Reaction added successfully! 🎉"
240+ echo " "
241+ echo -e " ${WHITE} 🔗 View PR:${NC} https://github.com/$OWNER /$REPO /pull/$PR_NUMBER "
242+
243+ # Show reaction emoji based on type
244+ case $REACTION in
245+ " +1" ) echo -e " ${GREEN} 👍 Added thumbs up!${NC} " ;;
246+ " -1" ) echo -e " ${RED} 👎 Added thumbs down!${NC} " ;;
247+ " laugh" ) echo -e " ${YELLOW} 😄 Added laugh!${NC} " ;;
248+ " heart" ) echo -e " ${RED} ❤️ Added heart!${NC} " ;;
249+ " hooray" ) echo -e " ${PURPLE} 🎉 Added hooray!${NC} " ;;
250+ " rocket" ) echo -e " ${BLUE} 🚀 Added rocket!${NC} " ;;
251+ " eyes" ) echo -e " ${CYAN} � Added eyes!${NC} " ;;
252+ esac
253+ else
254+ print_error " Failed to add reaction"
255+ echo " "
256+ echo " Error details:"
257+ echo " $RESPONSE "
258+ echo " "
259+ echo " 💡 ${YELLOW} Tip:${NC} Make sure you have permission to react to this content."
260+ exit 1
261+ fi
0 commit comments