Skip to content

Commit 97d7234

Browse files
committed
add better ctrl+c exiting when looping over multiple repos
1 parent 92fe3b3 commit 97d7234

File tree

1 file changed

+95
-64
lines changed

1 file changed

+95
-64
lines changed

internal/cmd/root.go

Lines changed: 95 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -168,89 +168,120 @@ func executeCombineCommand(ctx context.Context, spinner *Spinner, repos []string
168168
}
169169

170170
for _, repo := range repos {
171+
// Check if context was cancelled (CTRL+C pressed)
172+
select {
173+
case <-ctx.Done():
174+
return ctx.Err()
175+
default:
176+
// Continue processing
177+
}
178+
171179
spinner.UpdateMessage("Processing " + repo)
172180
Logger.Debug("Processing repository", "repo", repo)
173181

174-
// Parse owner and repo name
175-
parts := strings.Split(repo, "/")
176-
if len(parts) != 2 {
177-
Logger.Warn("Invalid repository format, skipping", "repo", repo)
182+
// Process the repository
183+
if err := processRepository(ctx, restClient, spinner, repo); err != nil {
184+
if ctx.Err() != nil {
185+
// If the context was cancelled, stop processing
186+
return ctx.Err()
187+
}
188+
// Otherwise just log the error and continue
189+
Logger.Warn("Failed to process repository", "repo", repo, "error", err)
178190
continue
179191
}
192+
}
180193

181-
owner := parts[0]
182-
repoName := parts[1]
194+
return nil
195+
}
183196

184-
// Get open PRs for the repository
185-
var pulls []struct {
186-
Number int
187-
Title string
188-
Head struct {
189-
Ref string
190-
}
191-
Base struct {
192-
Ref string
193-
SHA string
194-
}
195-
Labels []struct {
196-
Name string
197-
}
198-
}
197+
// processRepository handles a single repository's PRs
198+
func processRepository(ctx context.Context, client *api.RESTClient, spinner *Spinner, repo string) error {
199+
// Parse owner and repo name
200+
parts := strings.Split(repo, "/")
201+
if len(parts) != 2 {
202+
return fmt.Errorf("invalid repository format: %s", repo)
203+
}
199204

200-
endpoint := fmt.Sprintf("repos/%s/%s/pulls?state=open", owner, repoName)
201-
if err := restClient.Get(endpoint, &pulls); err != nil {
202-
Logger.Warn("Failed to fetch PRs", "repo", repo, "error", err)
203-
continue
204-
}
205+
owner := parts[0]
206+
repoName := parts[1]
205207

206-
// Filter PRs based on criteria
207-
var matchedPRs []struct {
208-
Number int
209-
Title string
210-
Branch string
211-
Base string
212-
BaseSHA string
208+
// Check for cancellation
209+
select {
210+
case <-ctx.Done():
211+
return ctx.Err()
212+
default:
213+
// Continue processing
214+
}
215+
216+
// Get open PRs for the repository
217+
var pulls []struct {
218+
Number int
219+
Title string
220+
Head struct {
221+
Ref string
222+
}
223+
Base struct {
224+
Ref string
225+
SHA string
226+
}
227+
Labels []struct {
228+
Name string
213229
}
230+
}
214231

215-
for _, pull := range pulls {
216-
branch := pull.Head.Ref
232+
endpoint := fmt.Sprintf("repos/%s/%s/pulls?state=open", owner, repoName)
233+
if err := client.Get(endpoint, &pulls); err != nil {
234+
return err
235+
}
217236

218-
// Check if PR matches all filtering criteria
219-
if !PrMatchesCriteria(branch, pull.Labels) {
220-
continue
221-
}
237+
// Check for cancellation again
238+
select {
239+
case <-ctx.Done():
240+
return ctx.Err()
241+
default:
242+
// Continue processing
243+
}
222244

223-
// TODO: Implement CI/approval status checking
224-
225-
matchedPRs = append(matchedPRs, struct {
226-
Number int
227-
Title string
228-
Branch string
229-
Base string
230-
BaseSHA string
231-
}{
232-
Number: pull.Number,
233-
Title: pull.Title,
234-
Branch: branch,
235-
Base: pull.Base.Ref,
236-
BaseSHA: pull.Base.SHA,
237-
})
238-
}
245+
// Filter PRs based on criteria
246+
var matchedPRs []struct {
247+
Number int
248+
Title string
249+
Branch string
250+
Base string
251+
BaseSHA string
252+
}
253+
254+
for _, pull := range pulls {
255+
branch := pull.Head.Ref
239256

240-
// Check if we have enough PRs to combine
241-
if len(matchedPRs) < minimum {
242-
Logger.Debug("Not enough PRs match criteria", "repo", repo, "matched", len(matchedPRs), "required", minimum)
257+
// Check if PR matches all filtering criteria
258+
if !PrMatchesCriteria(branch, pull.Labels) {
243259
continue
244260
}
245261

246-
// TODO: Implement PR combining logic
247-
// 1. Create combined branch
248-
// 2. Merge matched PR branches
249-
// 3. Create combined PR
250-
// 4. Add labels and assignees
262+
// TODO: Implement CI/approval status checking
263+
264+
matchedPRs = append(matchedPRs, struct {
265+
Number int
266+
Title string
267+
Branch string
268+
Base string
269+
BaseSHA string
270+
}{
271+
Number: pull.Number,
272+
Title: pull.Title,
273+
Branch: branch,
274+
Base: pull.Base.Ref,
275+
BaseSHA: pull.Base.SHA,
276+
})
277+
}
251278

252-
Logger.Debug("Matched PRs", "repo", repo, "count", len(matchedPRs))
279+
// Check if we have enough PRs to combine
280+
if len(matchedPRs) < minimum {
281+
Logger.Debug("Not enough PRs match criteria", "repo", repo, "matched", len(matchedPRs), "required", minimum)
282+
return nil
253283
}
254284

285+
Logger.Debug("Matched PRs", "repo", repo, "count", len(matchedPRs))
255286
return nil
256287
}

0 commit comments

Comments
 (0)