change defaults + remote path support

This commit is contained in:
Daniel Edrisian
2025-09-02 19:57:09 -07:00
parent 91bb558007
commit 491f8e5e6f

View File

@@ -10,6 +10,8 @@ import sys
import tempfile
import threading
from typing import Any, Dict, List, Optional, Tuple
from urllib.parse import urlparse
from urllib.request import urlopen
def _run(cmd: List[str], input_text: Optional[str] = None) -> Tuple[int, str, str]:
@@ -106,6 +108,13 @@ def load_reviewer_json(reviewer: str) -> Optional[Dict[str, Any]]:
except Exception:
return None
def is_https_url(s: str) -> bool:
try:
return s.startswith("https://")
except Exception:
return False
def load_json_from_path(path: str) -> Optional[Dict[str, Any]]:
try:
with open(path, "r", encoding="utf-8") as f:
@@ -114,6 +123,41 @@ def load_json_from_path(path: str) -> Optional[Dict[str, Any]]:
return None
def load_json_from_source(source: str) -> Optional[Dict[str, Any]]:
if is_https_url(source):
try:
with urlopen(source, timeout=30) as resp:
if resp.status != 200:
return None
data = resp.read()
return json.loads(data.decode("utf-8"))
except Exception:
return None
return load_json_from_path(source)
def reviewer_from_source(source: str, data: Optional[Dict[str, Any]]) -> str:
# Prefer explicit name inside JSON
name = None
try:
name = (data or {}).get("reviewer")
except Exception:
name = None
if isinstance(name, str) and name.strip():
return name.strip()
# Fallback: stem from path or URL
if is_https_url(source):
try:
p = urlparse(source)
base = os.path.basename(p.path)
stem = os.path.splitext(base)[0]
return stem or "reviewer"
except Exception:
return "reviewer"
base = os.path.basename(source)
return os.path.splitext(base)[0] or "reviewer"
def save_reviewer_json(reviewer: str, data: Dict[str, Any]):
"""Atomically write reviewers/<reviewer>.json to avoid corruption on interrupts."""
p = reviewers_json_path(reviewer)
@@ -644,8 +688,8 @@ def study_cli(argv: List[str]):
parser = argparse.ArgumentParser(prog="review study", description="Generate studyguides into reviewers/<user>.json and dump files.")
parser.add_argument("reviewer", nargs="?", help="GitHub login")
parser.add_argument("--profile", "-p", help="Path to reviewers JSON; overrides reviewer and save path")
parser.add_argument("--days", "-d", type=int, default=30, help="Look back N days for PRs (default: 30)")
parser.add_argument("--jobs", "-j", type=int, default=10, help="Parallel jobs (default: 10)")
parser.add_argument("--days", "-d", type=int, default=100, help="Look back N days for PRs (default: 30)")
parser.add_argument("--jobs", "-j", type=int, default=200, help="Parallel jobs (default: 10)")
parser.add_argument("--limit", "-n", type=int, default=None, help="Limit number of PRs processed")
parser.add_argument("--debug", action="store_true", help="Do not clear reviewers/dump/<reviewer> before running")
parser.add_argument("--force", action="store_true", help="Regenerate studyguides even if present")
@@ -662,11 +706,11 @@ def study_cli(argv: List[str]):
reviewer: Optional[str] = None
if profile_path:
data = load_json_from_path(profile_path)
data = load_json_from_source(profile_path)
if data is None:
print(f"Error: profile not found or invalid JSON: {profile_path}", file=sys.stderr)
sys.exit(2)
reviewer = str(data.get("reviewer") or os.path.splitext(os.path.basename(profile_path))[0])
reviewer = reviewer_from_source(profile_path, data)
else:
if not reviewer_arg:
print("Error: reviewer is required when --profile is not provided.", file=sys.stderr)
@@ -725,11 +769,15 @@ def study_cli(argv: List[str]):
limit=args.limit,
debug=args.debug,
force=args.force,
save_path=profile_path,
save_path=None if (profile_path and is_https_url(profile_path)) else profile_path,
)
if profile_path:
save_json_to_path(profile_path, data)
print(f"Updated {profile_path} with studyguides.")
if is_https_url(profile_path):
save_reviewer_json(reviewer, data)
print(f"Source was remote. Updated reviewers/{reviewer}.json with studyguides.")
else:
save_json_to_path(profile_path, data)
print(f"Updated {profile_path} with studyguides.")
else:
save_reviewer_json(reviewer, data)
print(f"Updated reviewers/{reviewer}.json with studyguides.")
@@ -778,11 +826,11 @@ def main():
# Resolve reviewer and dataset
if profile_path:
data = load_json_from_path(profile_path)
data = load_json_from_source(profile_path)
if data is None:
print(f"Error: profile not found or invalid JSON: {profile_path}", file=sys.stderr)
sys.exit(2)
reviewer = str(data.get("reviewer") or os.path.splitext(os.path.basename(profile_path))[0])
reviewer = reviewer_from_source(profile_path, data)
else:
reviewer = args.reviewer
if not reviewer: