Last active
April 22, 2023 18:50
-
-
Save netj/082aa1d431db0e240eb492f0a3f16873 to your computer and use it in GitHub Desktop.
macOS xbar menu item for GitHub Pull Requests/Issues
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env bash | |
# macOS xbar menu item for GitHub Pull Requests/Issues | |
# | |
# <xbar.title>GitHub assigned Pull Requests and Issues</xbar.title> | |
# <xbar.version>v2023.16.0</xbar.version> | |
# <xbar.author>Jaeho Shin</xbar.author> | |
# <xbar.author.github>netj</xbar.author.github> | |
# <xbar.desc>Quick handle for showing number of assigned Github Pull Requests / Issues and giving access to the most recent ones</xbar.desc> | |
# <xbar.image>https://github.githubassets.com/images/modules/logos_page/GitHub-Mark.png</xbar.image> | |
# <xbar.abouturl>https://gist.github.com/netj/082aa1d431db0e240eb492f0a3f16873</xbar.abouturl> | |
# (cf. https://github.com/matryer/xbar-plugins/blob/main/CONTRIBUTING.md#metadata) | |
set -euo pipefail | |
# find GitHub instance hostname from the filename | |
basenameWithInterval=$(basename "$0" .sh) | |
basename=${basenameWithInterval%.*} | |
export githubHostname=${basename#*=} | |
# optional filename prefix ending with an = can define menubar icon/label (e.g.: 🎨=github.com.5m.sh) | |
icon=${basename%%$githubHostname}; icon=${icon%=}; : ${icon:=$githubHostname} | |
export PATH=/opt/homebrew/bin:"$PATH" # XXX for jq from Homebrew | |
case $githubHostname in | |
github.com|api.github.*) # public Github or API hostname for GHE | |
githubHostname=${githubHostname#api.} | |
githubUrlApi=https://api.$githubHostname | |
;; | |
*) # Github Enterprise | |
githubUrlApi=https://$githubHostname/api/v3 | |
esac | |
githubUrlBase=https://$githubHostname | |
export githubUrlBase githubHostname githubUrlApi | |
githubApiCall() { local urlPath=$1; shift; curl -nfgsSL "$githubUrlApi$urlPath" "$@"; } | |
search_total_count() { jq -s '[.[].total_count] | add'; } | |
search2bitbar_menu_items() { | |
# TODO parameterize limit | |
limit=10 \ | |
jq -s ' | |
([.[].items[] | select(.archived | not)] | sort_by(.updated_at) | reverse | .[:(env.limit | tonumber)][] | | |
"\(.repository_url | ltrimstr("\(env.githubUrlApi)/repos/"))#\(.number) \(.title) | href=\(.html_url | @sh) terminal=false" | |
)' -r | |
} | |
XBAR_MENU() { | |
githubUser=$( githubApiCall "/user" | jq .login -r) | |
prs_assigned=$( githubApiCall "/search/issues?sort=updated&order=desc&q=archived:false+state:open+is:pr+assignee:$githubUser") | |
prs_authored=$( githubApiCall "/search/issues?sort=updated&order=desc&q=archived:false+state:open+is:pr+author:$githubUser") | |
prs_mentioning=$( githubApiCall "/search/issues?sort=updated&order=desc&q=archived:false+state:open+is:pr+mentions:$githubUser") | |
prs_requesting_review=$( githubApiCall "/search/issues?sort=updated&order=desc&q=archived:false+state:open+is:pr+review-requested:$githubUser") | |
prs="$prs_assigned $prs_authored $prs_mentioning $prs_requesting_review" | |
issues_assigned=$( githubApiCall "/search/issues?sort=updated&order=desc&q=archived:false+state:open+is:issue+assignee:$githubUser") | |
issues_authored=$( githubApiCall "/search/issues?sort=updated&order=desc&q=archived:false+state:open+is:issue+author:$githubUser") | |
issues_mentioning=$( githubApiCall "/search/issues?sort=updated&order=desc&q=archived:false+state:open+is:issue+mentions:$githubUser") | |
issues="$issues_assigned $issues_authored $issues_mentioning" | |
num_prs_assigned=$(search_total_count <<<"$prs_assigned") | |
num_issues_assigned=$(search_total_count <<<"$issues_assigned") | |
num_prs=$(search_total_count <<<"$prs") | |
num_issues=$(search_total_count <<<"$issues") | |
############################################################################### | |
# render xbar menu and menu items | |
echo -n "$icon" | |
echo "$(($num_prs_assigned + $num_issues_assigned))" | |
echo "---" | |
echo "$githubUser@$githubHostname | href=$githubUrlBase/$githubUser" | |
echo "$num_prs open pull requests" | |
echo "$num_issues open issues" | |
start_bitbar_menu_section() { | |
local title=$1; shift | |
echo "---" | |
echo "$title | color=#666666 $*" | |
} | |
start_bitbar_menu_section "$num_prs_assigned open PRs assigned to you" "href=$githubUrlBase/pulls/assigned" | |
search2bitbar_menu_items <<<"$prs_assigned" | |
start_bitbar_menu_section "$(search_total_count <<<"$issues_assigned") open issues assigned to you" "href=$githubUrlBase/issues/assigned" | |
search2bitbar_menu_items <<<"$issues_assigned" | |
start_bitbar_menu_section "$(search_total_count <<<"$prs_requesting_review") open PRs requested your review" "href=$githubUrlBase/pulls/review-requested" | |
search2bitbar_menu_items <<<"$prs_requesting_review" | |
start_bitbar_menu_section "$(search_total_count <<<"$prs_authored") open PRs authored by you" "href=$githubUrlBase/pulls" | |
search2bitbar_menu_items <<<"$prs_authored" | |
# TODO fold some items into submenu to give more focus to assigned+review-requested ones? | |
start_bitbar_menu_section "$(search_total_count <<<"$issues_authored") open issues authored by you" "href=$githubUrlBase/issues" | |
search2bitbar_menu_items <<<"$issues_authored" | |
start_bitbar_menu_section "$(search_total_count <<<"$prs_mentioning") open PRs mention you" "href=$githubUrlBase/pulls/mentioned" | |
search2bitbar_menu_items <<<"$prs_mentioning" | |
start_bitbar_menu_section "$(search_total_count <<<"$issues_mentioning") open issues mention you" "href=$githubUrlBase/issues/mentioned" | |
search2bitbar_menu_items <<<"$issues_mentioning" | |
} | |
[[ $# -gt 0 ]] || set -- XBAR_MENU | |
"$@" |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment