diff --git a/cmd/src/batch_remote.go b/cmd/src/batch_remote.go index f83df8f6bb..a5a1a57e1a 100644 --- a/cmd/src/batch_remote.go +++ b/cmd/src/batch_remote.go @@ -119,8 +119,9 @@ Examples: ui.ResolvingWorkspaces() ticker := time.NewTicker(1 * time.Second) defer ticker.Stop() + var res *service.BatchSpecWorkspaceResolution for range ticker.C { - res, err := svc.GetBatchSpecWorkspaceResolution(ctx, batchSpecID) + res, err = svc.GetBatchSpecWorkspaceResolution(ctx, batchSpecID) if err != nil { return err } @@ -131,7 +132,7 @@ Examples: break } } - ui.ResolvingWorkspacesSuccess() + ui.ResolvingWorkspacesSuccess(res.Workspaces.TotalCount) // We have to enqueue this for execution with a separate operation. // diff --git a/internal/batches/service/remote.go b/internal/batches/service/remote.go index b0492560e4..f671715def 100644 --- a/internal/batches/service/remote.go +++ b/internal/batches/service/remote.go @@ -275,6 +275,9 @@ query BatchSpecWorkspaceResolution($batchSpec: ID!) { workspaceResolution { failureMessage state + workspaces { + totalCount + } } } } @@ -284,6 +287,9 @@ query BatchSpecWorkspaceResolution($batchSpec: ID!) { type BatchSpecWorkspaceResolution struct { FailureMessage string `json:"failureMessage"` State string `json:"state"` + Workspaces struct { + TotalCount int `json:"totalCount"` + } `json:"workspaces"` } func (svc *Service) GetBatchSpecWorkspaceResolution(ctx context.Context, id string) (*BatchSpecWorkspaceResolution, error) { diff --git a/internal/batches/ui/tui.go b/internal/batches/ui/tui.go index ce1c310027..f5a8bade25 100644 --- a/internal/batches/ui/tui.go +++ b/internal/batches/ui/tui.go @@ -3,6 +3,7 @@ package ui import ( "context" "fmt" + "math" "os/exec" "github.com/neelance/parallel" @@ -97,6 +98,7 @@ func (ui *TUI) DeterminingWorkspaceCreatorTypeSuccess(wt workspace.CreatorType) func (ui *TUI) DeterminingWorkspaces() { ui.pending = batchCreatePending(ui.Out, "Determining workspaces") } + func (ui *TUI) DeterminingWorkspacesSuccess(workspacesCount, reposCount int, unsupported batches.UnsupportedRepoSet, ignored batches.IgnoredRepoSet) { batchCompletePending(ui.pending, fmt.Sprintf("Resolved %d workspaces from %d repositories", workspacesCount, reposCount)) @@ -113,6 +115,31 @@ func (ui *TUI) DeterminingWorkspacesSuccess(workspacesCount, reposCount int, uns } block.Close() } + + ui.maybeWorkspaceCountWarning(workspacesCount, 500) +} + +func (ui *TUI) maybeWorkspaceCountWarning(count, limit int) { + if count > limit { + block := ui.Out.Block(output.Linef( + "⚠️", output.StyleWarning, + "Batch changes with more than %d workspaces may be unwieldy to manage.", + limit, + )) + + for _, line := range []string{ + "We're working on providing more filtering options, and you can continue with", + fmt.Sprintf( + "this batch change if you want, but you may want to break it into %d or more", + int(math.Ceil(float64(count)/float64(limit))), + ), + "batch changes if you can.", + } { + block.WriteLine(output.Line("", output.StyleSuggestion, line)) + } + + block.Close() + } } func (ui *TUI) CheckingCache() { @@ -244,8 +271,9 @@ func (ui *TUI) ResolvingWorkspaces() { ui.pending = batchCreatePending(ui.Out, "Resolving workspaces") } -func (ui *TUI) ResolvingWorkspacesSuccess() { +func (ui *TUI) ResolvingWorkspacesSuccess(workspacesCount int) { batchCompletePending(ui.pending, "Resolving workspaces") + ui.maybeWorkspaceCountWarning(workspacesCount, 2000) } func (ui *TUI) ExecutingBatchSpec() {