logbook: statistics run on a clean detached snapshot of main ([logbook] snapshot), not the integrator's live checkout, which is often mid-batch; a failed run retries on the next tick instead of waiting for main to move
This commit is contained in:
1 parent
d7464aaa40
commit
a3fc48802c
1 file changed
+19
-2
+19
-2
@@ -109,6 +109,21 @@ def rebuild_stats(project, repo, stats_repo, head):
|
|||||||
return {"classified": stats.get("classified_percent"), "weighted": stats.get("weighted_percent")}
|
return {"classified": stats.get("classified_percent"), "weighted": stats.get("weighted_percent")}
|
||||||
|
|
||||||
|
|
||||||
|
def snapshot_at(config, repo, head):
|
||||||
|
"""A clean checkout of `head` for the statistics: [logbook] snapshot, a detached worktree of the decomp repository
|
||||||
|
that only this refresher uses. The live checkout is the integrator's and is often mid-batch with uncommitted
|
||||||
|
files, which the statistics tools rightly refuse. Without a snapshot setting, the live checkout is used."""
|
||||||
|
snapshot = config.get("snapshot")
|
||||||
|
if not snapshot:
|
||||||
|
return repo
|
||||||
|
path = Path(snapshot)
|
||||||
|
if not (path / ".git").exists():
|
||||||
|
_git(repo, "worktree", "add", "--detach", str(path), head)
|
||||||
|
else:
|
||||||
|
_git(str(path), "checkout", "--detach", "--force", head)
|
||||||
|
return str(path)
|
||||||
|
|
||||||
|
|
||||||
def refresh(project, force=False):
|
def refresh(project, force=False):
|
||||||
"""Bring the Logbook up to main. Returns what changed."""
|
"""Bring the Logbook up to main. Returns what changed."""
|
||||||
config = getattr(project, "logbook", None) or {}
|
config = getattr(project, "logbook", None) or {}
|
||||||
@@ -127,10 +142,12 @@ def refresh(project, force=False):
|
|||||||
out["log_error"] = str(error)
|
out["log_error"] = str(error)
|
||||||
if stats_repo:
|
if stats_repo:
|
||||||
try:
|
try:
|
||||||
out["stats"] = rebuild_stats(project, repo, stats_repo, head)
|
out["stats"] = rebuild_stats(project, snapshot_at(config, repo, head), stats_repo, head)
|
||||||
except (RuntimeError, OSError, ValueError, subprocess.TimeoutExpired) as error:
|
except (RuntimeError, OSError, ValueError, subprocess.TimeoutExpired) as error:
|
||||||
out["stats_error"] = str(error)
|
out["stats_error"] = str(error)
|
||||||
_save_state(project, {**state, "last_head": head, "last_refresh": logbook.now(),
|
# a failed statistics run is retried next time, instead of waiting for main to move again
|
||||||
|
done_head = state.get("last_head") if out.get("stats_error") else head
|
||||||
|
_save_state(project, {**state, "last_head": done_head, "last_refresh": logbook.now(),
|
||||||
**({"last_error": out.get("stats_error") or out.get("log_error")}
|
**({"last_error": out.get("stats_error") or out.get("log_error")}
|
||||||
if out.get("stats_error") or out.get("log_error") else {"last_error": None})})
|
if out.get("stats_error") or out.get("log_error") else {"last_error": None})})
|
||||||
return out
|
return out
|
||||||
|
|||||||
Reference in new issue
Block a user