internal/cli:stalled 與 xrefs 命令接線,完成 #7 CLI 層(堆疊於 #23)
- workflow 新增 StalledSource 介面(Source+CurrentUser+GetIssue)與 高階入口 RunStalled/ResolveIssueXrefs(xrefs 輸出附 source 出處) - APIClient 補上 StalledSource 面向(GetIssue/TryGetIssue 等) - CLI 新增 teai stalled [--hours N](JSON 與 gitea.py 位元組相容: 停用 HTML 轉義、縮排 2)與 teai xrefs <owner>/<repo> <number> (404 → exit 3);table 模式 stalled_hours 定點一位小數 - 接線層與 workflow 層單元測試(注入假資料源、固定時刻) - README 狀態行更新 驗證:go build/vet/test 全綠;對真實 API 並行掃描,stalled 輸出 與 gitea.py 位元組一致(2169 bytes);xrefs 邊界案例(PR#50/ issue#49 略過、CJK 緊鄰、跨倉庫 owner/repo#N)與 Python 版一致。
This commit is contained in:
@@ -122,3 +122,56 @@ func (a *APIClient) ListComments(owner, repo string, number int64) ([]Comment, e
|
||||
}
|
||||
return comments, nil
|
||||
}
|
||||
|
||||
// ── StalledSource 面向(#7 CLI 接線)────────────────────────────────────
|
||||
// APIClient 在 Client 之外同時實作 StalledSource(Source + CurrentUser +
|
||||
// GetIssue),讓 stalled/xrefs 命令與既有命令共用同一個 HTTP 用戶端。
|
||||
// 清單類方法直接委派 Client 同名操作,語義一致(type=issues、state=open)。
|
||||
|
||||
// GetIssue 單一 issue 查詢(PR 亦經此端點,帶 pull_request 標記);
|
||||
// 失敗(含 404)回 *gitea.ErrAPI,由 CLI 映射結束碼 3。
|
||||
func (a *APIClient) GetIssue(owner, repo string, number int64) (Issue, error) {
|
||||
var issue Issue
|
||||
path := "/repos/" + url.PathEscape(owner) + "/" + url.PathEscape(repo) +
|
||||
"/issues/" + strconv.FormatInt(number, 10)
|
||||
if err := a.Client.GetJSON(context.Background(), path, &issue); err != nil {
|
||||
return Issue{}, err
|
||||
}
|
||||
return issue, nil
|
||||
}
|
||||
|
||||
// TryGetIssue 寬容版單一 issue 查詢:失敗(含 404)回 (零值, false, nil),
|
||||
// 供 stalled 父追蹤項掃描靜默略過不存在的子項(Source 介面契約)。
|
||||
func (a *APIClient) TryGetIssue(owner, repo string, number int64) (Issue, bool, error) {
|
||||
issue, err := a.GetIssue(owner, repo, number)
|
||||
if err != nil {
|
||||
return Issue{}, false, nil
|
||||
}
|
||||
return issue, true, nil
|
||||
}
|
||||
|
||||
// MyOrganizations 委派 ListOrgs(Source 面向)。
|
||||
func (a *APIClient) MyOrganizations() ([]string, error) { return a.ListOrgs() }
|
||||
|
||||
// OrganizationRepositories 委派 ListOrgRepos(Source 面向)。
|
||||
func (a *APIClient) OrganizationRepositories(org string) ([]Repo, error) {
|
||||
return a.ListOrgRepos(org)
|
||||
}
|
||||
|
||||
// OpenIssues 委派 ListIssues(Source 面向;已排除 PR)。
|
||||
func (a *APIClient) OpenIssues(owner, repo string) ([]Issue, error) {
|
||||
return a.ListIssues(owner, repo)
|
||||
}
|
||||
|
||||
// OpenPulls 委派 ListPulls(Source 面向)。
|
||||
func (a *APIClient) OpenPulls(owner, repo string) ([]PullRequest, error) {
|
||||
return a.ListPulls(owner, repo)
|
||||
}
|
||||
|
||||
// IssueComments 委派 ListComments(Source 面向)。
|
||||
func (a *APIClient) IssueComments(owner, repo string, number int64) ([]Comment, error) {
|
||||
return a.ListComments(owner, repo, number)
|
||||
}
|
||||
|
||||
// 編譯期確認 APIClient 同時實作 Client 與 StalledSource。
|
||||
var _ StalledSource = (*APIClient)(nil)
|
||||
|
||||
Reference in New Issue
Block a user