feat(timer): 碼錶移出領取,等工作樹建成之後才起
原本的順序是「放行 → 設 assignee 與標籤 → 起錶 → 處理分支」,而工作樹建立 失敗會中止整個領取——錶已經起了才失敗,使用者會被計一段什麼都沒做的時間, 而工時要準正是工時報表的立足點。 claim 只留領取鎖的兩件事(assignee 與標籤),起錶交給新的 timer.js,由流程 正本排在 branch-prep 之後。timer 已經跑在這顆議題上時什麼都不做:中斷後重跑 是它最常見的處境,重新起錶會把已經累積的時間切成兩段;跑在別顆上則照舊擋下, 不代勞停錶。 三支腳本讀碼錶的那段各留一份,趁這次收進 lib。 議題 #40 Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
+10
-11
@@ -1,10 +1,13 @@
|
||||
#!/usr/bin/env node
|
||||
/**
|
||||
* 領取一顆工作包:上鎖、貼標籤、起錶。
|
||||
* 領取一顆工作包:上鎖、貼標籤。
|
||||
*
|
||||
* 鎖用 assignee 加標籤,不用碼錶——Gitea 只讓人讀自己的碼錶(`/user/stopwatches`),
|
||||
* 看不到別人的錶,拿它當鎖會漏判。碼錶在這裡只有一個用途:發現自己忘了停掉上一顆。
|
||||
*
|
||||
* **錶不在這一步起**。它等工作樹建好之後才由 timer.js 起動(見 branch-prep.js):
|
||||
* 工作樹建立失敗會中止整個領取,錶要是先起了,使用者就被計了一段什麼都沒做的時間。
|
||||
*
|
||||
* 四種狀態的處置:
|
||||
* - 他人已認領 → 擋。不會兩個人做同一件事。
|
||||
* - 自己的錶跑在本議題 → 擋。這顆你已經在做了,別重複起錶。
|
||||
@@ -24,12 +27,14 @@ import {
|
||||
fetchIssue,
|
||||
giteaRequest,
|
||||
listLabels,
|
||||
listStopwatches,
|
||||
main,
|
||||
parseFlags,
|
||||
parseIndex,
|
||||
parseRepo,
|
||||
preflight,
|
||||
resolveLogin,
|
||||
stopwatchOnIssue,
|
||||
} from './lib.js';
|
||||
|
||||
/** 領取鎖的另一半。本 plugin 不自動建立標籤,這個名字要在 repo 上先存在。 */
|
||||
@@ -84,9 +89,6 @@ main(async () => {
|
||||
});
|
||||
labels.push(IN_PROGRESS);
|
||||
}
|
||||
// 錶最後才起:前面任一步失敗時,不該留下一顆還在跑的碼錶
|
||||
planned.push({ method: 'POST', path: `${issuePath}/stopwatch/start`, body: {} });
|
||||
|
||||
if (dryRun) {
|
||||
return { dryRun: true, repo, index, title: issue.title, requests: planned, 已認領過 };
|
||||
}
|
||||
@@ -102,7 +104,8 @@ main(async () => {
|
||||
url: issue.html_url,
|
||||
assignee: me,
|
||||
labels,
|
||||
碼錶中: true,
|
||||
// 鎖上好了,錶還沒起:它等工作樹建好之後才由 timer.js 起動
|
||||
碼錶中: false,
|
||||
已認領過,
|
||||
};
|
||||
});
|
||||
@@ -128,14 +131,10 @@ function checkClaimable(assignees, me, index) {
|
||||
* 跑在別的議題是「你忘了停掉那一顆」。
|
||||
*/
|
||||
async function checkNoStopwatch(login, repo, index) {
|
||||
const path = '/user/stopwatches';
|
||||
const watches = expectOk(await giteaRequest(login, 'GET', path), `GET ${path}`) ?? [];
|
||||
const watches = await listStopwatches(login);
|
||||
if (watches.length === 0) return;
|
||||
|
||||
const here = watches.find(
|
||||
(watch) => `${watch.repo_owner_name}/${watch.repo_name}` === repo && watch.issue_index === index,
|
||||
);
|
||||
if (here) {
|
||||
if (stopwatchOnIssue(watches, repo, index)) {
|
||||
throw new ScriptError(
|
||||
'STOPWATCH_ON_THIS_ISSUE',
|
||||
`你的碼錶已經跑在議題 #${index} 上,這顆你正在做;` +
|
||||
|
||||
Reference in New Issue
Block a user