[teamai] Push 87 resource(s) from XingfenD
This commit is contained in:
@@ -0,0 +1,68 @@
|
||||
"""Background checkout refresh."""
|
||||
|
||||
import subprocess
|
||||
import threading
|
||||
|
||||
|
||||
def fetch_status(path, result, key):
|
||||
"""Background worker: `git fetch` a local checkout and count how far
|
||||
behind its upstream it is. Writes into result[key]; NEVER raises — any
|
||||
failure is recorded as {"error": ...} so the main flow is never blocked."""
|
||||
info = {"path": path}
|
||||
try:
|
||||
remotes = subprocess.run(
|
||||
["git", "-C", path, "remote"],
|
||||
capture_output=True, text=True,
|
||||
).stdout.strip()
|
||||
if not remotes:
|
||||
info["no_upstream"] = True
|
||||
result[key] = info
|
||||
return
|
||||
f = subprocess.run(
|
||||
["git", "-C", path, "fetch", "--quiet", "origin"],
|
||||
capture_output=True, text=True, timeout=300,
|
||||
)
|
||||
if f.returncode != 0:
|
||||
lines = [ln for ln in f.stderr.strip().splitlines() if ln.strip()]
|
||||
info["error"] = lines[-1] if lines else "git fetch failed"
|
||||
else:
|
||||
up = subprocess.run(
|
||||
["git", "-C", path, "rev-parse", "--abbrev-ref",
|
||||
"--symbolic-full-name", "@{upstream}"],
|
||||
capture_output=True, text=True,
|
||||
)
|
||||
head = subprocess.run(
|
||||
["git", "-C", path, "rev-parse", "--abbrev-ref", "HEAD"],
|
||||
capture_output=True, text=True,
|
||||
).stdout.strip()
|
||||
if up.returncode != 0 or head in ("", "HEAD"):
|
||||
info["no_upstream"] = True
|
||||
else:
|
||||
cnt = subprocess.run(
|
||||
["git", "-C", path, "rev-list", "--count",
|
||||
f"HEAD..{up.stdout.strip()}"],
|
||||
capture_output=True, text=True,
|
||||
)
|
||||
if cnt.returncode == 0 and cnt.stdout.strip().isdigit():
|
||||
info["behind"] = int(cnt.stdout.strip())
|
||||
else:
|
||||
info["no_upstream"] = True
|
||||
except (subprocess.SubprocessError, OSError, ValueError) as e:
|
||||
# ponytail: broad catch is the point — refresh must never be fatal
|
||||
info["error"] = str(e)
|
||||
result[key] = info
|
||||
|
||||
|
||||
def start_refresh(framework_paths):
|
||||
"""Spawn daemon threads to refresh local checkouts concurrently.
|
||||
|
||||
Returns (results_dict, threads); results are filled in as workers finish.
|
||||
"""
|
||||
results = {}
|
||||
threads = []
|
||||
for key, path in framework_paths.items():
|
||||
t = threading.Thread(target=fetch_status, args=(path, results, key),
|
||||
daemon=True)
|
||||
t.start()
|
||||
threads.append(t)
|
||||
return results, threads
|
||||
Reference in New Issue
Block a user