Skip to content

Instantly share code, notes, and snippets.

@relsqui
Last active August 16, 2023 18:08
Show Gist options
  • Save relsqui/0d1c00eb1a951b5d61ae272e5c4190b6 to your computer and use it in GitHub Desktop.
Save relsqui/0d1c00eb1a951b5d61ae272e5c4190b6 to your computer and use it in GitHub Desktop.

Multi-repo PRs-awaiting-review finder

This script adds two commands to your shell:

  • show-waiting-prs lists PRs awaiting review in the specified repository. It'll format them into a nice table (but not truncate any information, so it might be wider than your terminal). Example: show-waiting-prs relsqui/oobash
  • all-waiting-prs does that for every repo with the specified owner, formatting the result into one uniform table that might truncate usernames or PR titles to fit your terminal, but never URLs. Example: all-waiting-prs relsqui
    • Add a second argument to filter by a repository tag: all-waiting-prs relsqui game

Setup

  1. Install and configure the GitHub CLI
  2. Put the block below in your ~/.profile
  3. Restart your terminal (or source ~/.profile) to add the new commands to your environment
show-waiting-prs() {
  local search_term='review:none draft:false'
  local template='{{range .}}{{.author.login}}{{"\t"}}{{.title}}{{"\t"}}{{.url}} {{"\n"}}{{end}}'
  gh pr list -R "${1}" --search "$search_term" --json title,url,author --template "$template" | column -ts $'\t' -o $'\t'
}

all-waiting-prs() {
  local repo_owner="$1"
  local repo_tag="$2"
  gh repo list "$repo_owner" --topic "$repo_tag" --no-archived --limit 9999 --json 'nameWithOwner' | jq -r '.[].nameWithOwner' | while read repo; do
    show-waiting-prs "$repo"
  done | column -ts $'\t' -T 1,2 -E ''
}

If you'll usually want the same arguments, you can add something like this to your ~/.profile too:

alias prs='all-waiting-prs relsqui game'

and then invoke it as prs.

🚫 🍎 Caveat

BSD column doesn't have most of these options, so this won't work as written on a Mac. This gist has advice for other utilities, but I haven't figured out how to install GNU column, specifically, on a Mac. If you're adventurous, check out gh help formatting for alternative ideas, like their {{tablerow}} templating function.

How does it work?

show-waiting-prs

show-waiting-prs() { ... }
# define a bash function, any arguments will go into $1, $2, etc.

template='{{range .}}{{.author.login}}{{"\t"}}{{.title}}{{"\t"}}{{.url}} {{"\n"}}{{end}}'
# this is a Go template string. for each thing in the input (range) it prints
# the fields we want, separated by tabs, and then a newline at the end
# see `gh help formatting` or the Go docs for more details
# the space after the URL is so that if it happens to hit the edge of your terminal
# exactly, and your terminal supports clickable links, it won't try to include the
# beginning of the next line in the link

gh pr list -R "${1}" --search "$search_term" --json title,url,author --template "$template"
# ask github for PR information, see `gh pr list --help` for more details
# -R: specifies the repository
# --search: works like on the website
# --json: specifies which fields we want in the output
# --template: apply the template

column -ts $'\t' -o $'\t'
# parse input lines as tabular data
# -t: output in aligned columns (a human-readable table)
# -s $'\t': expect the input to be separated by literal tabs
# -o $'\t': print output fields separated by literal tabs
# by default, `column` prints fields separated by two spaces
# we use tabs here so that we can pipe it into column again in all-waiting-prs
# (so really all this is doing is aligning the columns)

all-waiting-prs

local repo_owner="$1"
local repo_tag="$2"
# get the arguments and assign them to named variables
# (this is just for readability)

gh repo list "$repo_owner" --topic "$repo_tag" --no-archived --limit 9999 --json 'nameWithOwner'
# get the list of repos to check for pull requests
# (shoutout to @spilliams for this improvement over my original hardcoded list)
# --topic: filter by repo tag
# --no-archived: exclude archived repos
# --limit: maximum number of repos to return, if you need to check ten thousand repos make this bigger
# --json: output the list as JSON that looks like:
# [{"nameWithOwner": "relsqui/oobash"}, ...]

jq -r '.[].nameWithOwner'
# turn that JSON into a plain list of owner/repo strings

while read repo; do ...; done
# loop over the repo names in the list, assigning each one to $repo

show-waiting-prs "$repo"
# call the other function with the repo name as an argument

column -ts $'\t' -T 1,2 -E ''
# mostly like the previous use of column, except:
# -T 1,2: truncate first and second column if necessary to fit
# (we don't do that in show-waiting prs so they're not already truncated when they get here)
# -E '': all column lengths should be considered for table sizing
# (by default, the last column is excluded, so rows could wrap)
# lack of -o: use default output column separators (two spaces)

How many PRs could you have reviewed in the time it took to write this up

Listen,,,

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment