#!/usr/bin/env bash # lib/forge-github.sh — the GitHub backend (issue #188, term 1). Sourced by # lib/forge.sh when forge_detect says github; never at the same time as the # forgejo backend — they define the same verbs on purpose. # # This file is the CURRENT call set, extracted 1:1 and nothing more. Term 5 # of the frozen Spec is "GitHub consumers are unchanged", and the cheapest # way to keep that true is for every verb here to be a thin pass-through to # the `gh` invocation the call site used before the port. No behaviour is # added, fixed or tidied on this path; anything that looks like an # improvement here is a regression risk against a forge nobody is currently # reporting bugs on. # forge_api [--paginate] [--jq ] # # The one deliberate difference from a pure pass-through: the caller no # longer names a page size, because the page-size parameter is not portable # and is therefore the backend's to own (#188). # # ?per_page=100 GitHub: 100 items Forgejo: 30 items (IGNORED) # ?limit=100 GitHub: 30 items Forgejo: 50 items (capped) # # Both answer HTTP 200 either way, so a call site that names one is a silent # truncation waiting for the other forge. per_page=100 is injected here — # exactly what the call sites said before — so the GitHub path is unchanged # in behaviour while the parameter stops being a call-site concern. forge_api() { local paginate=false endpoint="" jqexpr="" have_jq=false while [ $# -gt 0 ]; do case "$1" in --paginate) paginate=true ;; --jq) jqexpr="$2"; have_jq=true; shift ;; -*) ;; *) [ -n "$endpoint" ] || endpoint="$1" ;; esac shift done [ -n "$endpoint" ] || { echo "forge_api: endpoint required" >&2; return 1; } if [ "$paginate" = true ]; then endpoint="$(github_page_url "$endpoint")" if [ "$have_jq" = true ]; then gh api --paginate "$endpoint" --jq "$jqexpr" else gh api --paginate "$endpoint" fi else if [ "$have_jq" = true ]; then gh api "$endpoint" --jq "$jqexpr" else gh api "$endpoint" fi fi } # github_page_url — pure, so the page-size contract is testable # without a network. Strips any page-size parameter a caller left behind in # either dialect, then applies GitHub's own. github_page_url() { local endpoint="${1:?github_page_url: endpoint required}" clean clean="$(printf '%s' "$endpoint" | sed -E 's/([?&])(per_page|limit|page)=[0-9]+/\1/g; s/[?&]+$//; s/([?&])&+/\1/g')" case "$clean" in *\?) printf '%sper_page=100\n' "$clean" ;; *\?*) printf '%s&per_page=100\n' "$clean" ;; *) printf '%s?per_page=100\n' "$clean" ;; esac }