@@ -18,6 +18,7 @@ import (
1818 "github.com/mattn/go-isatty"
1919
2020 "github.com/sourcegraph/sourcegraph/lib/errors"
21+ "github.com/sourcegraph/sourcegraph/lib/output"
2122
2223 batcheslib "github.com/sourcegraph/sourcegraph/lib/batches"
2324 "github.com/sourcegraph/sourcegraph/lib/batches/template"
@@ -253,20 +254,38 @@ type executeBatchSpecOpts struct {
253254// executeBatchSpec performs all the steps required to upload the batch spec to
254255// Sourcegraph, including execution as needed and applying the resulting batch
255256// spec if specified.
256- func executeBatchSpec (ctx context.Context , ui ui.ExecUI , opts executeBatchSpecOpts ) (err error ) {
257+ func executeBatchSpec (ctx context.Context , opts executeBatchSpecOpts ) (err error ) {
258+ var execUI ui.ExecUI
259+ if opts .flags .textOnly {
260+ execUI = & ui.JSONLines {}
261+ } else {
262+ out := output .NewOutput (os .Stderr , output.OutputOpts {Verbose : * verbose })
263+ execUI = & ui.TUI {Out : out }
264+ }
265+
257266 defer func () {
258267 if err != nil {
259- ui .ExecutionError (err )
268+ execUI .ExecutionError (err )
260269 }
261270 }()
262271
263272 svc := service .New (& service.Opts {
264273 Client : opts .client ,
265274 })
266275
276+ ffs , err := svc .DetermineFeatureFlags (ctx )
277+ if err != nil {
278+ return err
279+ }
280+
281+ // Once we know about feature flags, reconfigure the UI if needed.
282+ if opts .flags .textOnly && ffs .BinaryDiffs {
283+ execUI = & ui.JSONLines {BinaryDiffs : true }
284+ }
285+
267286 imageCache := docker .NewImageCache ()
268287
269- if err := validateSourcegraphVersionConstraint (ctx , svc ); err != nil {
288+ if err := validateSourcegraphVersionConstraint (ctx , ffs ); err != nil {
270289 return err
271290 }
272291
@@ -309,45 +328,45 @@ func executeBatchSpec(ctx context.Context, ui ui.ExecUI, opts executeBatchSpecOp
309328 }
310329
311330 // Parse flags and build up our service and executor options.
312- ui .ParsingBatchSpec ()
331+ execUI .ParsingBatchSpec ()
313332 batchSpec , batchSpecDir , rawSpec , err := parseBatchSpec (ctx , opts .file , svc )
314333 if err != nil {
315334 var multiErr errors.MultiError
316335 if errors .As (err , & multiErr ) {
317- ui .ParsingBatchSpecFailure (multiErr )
336+ execUI .ParsingBatchSpecFailure (multiErr )
318337 return cmderrors .ExitCode (2 , nil )
319338 } else {
320339 // This shouldn't happen; let's just punt and let the normal
321340 // rendering occur.
322341 return err
323342 }
324343 }
325- ui .ParsingBatchSpecSuccess ()
344+ execUI .ParsingBatchSpecSuccess ()
326345
327- ui .ResolvingNamespace ()
346+ execUI .ResolvingNamespace ()
328347 namespace , err := svc .ResolveNamespace (ctx , opts .flags .namespace )
329348 if err != nil {
330349 return err
331350 }
332- ui .ResolvingNamespaceSuccess (namespace .ID )
351+ execUI .ResolvingNamespaceSuccess (namespace .ID )
333352
334353 var workspaceCreator workspace.Creator
335354
336355 if len (batchSpec .Steps ) > 0 {
337- ui .PreparingContainerImages ()
356+ execUI .PreparingContainerImages ()
338357 images , err := svc .EnsureDockerImages (
339358 ctx ,
340359 imageCache ,
341360 batchSpec .Steps ,
342361 parallelism ,
343- ui .PreparingContainerImagesProgress ,
362+ execUI .PreparingContainerImagesProgress ,
344363 )
345364 if err != nil {
346365 return err
347366 }
348- ui .PreparingContainerImagesSuccess ()
367+ execUI .PreparingContainerImagesSuccess ()
349368
350- ui .DeterminingWorkspaceCreatorType ()
369+ execUI .DeterminingWorkspaceCreatorType ()
351370 var typ workspace.CreatorType
352371 workspaceCreator , typ = workspace .NewCreator (ctx , opts .flags .workspace , opts .flags .cacheDir , opts .flags .tempDir , images )
353372 if typ == workspace .CreatorTypeVolume {
@@ -357,21 +376,21 @@ func executeBatchSpec(ctx context.Context, ui ui.ExecUI, opts executeBatchSpecOp
357376 return err
358377 }
359378 }
360- ui .DeterminingWorkspaceCreatorTypeSuccess (typ )
379+ execUI .DeterminingWorkspaceCreatorTypeSuccess (typ )
361380 }
362381
363- ui .DeterminingWorkspaces ()
382+ execUI .DeterminingWorkspaces ()
364383 workspaces , repos , err := svc .ResolveWorkspacesForBatchSpec (ctx , batchSpec , opts .flags .allowUnsupported , opts .flags .allowIgnored )
365384 if err != nil {
366385 if repoSet , ok := err .(batches.UnsupportedRepoSet ); ok {
367- ui .DeterminingWorkspacesSuccess (len (workspaces ), len (repos ), repoSet , nil )
386+ execUI .DeterminingWorkspacesSuccess (len (workspaces ), len (repos ), repoSet , nil )
368387 } else if repoSet , ok := err .(batches.IgnoredRepoSet ); ok {
369- ui .DeterminingWorkspacesSuccess (len (workspaces ), len (repos ), nil , repoSet )
388+ execUI .DeterminingWorkspacesSuccess (len (workspaces ), len (repos ), nil , repoSet )
370389 } else {
371390 return errors .Wrap (err , "resolving repositories" )
372391 }
373392 } else {
374- ui .DeterminingWorkspacesSuccess (len (workspaces ), len (repos ), nil , nil )
393+ execUI .DeterminingWorkspacesSuccess (len (workspaces ), len (repos ), nil , nil )
375394 }
376395
377396 archiveRegistry := repozip .NewArchiveRegistry (opts .client , opts .flags .cacheDir , opts .flags .cleanArchives )
@@ -389,14 +408,16 @@ func executeBatchSpec(ctx context.Context, ui ui.ExecUI, opts executeBatchSpecOp
389408 TempDir : opts .flags .tempDir ,
390409 GlobalEnv : os .Environ (),
391410 ForceRoot : opts .flags .runAsRoot ,
411+ BinaryDiffs : ffs .BinaryDiffs ,
392412 },
393- Logger : logManager ,
394- Cache : executor .NewDiskCache (opts .flags .cacheDir ),
395- GlobalEnv : os .Environ (),
413+ Logger : logManager ,
414+ Cache : executor .NewDiskCache (opts .flags .cacheDir ),
415+ BinaryDiffs : ffs .BinaryDiffs ,
416+ GlobalEnv : os .Environ (),
396417 },
397418 )
398419
399- ui .CheckingCache ()
420+ execUI .CheckingCache ()
400421 tasks := svc .BuildTasks (
401422 & template.BatchChangeAttributes {
402423 Name : batchSpec .Name ,
@@ -421,9 +442,9 @@ func executeBatchSpec(ctx context.Context, ui ui.ExecUI, opts executeBatchSpecOp
421442 return err
422443 }
423444 }
424- ui .CheckingCacheSuccess (len (specs ), len (uncachedTasks ))
445+ execUI .CheckingCacheSuccess (len (specs ), len (uncachedTasks ))
425446
426- taskExecUI := ui .ExecutingTasks (* verbose , parallelism )
447+ taskExecUI := execUI .ExecutingTasks (* verbose , parallelism )
427448 freshSpecs , logFiles , execErr := coord .ExecuteAndBuildSpecs (ctx , batchSpec , uncachedTasks , taskExecUI )
428449 // Add external changeset specs.
429450 importedSpecs , importErr := svc .CreateImportChangesetSpecs (ctx , batchSpec )
@@ -440,7 +461,7 @@ func executeBatchSpec(ctx context.Context, ui ui.ExecUI, opts executeBatchSpecOp
440461 if err == nil {
441462 taskExecUI .Success ()
442463 } else {
443- ui .ExecutingTasksSkippingErrors (err )
464+ execUI .ExecutingTasksSkippingErrors (err )
444465 }
445466 } else {
446467 if err != nil {
@@ -450,7 +471,7 @@ func executeBatchSpec(ctx context.Context, ui ui.ExecUI, opts executeBatchSpecOp
450471 }
451472
452473 if len (logFiles ) > 0 && opts .flags .keepLogs {
453- ui .LogFilesKept (logFiles )
474+ execUI .LogFilesKept (logFiles )
454475 }
455476
456477 specs = append (specs , freshSpecs ... )
@@ -464,29 +485,29 @@ func executeBatchSpec(ctx context.Context, ui ui.ExecUI, opts executeBatchSpecOp
464485 ids := make ([]graphql.ChangesetSpecID , len (specs ))
465486
466487 if len (specs ) > 0 {
467- ui .UploadingChangesetSpecs (len (specs ))
488+ execUI .UploadingChangesetSpecs (len (specs ))
468489
469490 for i , spec := range specs {
470491 id , err := svc .CreateChangesetSpec (ctx , spec )
471492 if err != nil {
472493 return err
473494 }
474495 ids [i ] = id
475- ui .UploadingChangesetSpecsProgress (i + 1 , len (specs ))
496+ execUI .UploadingChangesetSpecsProgress (i + 1 , len (specs ))
476497 }
477498
478- ui .UploadingChangesetSpecsSuccess (ids )
499+ execUI .UploadingChangesetSpecsSuccess (ids )
479500 } else if len (repos ) == 0 {
480- ui .NoChangesetSpecs ()
501+ execUI .NoChangesetSpecs ()
481502 }
482503
483- ui .CreatingBatchSpec ()
504+ execUI .CreatingBatchSpec ()
484505 id , url , err := svc .CreateBatchSpec (ctx , namespace .ID , rawSpec , ids )
485506 if err != nil {
486- return ui .CreatingBatchSpecError (err )
507+ return execUI .CreatingBatchSpecError (err )
487508 }
488509 previewURL := cfg .Endpoint + url
489- ui .CreatingBatchSpecSuccess (previewURL )
510+ execUI .CreatingBatchSpecSuccess (previewURL )
490511
491512 hasWorkspaceFiles := false
492513 for _ , step := range batchSpec .Steps {
@@ -496,26 +517,26 @@ func executeBatchSpec(ctx context.Context, ui ui.ExecUI, opts executeBatchSpecOp
496517 }
497518 }
498519 if hasWorkspaceFiles {
499- ui .UploadingWorkspaceFiles ()
520+ execUI .UploadingWorkspaceFiles ()
500521 if err = svc .UploadBatchSpecWorkspaceFiles (ctx , batchSpecDir , string (id ), batchSpec .Steps ); err != nil {
501522 // Since failing to upload workspace files should not stop processing, just warn
502- ui .UploadingWorkspaceFilesWarning (errors .Wrap (err , "uploading workspace files" ))
523+ execUI .UploadingWorkspaceFilesWarning (errors .Wrap (err , "uploading workspace files" ))
503524 } else {
504- ui .UploadingWorkspaceFilesSuccess ()
525+ execUI .UploadingWorkspaceFilesSuccess ()
505526 }
506527 }
507528
508529 if ! opts .applyBatchSpec {
509- ui .PreviewBatchSpec (previewURL )
530+ execUI .PreviewBatchSpec (previewURL )
510531 return
511532 }
512533
513- ui .ApplyingBatchSpec ()
534+ execUI .ApplyingBatchSpec ()
514535 batch , err := svc .ApplyBatchChange (ctx , id )
515536 if err != nil {
516537 return err
517538 }
518- ui .ApplyingBatchSpecSuccess (cfg .Endpoint + batch .URL )
539+ execUI .ApplyingBatchSpecSuccess (cfg .Endpoint + batch .URL )
519540
520541 return nil
521542}
@@ -617,11 +638,7 @@ func getBatchParallelism(ctx context.Context, flag int) (int, error) {
617638 return docker .NCPU (ctx )
618639}
619640
620- func validateSourcegraphVersionConstraint (ctx context.Context , svc * service.Service ) error {
621- ffs , err := svc .DetermineFeatureFlags (ctx )
622- if err != nil {
623- return err
624- }
641+ func validateSourcegraphVersionConstraint (ctx context.Context , ffs * batches.FeatureFlags ) error {
625642 if ffs .Sourcegraph40 {
626643 return nil
627644 }
0 commit comments