Skip to content

Commit 6d03bec

Browse files
authored
Merge pull request #8 from codeGROOVE-dev/sprinkler
Add --user flag
2 parents 2c31bca + 7c0f638 commit 6d03bec

File tree

2 files changed

+185
-11
lines changed

2 files changed

+185
-11
lines changed

main.go

Lines changed: 19 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -192,6 +192,7 @@ func main() {
192192
verbose = flag.Bool("verbose", false, "Show verbose logging from libraries")
193193
excludeOrgs = flag.String("exclude-orgs", "", "Comma-separated list of orgs to exclude")
194194
includeStale = flag.Bool("include-stale", false, "Include PRs that haven't been modified in 90 days")
195+
user = flag.String("user", "", "View PRs for specified user instead of authenticated user")
195196
)
196197
flag.Parse()
197198

@@ -229,14 +230,21 @@ func main() {
229230
}
230231
logger.Print("INFO: Successfully retrieved GitHub token")
231232

232-
username, err := currentUser(ctx, token, logger, httpClient)
233-
if err != nil {
234-
logger.Printf("ERROR: Failed to get current user: %v", err)
235-
fmt.Fprint(os.Stderr, "error: failed to identify github user\n")
236-
cancel()
237-
return
233+
// Determine the username to use - either specified via --user or the authenticated user
234+
var username string
235+
if *user != "" {
236+
username = *user
237+
logger.Printf("INFO: Using specified user: %s", username)
238+
} else {
239+
username, err = currentUser(ctx, token, logger, httpClient)
240+
if err != nil {
241+
logger.Printf("ERROR: Failed to get current user: %v", err)
242+
fmt.Fprint(os.Stderr, "error: failed to identify github user\n")
243+
cancel()
244+
return
245+
}
246+
logger.Printf("INFO: Authenticated as user: %s", username)
238247
}
239-
logger.Printf("INFO: Authenticated as user: %s", username)
240248

241249
// Set up turn client
242250
var turnClient *turn.Client
@@ -809,9 +817,9 @@ type displayConfig struct {
809817
httpClient *http.Client
810818
turnClient *turn.Client
811819
lastDisplayHash *string
812-
excludedOrgs []string
813820
token string
814821
username string
822+
excludedOrgs []string
815823
blockingOnly bool
816824
verbose bool
817825
includeStale bool
@@ -820,13 +828,13 @@ type displayConfig struct {
820828

821829
// watchConfig holds configuration for watch mode.
822830
type watchConfig struct {
823-
logger *log.Logger
824831
httpClient *http.Client
825832
turnClient *turn.Client
826-
excludedOrgs []string
833+
logger *log.Logger
834+
org string
827835
token string
828836
username string
829-
org string
837+
excludedOrgs []string
830838
interval time.Duration
831839
blockingOnly bool
832840
notifyMode bool

main_test.go

Lines changed: 166 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -247,3 +247,169 @@ func TestCategorizePRs(t *testing.T) {
247247
}
248248
}
249249
}
250+
251+
func TestGeneratePRDisplayBlockedFlag(t *testing.T) {
252+
username := "alice"
253+
254+
// Create test PRs with blocking/non-blocking scenarios
255+
incomingBlocked := PR{
256+
Number: 1,
257+
Title: "Incoming blocked PR",
258+
HTMLURL: "https://github.com/org/repo/pull/1",
259+
User: User{Login: "bob"},
260+
RequestedReviewers: []User{{Login: "alice"}}, // alice is requested reviewer
261+
}
262+
263+
incomingNotBlocked := PR{
264+
Number: 2,
265+
Title: "Incoming non-blocked PR",
266+
HTMLURL: "https://github.com/org/repo/pull/2",
267+
User: User{Login: "charlie"},
268+
RequestedReviewers: []User{{Login: "dave"}}, // alice is not requested reviewer
269+
}
270+
271+
outgoingBlocked := PR{
272+
Number: 3,
273+
Title: "Outgoing blocked PR",
274+
HTMLURL: "https://github.com/org/repo/pull/3",
275+
User: User{Login: "alice"}, // alice is author
276+
RequestedReviewers: []User{{Login: "alice"}}, // alice is requested reviewer (perhaps due to turn server logic)
277+
}
278+
279+
outgoingNotBlocked := PR{
280+
Number: 4,
281+
Title: "Outgoing non-blocked PR",
282+
HTMLURL: "https://github.com/org/repo/pull/4",
283+
User: User{Login: "alice"}, // alice is author
284+
RequestedReviewers: []User{{Login: "eve"}}, // alice is not requested reviewer
285+
}
286+
287+
allPRs := []PR{incomingBlocked, incomingNotBlocked, outgoingBlocked, outgoingNotBlocked}
288+
289+
tests := []struct {
290+
name string
291+
prs []PR
292+
blockingOnly bool
293+
expectIncoming bool
294+
expectOutgoing bool
295+
expectIncomingCount int
296+
expectOutgoingCount int
297+
}{
298+
{
299+
name: "normal mode shows all PRs",
300+
prs: allPRs,
301+
blockingOnly: false,
302+
expectIncoming: true,
303+
expectOutgoing: true,
304+
expectIncomingCount: 2, // both incoming PRs
305+
expectOutgoingCount: 2, // both outgoing PRs
306+
},
307+
{
308+
name: "blocked mode shows only blocked PRs",
309+
prs: allPRs,
310+
blockingOnly: true,
311+
expectIncoming: true, // has blocked incoming
312+
expectOutgoing: true, // has blocked outgoing
313+
expectIncomingCount: 1, // only blocked incoming
314+
expectOutgoingCount: 1, // only blocked outgoing
315+
},
316+
{
317+
name: "blocked mode with only incoming blocked",
318+
prs: []PR{incomingBlocked, incomingNotBlocked, outgoingNotBlocked},
319+
blockingOnly: true,
320+
expectIncoming: true, // has blocked incoming
321+
expectOutgoing: false, // no blocked outgoing
322+
expectIncomingCount: 1, // only blocked incoming
323+
expectOutgoingCount: 0, // no outgoing shown
324+
},
325+
{
326+
name: "blocked mode with only outgoing blocked",
327+
prs: []PR{incomingNotBlocked, outgoingBlocked, outgoingNotBlocked},
328+
blockingOnly: true,
329+
expectIncoming: false, // no blocked incoming
330+
expectOutgoing: true, // has blocked outgoing
331+
expectIncomingCount: 0, // no incoming shown
332+
expectOutgoingCount: 1, // only blocked outgoing
333+
},
334+
{
335+
name: "blocked mode with no blocked PRs",
336+
prs: []PR{incomingNotBlocked, outgoingNotBlocked},
337+
blockingOnly: true,
338+
expectIncoming: false, // no blocked incoming
339+
expectOutgoing: false, // no blocked outgoing
340+
expectIncomingCount: 0, // no incoming shown
341+
expectOutgoingCount: 0, // no outgoing shown
342+
},
343+
}
344+
345+
for _, tt := range tests {
346+
t.Run(tt.name, func(t *testing.T) {
347+
output := generatePRDisplay(tt.prs, username, tt.blockingOnly, false, true, nil)
348+
349+
// Debug output for failing test
350+
if tt.name == "blocked mode with only outgoing blocked" {
351+
t.Logf("Debug output: %q", output)
352+
}
353+
354+
// For the case with no blocked PRs, expect empty output
355+
if !tt.expectIncoming && !tt.expectOutgoing {
356+
if strings.TrimSpace(output) != "" {
357+
t.Errorf("Expected empty output for no blocked PRs, got: %q", output)
358+
}
359+
return
360+
}
361+
362+
// Check for incoming section presence
363+
hasIncomingSection := strings.Contains(output, "incoming -")
364+
if hasIncomingSection != tt.expectIncoming {
365+
t.Errorf("Expected incoming section: %v, got: %v", tt.expectIncoming, hasIncomingSection)
366+
}
367+
368+
// Check for outgoing section presence
369+
hasOutgoingSection := strings.Contains(output, "outgoing -")
370+
if hasOutgoingSection != tt.expectOutgoing {
371+
t.Errorf("Expected outgoing section: %v, got: %v", tt.expectOutgoing, hasOutgoingSection)
372+
}
373+
374+
// Count actual PRs shown in each section
375+
if tt.expectIncoming {
376+
incomingLines := 0
377+
lines := strings.Split(output, "\n")
378+
incomingStarted := false
379+
for _, line := range lines {
380+
if strings.Contains(line, "incoming -") {
381+
incomingStarted = true
382+
continue
383+
}
384+
if strings.Contains(line, "outgoing -") {
385+
break
386+
}
387+
if incomingStarted && (strings.HasPrefix(line, "• ") || strings.HasPrefix(line, " ")) {
388+
incomingLines++
389+
}
390+
}
391+
if incomingLines != tt.expectIncomingCount {
392+
t.Errorf("Expected %d incoming PRs shown, got %d", tt.expectIncomingCount, incomingLines)
393+
}
394+
}
395+
396+
if tt.expectOutgoing {
397+
outgoingLines := 0
398+
lines := strings.Split(output, "\n")
399+
outgoingStarted := false
400+
for _, line := range lines {
401+
if strings.Contains(line, "outgoing -") {
402+
outgoingStarted = true
403+
continue
404+
}
405+
if outgoingStarted && (strings.HasPrefix(line, "• ") || strings.HasPrefix(line, " ")) {
406+
outgoingLines++
407+
}
408+
}
409+
if outgoingLines != tt.expectOutgoingCount {
410+
t.Errorf("Expected %d outgoing PRs shown, got %d", tt.expectOutgoingCount, outgoingLines)
411+
}
412+
}
413+
})
414+
}
415+
}

0 commit comments

Comments
 (0)