Skip to content

Commit

Permalink
style: improve code structure and comments
Browse files Browse the repository at this point in the history
  • Loading branch information
LangLangBart committed Jul 18, 2024
1 parent a6835a8 commit 44871fd
Showing 1 changed file with 103 additions and 84 deletions.
187 changes: 103 additions & 84 deletions gh-notify
Original file line number Diff line number Diff line change
Expand Up @@ -2,27 +2,31 @@
set -o errexit -o nounset -o pipefail
# https://www.gnu.org/software/bash/manual/bash.html#The-Set-Builtin

# ====================== Infos =======================
###############################################################################
# Information
###############################################################################

# https://docs.github.com/en/rest/activity/notifications
# https://docs.github.com/en/graphql/reference/queries
# NotificationReason:
# assign, author, comment, invitation, manual, mention, review_requested, security_alert, state_change, subscribed, team_mention, ci_activity
# NotificationSubjectTypes:
# CheckSuite, Commit, Discussion, Issue, PullRequest, Release, RepositoryVulnerabilityAlert, ...

# ====================== set variables =======================
###############################################################################
# Set Variables
###############################################################################

# The minimum fzf version that the user needs to run all interactive commands.
MIN_FZF_VERSION="0.29.0"

# export variables for use in child processes
# Export variables for use in child processes.
set -o allexport
# https://docs.github.com/en/rest/overview/api-versions
export GH_REST_API_VERSION="X-GitHub-Api-Version:2022-11-28"
GH_REST_API_VERSION="X-GitHub-Api-Version:2022-11-28"
# Enable terminal-style output even when the output is redirected.
export GH_FORCE_TTY=1
# shellcheck disable=SC2034
GH_FORCE_TTY=1
# The maximum number of notifications per page set by GitHub.
GH_NOTIFY_PER_PAGE_LIMIT=50

# Need to be exported because of its use in the 'print_help_text' function
set -o allexport
# Customize the fzf keys using environment variables
: "${GH_NOTIFY_MARK_ALL_READ_KEY:=ctrl-a}"
: "${GH_NOTIFY_OPEN_BROWSER_KEY:=ctrl-b}"
Expand All @@ -36,12 +40,46 @@ set -o allexport
: "${GH_NOTIFY_VIEW_KEY:=enter}"
: "${GH_NOTIFY_TOGGLE_PREVIEW_KEY:=tab}"
: "${GH_NOTIFY_TOGGLE_HELP_KEY:=?}"
set +o allexport

# The maximum number of notifications per page (set by GitHub)
export GH_NOTIFY_PER_PAGE_LIMIT=50
# Assign 'GH_NOTIFY_DEBUG_MODE' with 'true' to see more information
export GH_NOTIFY_DEBUG_MODE=${GH_NOTIFY_DEBUG_MODE:-false}
: "${GH_NOTIFY_DEBUG_MODE:=false}"

# 'SHLVL' variable represents the nesting level of the current shell
NESTED_START_LVL="$SHLVL"
FINAL_MSG='All caught up!'

# color codes
GREEN='\033[0;32m'
DARK_GRAY='\033[0;90m'
NC='\033[0m'
WHITE_BOLD='\033[1m'

exclusion_string='XXX_BOGUS_STRING_THAT_SHOULD_NOT_EXIST_XXX'
filter_string=''
num_notifications=0
only_participating_flag=false
include_all_flag=false
preview_window_visibility='hidden'
python_executable=''
set +o allexport

# No need to export, since they aren't used in any child process.
print_static_flag=false
mark_read_flag=false
update_subscription_url=''

# The minimum fzf version that the user needs to run all interactive commands.
MIN_FZF_VERSION="0.29.0"

###############################################################################
# Debugging and Error Handling Configuration
###############################################################################

die() {
echo ERROR: "$*" >&2
exit 1
}

if $GH_NOTIFY_DEBUG_MODE; then
export gh_notify_debug_log="${BASH_SOURCE[0]%/*}/gh_notify_debug.log"

Expand All @@ -68,6 +106,11 @@ if $GH_NOTIFY_DEBUG_MODE; then
# Redirect possible errors and debug information from 'gh api' calls to a file
# exec 5> >(tee -a "$gh_notify_debug_log")

# Ensure Bash 4.1+ for BASH_XTRACEFD support.
if [[ ${BASH_VERSINFO[0]} -lt 4 || (${BASH_VERSINFO[0]} -eq 4 && ${BASH_VERSINFO[1]} -lt 1) ]]; then
die "Bash 4.1 or newer is required for debugging. Current version: ${BASH_VERSION}"
fi

# Redirect xtrace output to a file
exec 6>>"$gh_notify_debug_log"
# Write the trace output to file descriptor 6
Expand All @@ -76,36 +119,11 @@ if $GH_NOTIFY_DEBUG_MODE; then
export PS4='+$(date +%Y-%m-%d:%H:%M:%S) ${FUNCNAME[0]:-}:L${LINENO:-}: '
set -o xtrace
fi
# 'SHLVL' variable represents the nesting level of the current shell
export NESTED_START_LVL="$SHLVL"
export FINAL_MSG='All caught up!'

# color codes
export GREEN='\033[0;32m'
export DARK_GRAY='\033[0;90m'
export NC='\033[0m'
export WHITE_BOLD='\033[1m'

export exclusion_string='XXX_BOGUS_STRING_THAT_SHOULD_NOT_EXIST_XXX'
export filter_string=''
export num_notifications=0
export only_participating_flag=false
export include_all_flag=false
export preview_window_visibility='hidden'
export python_executable=''
# not necessarily to be exported, since they are not used in any child process
print_static_flag=false
mark_read_flag=false
update_subscription_url=''

# ===================== basic functions =====================

die() {
echo ERROR: "$*" >&2
exit 1
}
###############################################################################
# Helper Functions
###############################################################################

# Create help message with colored text
# IMPORTANT: Keep it synchronized with the README, but without the Examples.
print_help_text() {
local help_text
Expand Down Expand Up @@ -160,37 +178,6 @@ EOF
echo -e "$help_text"
}

# ====================== parse command-line options =======================

while getopts 'e:f:n:u:pawhsr' flag; do
case "${flag}" in
e)
FINAL_MSG="No results found."
exclusion_string="${OPTARG}"
;;
f)
FINAL_MSG="No results found."
filter_string="${OPTARG}"
;;
n) num_notifications="${OPTARG}" ;;
p) only_participating_flag=true ;;
u) update_subscription_url="${OPTARG}" ;;
a) include_all_flag=true ;;
w) preview_window_visibility='nohidden' ;;
s) print_static_flag=true ;;
r) mark_read_flag=true ;;
h)
print_help_text
exit 0
;;
*)
die "see 'gh notify -h' for help"
;;
esac
done

# ===================== helper functions ==========================

gh_rest_api() {
command gh api --header "$GH_REST_API_VERSION" --method GET --cache=0s "$@"
}
Expand Down Expand Up @@ -515,9 +502,16 @@ mark_all_read() {

mark_individual_read() {
local thread_id thread_state
# TODO: Investigate potential rate-limiting issues when sending too many requests in short
# succession. I didn't encounter any rate-limiting when testing with 100 unread notifications,
# but further testing is needed to be sure.

# Running commands in the background of a script can cause it to hang, especially if the
# command outputs to stdout: https://tldp.org/LDP/abs/html/x9644.html#WAITHANG
while IFS=' ' read -r _ thread_id thread_state _; do
if [[ $thread_state == "UNREAD" ]]; then
gh_rest_api --silent --method PATCH "notifications/threads/${thread_id}"
# https://docs.github.com/en/rest/activity/notifications#mark-a-thread-as-read
gh_rest_api --silent --method PATCH "notifications/threads/${thread_id}" &>/dev/null &
fi
done <"$1"
}
Expand All @@ -534,14 +528,12 @@ select_notif() {
# a failed 'print_notifs' call, but does not display the message.

# See the man page (man fzf) for an explanation of the arguments.

output=$(
# shellcheck disable=SC2086
SHELL="$(which bash)" command fzf ${GH_NOTIFY_FZF_OPTS:-} \
SHELL="$(which bash)" FZF_DEFAULT_OPTS="${FZF_DEFAULT_OPTS-} ${GH_NOTIFY_FZF_OPTS-}" command fzf \
--ansi \
--bind "${GH_NOTIFY_RESIZE_PREVIEW_KEY}:change-preview-window(75%:nohidden|75%:down:nohidden:border-top|nohidden)" \
--bind "change:first" \
--bind "${GH_NOTIFY_MARK_ALL_READ_KEY}:select-all+execute-silent([[ -z {q} ]] && mark_all_read {} || mark_individual_read {+f})+reload:print_notifs || true" \
--bind "${GH_NOTIFY_MARK_ALL_READ_KEY}:select-all+execute-silent(if [[ -z {q} ]]; then mark_all_read {}; else mark_individual_read {+f}; fi)+reload:print_notifs || true" \
--bind "${GH_NOTIFY_OPEN_BROWSER_KEY}:execute-silent:open_in_browser {}" \
--bind "${GH_NOTIFY_VIEW_DIFF_KEY}:toggle-preview+change-preview:if command grep -q PullRequest <<<{10}; then command gh pr diff {11} --repo {5} | highlight_output; else view_notification {}; fi" \
--bind "${GH_NOTIFY_VIEW_PATCH_KEY}:toggle-preview+change-preview:if command grep -q PullRequest <<<{10}; then command gh pr diff {11} --patch --repo {5} | highlight_output; else view_notification {}; fi" \
Expand Down Expand Up @@ -683,8 +675,35 @@ update_subscription() {
fi
}

gh_notify() {
main() {
local python_version notifs
# CLI Options
while getopts 'e:f:n:u:pawsrh' flag; do
case "${flag}" in
e)
FINAL_MSG="No results found."
exclusion_string="${OPTARG}"
;;
f)
FINAL_MSG="No results found."
filter_string="${OPTARG}"
;;
n) num_notifications="${OPTARG}" ;;
p) only_participating_flag=true ;;
u) update_subscription_url="${OPTARG}" ;;
a) include_all_flag=true ;;
w) preview_window_visibility='nohidden' ;;
s) print_static_flag=true ;;
r) mark_read_flag=true ;;
h)
print_help_text
exit 0
;;
*)
die "see 'gh notify -h' for help"
;;
esac
done

if ! command -v gh >/dev/null; then
die "install 'gh'"
Expand Down Expand Up @@ -714,7 +733,6 @@ gh_notify() {
if ! command -v fzf >/dev/null; then
die "install 'fzf' or use the -s flag"
fi

check_version fzf "$MIN_FZF_VERSION"
fi

Expand All @@ -731,7 +749,8 @@ gh_notify() {
fi
}

# This will call the function only when the script is run, not when it's sourced
if [[ ${BASH_SOURCE[0]} == "${0}" ]]; then
gh_notify
fi
###############################################################################
# Script Execution
###############################################################################

main "$@"

0 comments on commit 44871fd

Please sign in to comment.