Skip to content

Commit 35860a2

Browse files
Thomas StrombergThomas Stromberg
authored andcommitted
more code reorganization
1 parent c2cc72d commit 35860a2

18 files changed

+535
-563
lines changed

cmd/prx/main.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -115,7 +115,8 @@ func githubToken() (string, error) {
115115
return token, nil
116116
}
117117

118-
func parsePRURL(prURL string) (owner, repo string, prNumber int, err error) { //nolint:revive // Function needs all 4 return values
118+
//nolint:revive // function-result-limit: function needs all 4 return values
119+
func parsePRURL(prURL string) (owner, repo string, prNumber int, err error) {
119120
u, err := url.Parse(prURL)
120121
if err != nil {
121122
return "", "", 0, err

pkg/prx/check_run_history_test.go

Lines changed: 2 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -164,11 +164,7 @@ func TestCheckRunHistory_MultipleCommits(t *testing.T) {
164164

165165
httpClient := &http.Client{Transport: http.DefaultTransport}
166166
client := NewClient("test-token", WithHTTPClient(httpClient))
167-
client.github = &githubClient{
168-
client: httpClient,
169-
token: "test-token",
170-
api: server.URL,
171-
}
167+
client.github = newTestGitHubClient(httpClient, "test-token", server.URL)
172168

173169
ctx := context.Background()
174170
prData, err := client.PullRequest(ctx, "codeGROOVE-dev", "slacker", 66)
@@ -319,11 +315,7 @@ func TestCheckRunHistory_CommitSHAPreservation(t *testing.T) {
319315

320316
httpClient := &http.Client{Transport: http.DefaultTransport}
321317
client := NewClient("test-token", WithHTTPClient(httpClient))
322-
client.github = &githubClient{
323-
client: httpClient,
324-
token: "test-token",
325-
api: server.URL,
326-
}
318+
client.github = newTestGitHubClient(httpClient, "test-token", server.URL)
327319

328320
ctx := context.Background()
329321
prData, err := client.PullRequest(ctx, "testowner", "testrepo", 100)

pkg/prx/checks_test.go

Lines changed: 2 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -127,11 +127,7 @@ func TestClient_PullRequestWithCheckRuns(t *testing.T) {
127127

128128
httpClient := &http.Client{Transport: http.DefaultTransport}
129129
client := NewClient("test-token", WithHTTPClient(httpClient))
130-
client.github = &githubClient{
131-
client: httpClient,
132-
token: "test-token",
133-
api: server.URL,
134-
}
130+
client.github = newTestGitHubClient(httpClient, "test-token", server.URL)
135131

136132
ctx := context.Background()
137133
prData, err := client.PullRequest(ctx, "testowner", "testrepo", 555)
@@ -243,11 +239,7 @@ func TestClient_PullRequestWithBranchProtection(t *testing.T) {
243239

244240
httpClient := &http.Client{Transport: http.DefaultTransport}
245241
client := NewClient("test-token", WithHTTPClient(httpClient))
246-
client.github = &githubClient{
247-
client: httpClient,
248-
token: "test-token",
249-
api: server.URL,
250-
}
242+
client.github = newTestGitHubClient(httpClient, "test-token", server.URL)
251243

252244
ctx := context.Background()
253245
prData, err := client.PullRequest(ctx, "testowner", "testrepo", 666)

pkg/prx/client.go

Lines changed: 12 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@ import (
77
"context"
88
"crypto/sha256"
99
"encoding/hex"
10-
"encoding/json"
1110
"errors"
1211
"fmt"
1312
"log/slog"
@@ -18,6 +17,7 @@ import (
1817
"strings"
1918
"time"
2019

20+
"github.com/codeGROOVE-dev/prx/pkg/prx/github"
2121
"github.com/codeGROOVE-dev/sfcache"
2222
"github.com/codeGROOVE-dev/sfcache/pkg/store/localfs"
2323
)
@@ -39,11 +39,7 @@ type PRStore = sfcache.Store[string, PullRequestData]
3939

4040
// Client provides methods to fetch GitHub pull request events.
4141
type Client struct {
42-
github interface {
43-
get(ctx context.Context, path string, v any) (*githubResponse, error)
44-
raw(ctx context.Context, path string) (json.RawMessage, *githubResponse, error)
45-
collaborators(ctx context.Context, owner, repo string) (map[string]string, error)
46-
}
42+
github *github.Client
4743
logger *slog.Logger
4844
collaboratorsCache *sfcache.MemoryCache[string, map[string]string]
4945
prCache *sfcache.TieredCache[string, PullRequestData]
@@ -65,11 +61,11 @@ func WithHTTPClient(httpClient *http.Client) Option {
6561
return func(c *Client) {
6662
// Wrap the transport with retry logic if not already wrapped
6763
if httpClient.Transport == nil {
68-
httpClient.Transport = &RetryTransport{Base: http.DefaultTransport}
69-
} else if _, ok := httpClient.Transport.(*RetryTransport); !ok {
70-
httpClient.Transport = &RetryTransport{Base: httpClient.Transport}
64+
httpClient.Transport = &github.Transport{Base: http.DefaultTransport}
65+
} else if _, ok := httpClient.Transport.(*github.Transport); !ok {
66+
httpClient.Transport = &github.Transport{Base: httpClient.Transport}
7167
}
72-
c.github = &githubClient{client: httpClient, token: c.token, api: githubAPI}
68+
c.github = newGitHubClient(httpClient, c.token, github.API)
7369
}
7470
}
7571

@@ -102,14 +98,14 @@ func NewClient(token string, opts ...Option) *Client {
10298
logger: slog.Default(),
10399
token: token,
104100
collaboratorsCache: sfcache.New[string, map[string]string](sfcache.TTL(collaboratorsCacheTTL)),
105-
github: &githubClient{
106-
client: &http.Client{
107-
Transport: &RetryTransport{Base: transport},
101+
github: newGitHubClient(
102+
&http.Client{
103+
Transport: &github.Transport{Base: transport},
108104
Timeout: 30 * time.Second,
109105
},
110-
token: token,
111-
api: githubAPI,
112-
},
106+
token,
107+
github.API,
108+
),
113109
}
114110

115111
for _, opt := range opts {

pkg/prx/client_cache_test.go

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -96,9 +96,7 @@ func TestCacheClient(t *testing.T) {
9696
}()
9797

9898
// Override the GitHub client to use test server
99-
if gc, ok := client.github.(*githubClient); ok {
100-
gc.api = server.URL
101-
}
99+
client.github = newTestGitHubClient(&http.Client{Transport: &http.Transport{}}, "test-token", server.URL)
102100

103101
ctx := context.Background()
104102

pkg/prx/client_graphql.go

Lines changed: 41 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@ import (
77
"sort"
88
"strings"
99
"time"
10+
11+
"github.com/codeGROOVE-dev/prx/pkg/prx/github"
1012
)
1113

1214
// pullRequestViaGraphQL fetches pull request data using GraphQL with minimal REST fallbacks.
@@ -79,31 +81,31 @@ func (c *Client) pullRequestViaGraphQL(ctx context.Context, owner, repo string,
7981

8082
// fetchRulesetsREST fetches repository rulesets via REST API (not available in GraphQL).
8183
func (c *Client) fetchRulesetsREST(ctx context.Context, owner, repo string) ([]string, error) {
82-
rulesetPath := fmt.Sprintf("/repos/%s/%s/rulesets", owner, repo)
83-
var rulesets []githubRuleset
84+
path := fmt.Sprintf("/repos/%s/%s/rulesets", owner, repo)
85+
var rulesets []github.Ruleset
8486

85-
_, err := c.github.get(ctx, rulesetPath, &rulesets)
86-
if err != nil {
87+
if _, err := c.github.Get(ctx, path, &rulesets); err != nil {
8788
return nil, err
8889
}
8990

90-
var requiredChecks []string
91-
for _, ruleset := range rulesets {
92-
if ruleset.Target == "branch" {
93-
for _, rule := range ruleset.Rules {
94-
if rule.Type == "required_status_checks" && rule.Parameters.RequiredStatusChecks != nil {
95-
for _, check := range rule.Parameters.RequiredStatusChecks {
96-
requiredChecks = append(requiredChecks, check.Context)
97-
}
91+
var required []string
92+
for _, rs := range rulesets {
93+
if rs.Target != "branch" {
94+
continue
95+
}
96+
for _, rule := range rs.Rules {
97+
if rule.Type == "required_status_checks" && rule.Parameters.RequiredStatusChecks != nil {
98+
for _, chk := range rule.Parameters.RequiredStatusChecks {
99+
required = append(required, chk.Context)
98100
}
99101
}
100102
}
101103
}
102104

103105
c.logger.InfoContext(ctx, "fetched required checks from rulesets",
104-
"count", len(requiredChecks), "checks", requiredChecks)
106+
"count", len(required), "checks", required)
105107

106-
return requiredChecks, nil
108+
return required, nil
107109
}
108110

109111
// fetchCheckRunsREST fetches check runs via REST API for a specific commit.
@@ -113,8 +115,8 @@ func (c *Client) fetchCheckRunsREST(ctx context.Context, owner, repo, sha string
113115
}
114116

115117
path := fmt.Sprintf("/repos/%s/%s/commits/%s/check-runs?per_page=100", owner, repo, sha)
116-
var checkRuns githubCheckRuns
117-
if _, err := c.github.get(ctx, path, &checkRuns); err != nil {
118+
var checkRuns github.CheckRuns
119+
if _, err := c.github.Get(ctx, path, &checkRuns); err != nil {
118120
return nil, fmt.Errorf("fetching check runs: %w", err)
119121
}
120122

@@ -172,33 +174,26 @@ func (c *Client) fetchCheckRunsREST(ctx context.Context, owner, repo, sha string
172174
// Errors fetching individual commits are logged but don't stop the overall process.
173175
func (c *Client) fetchAllCheckRunsREST(ctx context.Context, owner, repo string, prData *PullRequestData) []Event {
174176
// Collect all unique commit SHAs from the PR
175-
commitSHAs := make([]string, 0)
177+
shas := make(map[string]bool)
176178

177179
// Add HEAD SHA (most important)
178180
if prData.PullRequest.HeadSHA != "" {
179-
commitSHAs = append(commitSHAs, prData.PullRequest.HeadSHA)
181+
shas[prData.PullRequest.HeadSHA] = true
180182
}
181183

182184
// Add all other commit SHAs from commit events
183185
for i := range prData.Events {
184186
e := &prData.Events[i]
185187
if e.Kind == "commit" && e.Body != "" {
186-
// Body contains the commit SHA for commit events
187-
commitSHAs = append(commitSHAs, e.Body)
188+
shas[e.Body] = true
188189
}
189190
}
190191

191-
// Deduplicate SHAs (in case HEAD is also in commit events)
192-
uniqueSHAs := make(map[string]bool)
193-
for _, sha := range commitSHAs {
194-
uniqueSHAs[sha] = true
195-
}
196-
197192
// Fetch check runs for each unique commit
198-
var allEvents []Event
199-
seenCheckRuns := make(map[string]bool) // Track unique check runs by "name:timestamp"
193+
var all []Event
194+
seen := make(map[string]bool) // Track unique check runs by "name:timestamp"
200195

201-
for sha := range uniqueSHAs {
196+
for sha := range shas {
202197
events, err := c.fetchCheckRunsREST(ctx, owner, repo, sha)
203198
if err != nil {
204199
c.logger.WarnContext(ctx, "failed to fetch check runs for commit", "sha", sha, "error", err)
@@ -207,19 +202,17 @@ func (c *Client) fetchAllCheckRunsREST(ctx context.Context, owner, repo string,
207202

208203
// Add only unique check runs (same check can run on multiple commits)
209204
for i := range events {
210-
event := &events[i]
211-
// Create a unique key based on check name and timestamp
212-
key := fmt.Sprintf("%s:%s", event.Body, event.Timestamp.Format(time.RFC3339Nano))
213-
if !seenCheckRuns[key] {
214-
seenCheckRuns[key] = true
215-
// Add the commit SHA to the Target field
216-
event.Target = sha
217-
allEvents = append(allEvents, *event)
205+
ev := &events[i]
206+
key := fmt.Sprintf("%s:%s", ev.Body, ev.Timestamp.Format(time.RFC3339Nano))
207+
if !seen[key] {
208+
seen[key] = true
209+
ev.Target = sha
210+
all = append(all, *ev)
218211
}
219212
}
220213
}
221214

222-
return allEvents
215+
return all
223216
}
224217

225218
// existingRequiredChecks extracts required checks that were already identified.
@@ -228,19 +221,17 @@ func (*Client) existingRequiredChecks(prData *PullRequestData) []string {
228221

229222
// Extract from existing events that are marked as required
230223
for i := range prData.Events {
231-
event := &prData.Events[i]
232-
if event.Required && (event.Kind == "check_run" || event.Kind == "status_check") {
233-
required = append(required, event.Body)
224+
e := &prData.Events[i]
225+
if e.Required && (e.Kind == "check_run" || e.Kind == "status_check") {
226+
required = append(required, e.Body)
234227
}
235228
}
236229

237230
// Also extract from pending checks in check summary (these are required but haven't run)
238231
if prData.PullRequest.CheckSummary != nil {
239-
for check := range prData.PullRequest.CheckSummary.Pending {
240-
// Check if it's not already in the list
241-
found := slices.Contains(required, check)
242-
if !found {
243-
required = append(required, check)
232+
for chk := range prData.PullRequest.CheckSummary.Pending {
233+
if !slices.Contains(required, chk) {
234+
required = append(required, chk)
244235
}
245236
}
246237
}
@@ -252,16 +243,16 @@ func (*Client) existingRequiredChecks(prData *PullRequestData) []string {
252243
// This recalculates the entire check summary from ALL events to ensure we have the latest state.
253244
func (c *Client) recalculateCheckSummaryWithCheckRuns(_ /* ctx */ context.Context, prData *PullRequestData, _ /* checkRunEvents */ []Event) {
254245
// Get existing required checks before we overwrite the summary
255-
var requiredChecks []string
246+
var required []string
256247
if prData.PullRequest.CheckSummary != nil {
257-
for check := range prData.PullRequest.CheckSummary.Pending {
258-
requiredChecks = append(requiredChecks, check)
248+
for chk := range prData.PullRequest.CheckSummary.Pending {
249+
required = append(required, chk)
259250
}
260251
}
261252

262253
// Recalculate the entire check summary from ALL events (including the new check runs)
263254
// This ensures we get the latest state based on timestamps
264-
prData.PullRequest.CheckSummary = calculateCheckSummary(prData.Events, requiredChecks)
255+
prData.PullRequest.CheckSummary = calculateCheckSummary(prData.Events, required)
265256

266257
// Update test state based on the recalculated check summary
267258
prData.PullRequest.TestState = c.calculateTestStateFromCheckSummary(prData.PullRequest.CheckSummary)

pkg/prx/client_pullrequest_test.go

Lines changed: 2 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -61,11 +61,7 @@ func TestClient_PullRequest(t *testing.T) {
6161
client := NewClient("test-token", WithHTTPClient(httpClient))
6262

6363
// Override the API URL to point to our test server
64-
client.github = &githubClient{
65-
client: httpClient,
66-
token: "test-token",
67-
api: server.URL,
68-
}
64+
client.github = newTestGitHubClient(httpClient, "test-token", server.URL)
6965

7066
ctx := context.Background()
7167
prData, err := client.PullRequest(ctx, "testowner", "testrepo", 123)
@@ -142,11 +138,7 @@ func TestClient_PullRequestWithCache(t *testing.T) {
142138
client := NewClient("test-token", WithCacheStore(store), WithHTTPClient(httpClient))
143139

144140
// Override the API URL
145-
client.github = &githubClient{
146-
client: httpClient,
147-
token: "test-token",
148-
api: server.URL,
149-
}
141+
client.github = newTestGitHubClient(httpClient, "test-token", server.URL)
150142

151143
ctx := context.Background()
152144
refTime := time.Now()

0 commit comments

Comments
 (0)