Compare commits
1 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 9f0872c36a |
+29
-42
@@ -56,27 +56,6 @@ def _req(method, path, data=None):
|
|||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
|
||||||
|
|
||||||
def _req_safe(method, path, data=None):
|
|
||||||
"""Like _req but returns None on HTTPError instead of crashing.
|
|
||||||
Used for probing issue/PR existence where the caller can handle absence.
|
|
||||||
"""
|
|
||||||
url = f"{BASE}{path}"
|
|
||||||
payload = json.dumps(data).encode("utf-8") if data else None
|
|
||||||
req = urllib.request.Request(url, data=payload, method=method)
|
|
||||||
req.add_header("Authorization", f"token {GITEA_TOKEN}")
|
|
||||||
req.add_header("Content-Type", "application/json")
|
|
||||||
try:
|
|
||||||
with urllib.request.urlopen(req) as resp:
|
|
||||||
raw = resp.read()
|
|
||||||
if not raw:
|
|
||||||
return {}
|
|
||||||
return json.loads(raw)
|
|
||||||
except urllib.error.HTTPError as e:
|
|
||||||
body = e.read().decode()
|
|
||||||
print(f"API Error {e.code}: {body}", file=sys.stderr)
|
|
||||||
return None
|
|
||||||
|
|
||||||
|
|
||||||
# ── Issue operations ─────────────────────────────────────────────────────────
|
# ── Issue operations ─────────────────────────────────────────────────────────
|
||||||
|
|
||||||
def list_issues(labels: list[str] | None = None):
|
def list_issues(labels: list[str] | None = None):
|
||||||
@@ -103,17 +82,17 @@ def _get_blocking_refs(issue_num: int) -> set[int]:
|
|||||||
"""
|
"""
|
||||||
refs: set[int] = set()
|
refs: set[int] = set()
|
||||||
# Body
|
# Body
|
||||||
issue = _req_safe("GET", f"/issues/{issue_num}")
|
issue = _req("GET", f"/issues/{issue_num}")
|
||||||
if issue is None:
|
|
||||||
return refs # API error → return empty set, keep blocked
|
|
||||||
body = issue.get("body", "") or ""
|
body = issue.get("body", "") or ""
|
||||||
refs.update(int(m.group(1)) for m in re.finditer(r'#(\d+)', body))
|
refs.update(int(m.group(1)) for m in re.finditer(r'#(\d+)', body))
|
||||||
# Comments
|
# Comments
|
||||||
comments = _req_safe("GET", f"/issues/{issue_num}/comments")
|
try:
|
||||||
if comments:
|
comments = _req("GET", f"/issues/{issue_num}/comments")
|
||||||
for c in comments:
|
for c in comments:
|
||||||
cbody = c.get("body", "") or ""
|
cbody = c.get("body", "") or ""
|
||||||
refs.update(int(m.group(1)) for m in re.finditer(r'#(\d+)', cbody))
|
refs.update(int(m.group(1)) for m in re.finditer(r'#(\d+)', cbody))
|
||||||
|
except SystemExit:
|
||||||
|
pass
|
||||||
return refs
|
return refs
|
||||||
|
|
||||||
|
|
||||||
@@ -124,7 +103,12 @@ def blocked_check():
|
|||||||
If no references found or all referenced issues are closed,
|
If no references found or all referenced issues are closed,
|
||||||
removes the 'blocked' label.
|
removes the 'blocked' label.
|
||||||
"""
|
"""
|
||||||
all_blocked = _req_safe("GET", "/issues?state=open&labels=blocked")
|
try:
|
||||||
|
all_blocked = _req("GET", "/issues?state=open&labels=blocked")
|
||||||
|
except SystemExit:
|
||||||
|
print("No blocked issues found.")
|
||||||
|
return
|
||||||
|
|
||||||
if not all_blocked:
|
if not all_blocked:
|
||||||
print("No blocked issues found.")
|
print("No blocked issues found.")
|
||||||
return
|
return
|
||||||
@@ -135,13 +119,13 @@ def blocked_check():
|
|||||||
|
|
||||||
all_resolved = True
|
all_resolved = True
|
||||||
for blk in blocking_nums:
|
for blk in blocking_nums:
|
||||||
blk_issue = _req_safe("GET", f"/issues/{blk}")
|
try:
|
||||||
if blk_issue is None:
|
blk_issue = _req("GET", f"/issues/{blk}")
|
||||||
all_resolved = False # API error → keep blocked
|
if blk_issue.get("state") != "closed":
|
||||||
break
|
all_resolved = False
|
||||||
if blk_issue.get("state") != "closed":
|
break
|
||||||
all_resolved = False
|
except SystemExit:
|
||||||
break
|
pass
|
||||||
|
|
||||||
if all_resolved:
|
if all_resolved:
|
||||||
current_label_names = [l["name"] for l in issue.get("labels", [])]
|
current_label_names = [l["name"] for l in issue.get("labels", [])]
|
||||||
@@ -195,7 +179,10 @@ def _unblock_issues_blocked_by(closed_num):
|
|||||||
in any blocked issue and all referenced issues are now closed,
|
in any blocked issue and all referenced issues are now closed,
|
||||||
removes the 'blocked' label and comments on the unblocked issue.
|
removes the 'blocked' label and comments on the unblocked issue.
|
||||||
"""
|
"""
|
||||||
all_blocked = _req_safe("GET", "/issues?state=open&labels=blocked")
|
try:
|
||||||
|
all_blocked = _req("GET", "/issues?state=open&labels=blocked")
|
||||||
|
except SystemExit:
|
||||||
|
return
|
||||||
if not all_blocked:
|
if not all_blocked:
|
||||||
return
|
return
|
||||||
|
|
||||||
@@ -209,13 +196,13 @@ def _unblock_issues_blocked_by(closed_num):
|
|||||||
for blk in blocking_nums:
|
for blk in blocking_nums:
|
||||||
if blk == closed_num:
|
if blk == closed_num:
|
||||||
continue
|
continue
|
||||||
blk_issue = _req_safe("GET", f"/issues/{blk}")
|
try:
|
||||||
if blk_issue is None:
|
blk_issue = _req("GET", f"/issues/{blk}")
|
||||||
all_resolved = False # API error → keep blocked
|
if blk_issue.get("state") != "closed":
|
||||||
break
|
all_resolved = False
|
||||||
if blk_issue.get("state") != "closed":
|
break
|
||||||
all_resolved = False
|
except SystemExit:
|
||||||
break
|
pass # Inaccessible → treat as resolved
|
||||||
|
|
||||||
if all_resolved:
|
if all_resolved:
|
||||||
current_label_names = [l["name"] for l in issue.get("labels", [])]
|
current_label_names = [l["name"] for l in issue.get("labels", [])]
|
||||||
|
|||||||
Reference in New Issue
Block a user