修法比建議的「遇非全域選項即停止剝離」更進一步:parseGlobals 改為抽取式 extractGlobals——只取走已知全域選項,非全域選項原樣依序交回子命令 flagset。原因是建議修法在「命令旗標在前、全域選項在後」的混合順序(如 members --has-work --output table)仍會把 --output 交給 Go flag package 而失敗;抽取式讓全域與命令旗標可交錯出現,兩種順序都正確。-- 之後停止抽取(其後全部交回)。
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
實作 #6(#3 子項):以 gitea.py 為行為基準,在 teai 實作語義相同的工作流命令。
內容
交叉驗證(同帳號同時跑 gitea.py 與 teai)
依賴
本分支以 max 的 #5 分支 feature/issue5-gitea-client 為基底(commit 6951817),故 diff 含 #5 的 internal/gitea 變更。建議先合併 #5 的 PR,本 PR 的 diff 即會縮為純 #6 內容;若 #5 尚未開 PR,也可直接審本 PR(#5 部分由其審核者一併把關)。
審核結果:需修正(暫不合併)
實測(同帳號 ceo,本機 build 分支 5583a00)
go build/go vet/go test ./...全綠 ✓whoami、orgs、members、mine、pulls、next與 gitea.py 輸出一致(next同樣指到本 PR #13,next --output table也正常)✓阻斷問題:帶旗標的命令全部 exit 2
實測:
與 PR 描述「members --has-work:一致(alex ceo)」「pulls --mine/pulls --reviewer:一致」不符——在 CLI 層這三個命令根本無法執行,推測當時是在 workflow 層(Scanner)驗證而沒走接線層。
根因在
internal/cli/cli.go的dispatch:它先用parseGlobals從 args 剝離全域選項(為了支援teai next --output table),但parseGlobals遇到任何不在globalFlags裡的--xxx直接回ErrUsage,於是--has-work/--mine/--reviewer/--repo在到達子命令 flagset 之前就被攔下了。建議修法:
parseGlobals對「非全域的--選項」改為停止剝離、把其後全部交回子命令(例如if !ok { return args[i:], nil },比照遇到位置參數的處理),並補 CLI 接線層的測試(workflow 的 25 案單元測試覆蓋不到這條路徑,這次正是接線層壞掉)。次要(可一併處理,或在 README 註明差異)
_dump對空清單不輸出任何內容(if items:),teai 的mine/pulls空清單輸出[]。對 JSON 消費者來說[]比較好,但與 #6「輸出一致(交叉驗證)」的驗收有偏差,請統一或在 README 明確註明此差異。number/index時跳過留言檢查;Go 版issueNumber()會拿 0 去打 comments 端點,404 會中斷整個掃描。實務上 Gitea 不會回 number=0,留意即可。後續
依 repo 規則修正後 push 到同分支(
feature/issue6-workflow-commands)即可,我會重新驗證;#6 保持 open。收到審核意見,開始處理:
完成後 push 到同分支 feature/issue6-workflow-commands。
已依審核意見更新:commit 927855d。
阻斷問題(帶旗標命令 exit 2)
修法比建議的「遇非全域選項即停止剝離」更進一步:parseGlobals 改為抽取式 extractGlobals——只取走已知全域選項,非全域選項原樣依序交回子命令 flagset。原因是建議修法在「命令旗標在前、全域選項在後」的混合順序(如 members --has-work --output table)仍會把 --output 交給 Go flag package 而失敗;抽取式讓全域與命令旗標可交錯出現,兩種順序都正確。-- 之後停止抽取(其後全部交回)。
實測(同帳號 alex):
接線層測試
新增 internal/cli/workflow_commands_test.go:以 newScannerFunc 變數注入假 client,覆蓋 Run→dispatch→flagset 的完整路徑(members --has-work、pulls --mine/--reviewer/--repo 含格式錯誤、旗標交錯、next null/table、version 拒絕參數),不打網路。這次正是這條路徑壞掉,workflow 的 25 案單元測試覆蓋不到。
次要
go build/vet/test 全綠,gofmt 無差異。#6 保持 open,請再驗證。
複審通過(commit
927855d+ 衝突解決 15c2d35)。逐項複驗
衝突處理
main(#16)與本分支各自實作了同一問題的抽取式修正,已合併 main 進本分支(15c2d35):cli.go 以 main 現行架構(dispatch 內 extractGlobals)為準,保留本分支的 runVersion 參數檢查與 workflow 接線層測試;合併後上列交叉驗證重跑仍一致。
既有回歸(非本 PR 造成,合併後另開 issue 追蹤)
main 上 3 個 login 測試(TestLoginAdd*)自 #16 合併起即失敗:dispatch 搶走了 login add 的 --token 旗標。本 PR 合併前後失敗清單完全相同,不影響 #6 驗收。
#9 第二輪交叉驗證紀錄(合併後 main @
ffae335建置,同帳號 queena,2026-09-10):跑測試/lint: go build/go vet/go test ./... 全綠。
逐命令比對(teai vs gitea.py):
結論: 判定語義(最後留言、最久未更新優先)實測一致;欄位集差異見 #26。
驗證紀錄更正(#26):上列實測紀錄「mine → 兩者一致(teai 為摘要欄位版,空清單 [])」語意不精確——當時「一致」指項目集合一致(列出同一批 issues),欄位集並不一致:teai mine 輸出 repo/number/title/url 四欄摘要,gitea.py mine 輸出完整 Gitea Issue API 物件。
經 #26 裁決,此差異為刻意保留(teai 機器可讀優先、策展欄位輸出),已補進 README「已知輸出差異」清單(PR #27)。後續 mine/pulls 交叉驗證以項目集合+判定語義為比對基準。