En Windows el stdout de Python defaultea a cp1252 y crashea con
UnicodeEncodeError al imprimir literales no-ASCII (e.g. el ✓ del print
de éxito de pr-create.sh). El sintoma era que el PR se creaba OK pero
el script terminaba con exit 1 por el crash del print posterior.
Agrego export PYTHONIOENCODING=utf-8 después de set -euo pipefail en
los 10 scripts que invocan python (todos menos query.sh). Cubre tanto
las invocaciones inline como futuras sin tener que acordarse caso por
caso. Mantiene los literales unicode existentes (✓, →, ─, ⚠️).
89 lines
2.5 KiB
Bash
89 lines
2.5 KiB
Bash
#!/usr/bin/env bash
|
|
# gitea skill — listar PRs de un repo.
|
|
#
|
|
# Uso:
|
|
# pr-list.sh <owner>/<repo> [--state open|closed|all] [--limit N]
|
|
#
|
|
# Si pasás solo <repo>, usa GITEA_DEFAULT_OWNER del .env (NucleOS).
|
|
# Devuelve una tabla compacta. Para ver el JSON crudo, usá query.sh directamente.
|
|
|
|
set -euo pipefail
|
|
|
|
# Forzar UTF-8 en stdout de Python (Windows defaultea a cp1252 y crashea con
|
|
# literales no-ASCII). Ver memoria feedback_api_utf8_encoding.md.
|
|
export PYTHONIOENCODING=utf-8
|
|
|
|
SKILL_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
|
|
QUERY="$SKILL_DIR/scripts/query.sh"
|
|
|
|
state="open"
|
|
limit=20
|
|
repo_arg=""
|
|
|
|
while [[ $# -gt 0 ]]; do
|
|
case "$1" in
|
|
--state) state="$2"; shift 2 ;;
|
|
--limit) limit="$2"; shift 2 ;;
|
|
-h|--help)
|
|
cat <<EOF
|
|
Uso: pr-list.sh <owner>/<repo> [--state open|closed|all] [--limit N]
|
|
|
|
Ejemplos:
|
|
pr-list.sh NucleOS/nucleo-infra
|
|
pr-list.sh nucleo-infra --state closed --limit 5
|
|
EOF
|
|
exit 0
|
|
;;
|
|
-*) echo "ERROR: flag desconocida: $1" >&2; exit 2 ;;
|
|
*) repo_arg="$1"; shift ;;
|
|
esac
|
|
done
|
|
|
|
if [[ -z "$repo_arg" ]]; then
|
|
echo "ERROR: pasá <owner>/<repo> o solo <repo>." >&2
|
|
exit 2
|
|
fi
|
|
|
|
# Resolver owner/repo
|
|
if [[ "$repo_arg" == */* ]]; then
|
|
owner="${repo_arg%%/*}"
|
|
repo="${repo_arg##*/}"
|
|
else
|
|
set -a; source "$SKILL_DIR/.env"; set +a
|
|
owner="${GITEA_DEFAULT_OWNER:?owner no especificado y GITEA_DEFAULT_OWNER vacío}"
|
|
repo="$repo_arg"
|
|
fi
|
|
|
|
resp="$("$QUERY" "/repos/${owner}/${repo}/pulls?state=${state}&limit=${limit}")"
|
|
|
|
# Detectar errores (objeto, no array)
|
|
if [[ "${resp:0:1}" == "{" ]]; then
|
|
echo "$resp" | PYTHONIOENCODING=utf-8 python -c "
|
|
import json, sys
|
|
d=json.load(sys.stdin)
|
|
print('ERROR:', d.get('message') or d.get('error') or d, file=sys.stderr)
|
|
" >&2
|
|
exit 1
|
|
fi
|
|
|
|
echo "$resp" | PYTHONIOENCODING=utf-8 python -c "
|
|
import json, sys
|
|
prs = json.load(sys.stdin)
|
|
if not prs:
|
|
print('(sin PRs en estado: $state)')
|
|
sys.exit(0)
|
|
print(f'{len(prs)} PR(s) en $owner/$repo (state=$state):')
|
|
print()
|
|
for pr in prs:
|
|
n = pr.get('number')
|
|
title = (pr.get('title') or '').replace('\n', ' ')
|
|
if len(title) > 70: title = title[:67] + '...'
|
|
state_label = 'merged' if pr.get('merged') else pr.get('state','?')
|
|
head = (pr.get('head') or {}).get('ref','?')
|
|
base = (pr.get('base') or {}).get('ref','?')
|
|
user = (pr.get('user') or {}).get('login','?')
|
|
updated = (pr.get('updated_at') or '')[:10]
|
|
print(f' #{n:<4} [{state_label:<7}] {title}')
|
|
print(f' {user} | {head} → {base} | updated {updated}')
|
|
"
|