191 lines
6.0 KiB
Python
191 lines
6.0 KiB
Python
#!/usr/bin/env python3
|
|
"""
|
|
Minimal Gitea API client. Reads GITEA_* from environment or .env in repo root.
|
|
"""
|
|
from __future__ import annotations
|
|
|
|
import argparse
|
|
import json
|
|
import sys
|
|
from pathlib import Path
|
|
|
|
from gitea_lib import (
|
|
issues_comment,
|
|
issues_create,
|
|
issues_get,
|
|
issues_list_all,
|
|
issues_list_page,
|
|
issues_patch,
|
|
load_dotenv,
|
|
repo_file_content,
|
|
repo_root,
|
|
require_config,
|
|
)
|
|
|
|
|
|
def cmd_issues_list(args: argparse.Namespace, base: str, token: str, owner: str, repo: str) -> None:
|
|
if args.all_pages:
|
|
items = issues_list_all(
|
|
base, token, owner, repo, state=args.state, limit=args.limit
|
|
)
|
|
else:
|
|
_, items = issues_list_page(
|
|
base,
|
|
token,
|
|
owner,
|
|
repo,
|
|
state=args.state,
|
|
page=args.page,
|
|
limit=args.limit,
|
|
)
|
|
for it in items:
|
|
num = it.get("number")
|
|
title = it.get("title")
|
|
st = it.get("state")
|
|
print(f"#{num} [{st}] {title}")
|
|
|
|
|
|
def cmd_issues_get(args: argparse.Namespace, base: str, token: str, owner: str, repo: str) -> None:
|
|
status, payload = issues_get(base, token, owner, repo, args.number)
|
|
print(json.dumps(payload, indent=2, ensure_ascii=False))
|
|
if status >= 400:
|
|
sys.exit(1)
|
|
|
|
|
|
def cmd_issues_create(args: argparse.Namespace, base: str, token: str, owner: str, repo: str) -> None:
|
|
body = args.body or ""
|
|
if args.body_file:
|
|
body = Path(args.body_file).read_text(encoding="utf-8")
|
|
status, payload = issues_create(
|
|
base,
|
|
token,
|
|
owner,
|
|
repo,
|
|
title=args.title,
|
|
body=body,
|
|
labels=args.labels or [],
|
|
)
|
|
print(json.dumps(payload, indent=2, ensure_ascii=False))
|
|
if status >= 400:
|
|
sys.exit(1)
|
|
|
|
|
|
def cmd_issues_comment(args: argparse.Namespace, base: str, token: str, owner: str, repo: str) -> None:
|
|
body = args.body or ""
|
|
if getattr(args, "body_file", None):
|
|
body = Path(args.body_file).read_text(encoding="utf-8")
|
|
if not body.strip():
|
|
sys.stderr.write("issues comment: --body oder --body-file mit Inhalt erforderlich\n")
|
|
sys.exit(2)
|
|
status, payload = issues_comment(
|
|
base, token, owner, repo, args.number, body
|
|
)
|
|
print(json.dumps(payload, indent=2, ensure_ascii=False))
|
|
if status >= 400:
|
|
sys.exit(1)
|
|
|
|
|
|
def cmd_issues_close(args: argparse.Namespace, base: str, token: str, owner: str, repo: str) -> None:
|
|
status, payload = issues_patch(
|
|
base, token, owner, repo, args.number, {"state": "closed"}
|
|
)
|
|
print(json.dumps(payload, indent=2, ensure_ascii=False))
|
|
if status >= 400:
|
|
sys.exit(1)
|
|
|
|
|
|
def cmd_issues_reopen(args: argparse.Namespace, base: str, token: str, owner: str, repo: str) -> None:
|
|
status, payload = issues_patch(
|
|
base, token, owner, repo, args.number, {"state": "open"}
|
|
)
|
|
print(json.dumps(payload, indent=2, ensure_ascii=False))
|
|
if status >= 400:
|
|
sys.exit(1)
|
|
|
|
|
|
def cmd_repo_contents(args: argparse.Namespace, base: str, token: str, owner: str, repo: str) -> None:
|
|
status, payload = repo_file_content(
|
|
base, token, owner, repo, args.path, ref=args.ref or ""
|
|
)
|
|
if status >= 400:
|
|
print(json.dumps(payload, indent=2, ensure_ascii=False))
|
|
sys.exit(1)
|
|
if isinstance(payload, dict) and payload.get("encoding") == "text":
|
|
print(payload.get("content", ""))
|
|
else:
|
|
print(json.dumps(payload, indent=2, ensure_ascii=False))
|
|
|
|
|
|
def main() -> None:
|
|
if hasattr(sys.stdout, "reconfigure"):
|
|
try:
|
|
sys.stdout.reconfigure(encoding="utf-8")
|
|
except Exception:
|
|
pass
|
|
root = repo_root()
|
|
load_dotenv(root)
|
|
|
|
parser = argparse.ArgumentParser(description="Gitea API helper")
|
|
sub = parser.add_subparsers(dest="domain", required=True)
|
|
|
|
p_issues = sub.add_parser("issues", help="Issues")
|
|
i_sub = p_issues.add_subparsers(dest="issues_cmd", required=True)
|
|
|
|
p_il = i_sub.add_parser("list", help="List issues")
|
|
p_il.add_argument("--state", default="open", choices=["open", "closed", "all"])
|
|
p_il.add_argument("--limit", type=int, default=50)
|
|
p_il.add_argument("--page", type=int, default=1)
|
|
p_il.add_argument(
|
|
"--all-pages",
|
|
action="store_true",
|
|
help="Alle Seiten abfragen (Vorsicht bei sehr vielen Issues)",
|
|
)
|
|
p_il.set_defaults(_handler=cmd_issues_list)
|
|
|
|
p_ig = i_sub.add_parser("get", help="Get one issue")
|
|
p_ig.add_argument("number", type=int)
|
|
p_ig.set_defaults(_handler=cmd_issues_get)
|
|
|
|
p_ic = i_sub.add_parser("create", help="Create issue")
|
|
p_ic.add_argument("--title", required=True)
|
|
p_ic.add_argument("--body", default="")
|
|
p_ic.add_argument("--body-file")
|
|
p_ic.add_argument("--labels", nargs="*", default=[])
|
|
p_ic.set_defaults(_handler=cmd_issues_create)
|
|
|
|
p_co = i_sub.add_parser("comment", help="Add comment")
|
|
p_co.add_argument("number", type=int)
|
|
p_co.add_argument("--body", default="")
|
|
p_co.add_argument("--body-file", help="Kommentar aus Datei (UTF-8); überschreibt --body wenn gesetzt")
|
|
p_co.set_defaults(_handler=cmd_issues_comment)
|
|
|
|
p_cl = i_sub.add_parser("close", help="Close issue")
|
|
p_cl.add_argument("number", type=int)
|
|
p_cl.set_defaults(_handler=cmd_issues_close)
|
|
|
|
p_ro = i_sub.add_parser("reopen", help="Reopen issue")
|
|
p_ro.add_argument("number", type=int)
|
|
p_ro.set_defaults(_handler=cmd_issues_reopen)
|
|
|
|
p_repo = sub.add_parser("repo", help="Repository (API)")
|
|
r_sub = p_repo.add_subparsers(dest="repo_cmd", required=True)
|
|
|
|
p_rc = r_sub.add_parser("file", help="Get file or directory metadata/content")
|
|
p_rc.add_argument("path")
|
|
p_rc.add_argument("--ref", default="", help="branch/tag/commit")
|
|
p_rc.set_defaults(_handler=cmd_repo_contents)
|
|
|
|
args = parser.parse_args()
|
|
try:
|
|
base, token, owner, reponame = require_config()
|
|
except RuntimeError as e:
|
|
sys.stderr.write(str(e) + "\n")
|
|
sys.exit(1)
|
|
|
|
handler = args._handler
|
|
handler(args, base, token, owner, reponame)
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main()
|