From e20c8f8fc05c0a78292f87f7f615b4bb6e3465c3 Mon Sep 17 00:00:00 2001 From: Erik Seliger Date: Wed, 22 Sep 2021 16:35:02 +0200 Subject: [PATCH 1/3] Cleanup and complete json logs a bit --- cmd/src/batch_common.go | 14 ++++-- cmd/src/batch_exec.go | 18 +++++--- internal/batches/executor/coordinator_test.go | 5 ++- internal/batches/executor/run_steps.go | 43 ++++++++++++++++--- internal/batches/executor/ui.go | 12 +++++- internal/batches/ui/json_lines.go | 32 ++++++++++++-- internal/batches/ui/task_exec_tui.go | 14 +++++- 7 files changed, 114 insertions(+), 24 deletions(-) diff --git a/cmd/src/batch_common.go b/cmd/src/batch_common.go index 78b1a4ee18..c32985babf 100644 --- a/cmd/src/batch_common.go +++ b/cmd/src/batch_common.go @@ -312,9 +312,17 @@ func executeBatchSpec(ctx context.Context, opts executeBatchSpecOpts) (err error if err != nil && !opts.flags.skipErrors { return err } - taskExecUI.Success() - if err != nil && opts.flags.skipErrors { - opts.ui.ExecutingTasksSkippingErrors(err) + if err == nil || opts.flags.skipErrors { + if err == nil { + taskExecUI.Success() + } else { + opts.ui.ExecutingTasksSkippingErrors(err) + } + } else { + if err != nil { + taskExecUI.Failed(err) + return err + } } if len(logFiles) > 0 && opts.flags.keepLogs { diff --git a/cmd/src/batch_exec.go b/cmd/src/batch_exec.go index 190a91bca6..78546e55aa 100644 --- a/cmd/src/batch_exec.go +++ b/cmd/src/batch_exec.go @@ -9,6 +9,7 @@ import ( "github.com/cockroachdb/errors" "github.com/hashicorp/go-multierror" + "github.com/sourcegraph/src-cli/internal/batches/executor" "github.com/sourcegraph/src-cli/internal/batches/graphql" "github.com/sourcegraph/src-cli/internal/batches/service" @@ -164,12 +165,17 @@ func executeBatchSpecInWorkspaces(ctx context.Context, opts executeBatchSpecOpts taskExecUI := opts.ui.ExecutingTasks(*verbose, opts.flags.parallelism) freshSpecs, _, err := coord.Execute(ctx, uncachedTasks, batchSpec, taskExecUI) - if err != nil && !opts.flags.skipErrors { - return err - } - taskExecUI.Success() - if err != nil && opts.flags.skipErrors { - opts.ui.ExecutingTasksSkippingErrors(err) + if err == nil || opts.flags.skipErrors { + if err == nil { + taskExecUI.Success() + } else { + opts.ui.ExecutingTasksSkippingErrors(err) + } + } else { + if err != nil { + taskExecUI.Failed(err) + return err + } } specs := append(cachedSpecs, freshSpecs...) diff --git a/internal/batches/executor/coordinator_test.go b/internal/batches/executor/coordinator_test.go index d4af8ca807..c34d0c2edc 100644 --- a/internal/batches/executor/coordinator_test.go +++ b/internal/batches/executor/coordinator_test.go @@ -519,8 +519,9 @@ type dummyTaskExecutionUI struct { specs map[*Task][]*batcheslib.ChangesetSpec } -func (d *dummyTaskExecutionUI) Start([]*Task) {} -func (d *dummyTaskExecutionUI) Success() {} +func (d *dummyTaskExecutionUI) Start([]*Task) {} +func (d *dummyTaskExecutionUI) Success() {} +func (d *dummyTaskExecutionUI) Failed(err error) {} func (d *dummyTaskExecutionUI) TaskStarted(t *Task) { d.mu.Lock() defer d.mu.Unlock() diff --git a/internal/batches/executor/run_steps.go b/internal/batches/executor/run_steps.go index e50bc53327..0aa3976e30 100644 --- a/internal/batches/executor/run_steps.go +++ b/internal/batches/executor/run_steps.go @@ -167,6 +167,16 @@ func runSteps(ctx context.Context, opts *executionOpts) (result executionResult, return execResult, nil, err } stdoutBuffer, stderrBuffer, err := executeSingleStep(ctx, opts, workspace, i, step, digest, &stepContext) + defer func() { + if err != nil { + exitCode := -1 + sfe := &stepFailedErr{} + if errors.As(err, sfe) { + exitCode = sfe.ExitCode + } + opts.ui.StepFailed(i+1, err, exitCode) + } + }() if err != nil { return execResult, nil, err } @@ -233,10 +243,11 @@ func executeSingleStep( // ---------- // PREPARATION // ---------- - opts.ui.StepPreparing(i + 1) + opts.ui.StepPreparingStart(i + 1) cidFile, cleanup, err := createCidFile(ctx, opts.tempDir, util.SlugForRepo(opts.task.Repository.Name, opts.task.Repository.Rev())) if err != nil { + opts.ui.StepPreparingFailed(i+1, err) return bytes.Buffer{}, bytes.Buffer{}, err } defer cleanup() @@ -244,11 +255,14 @@ func executeSingleStep( // For now, we only support shell scripts provided via the Run field. shell, containerTemp, err := probeImageForShell(ctx, imageDigest) if err != nil { - return bytes.Buffer{}, bytes.Buffer{}, errors.Wrapf(err, "probing image %q for shell", step.Container) + err = errors.Wrapf(err, "probing image %q for shell", step.Container) + opts.ui.StepPreparingFailed(i+1, err) + return bytes.Buffer{}, bytes.Buffer{}, err } runScriptFile, runScript, cleanup, err := createRunScriptFile(ctx, opts.tempDir, step.Run, stepContext) if err != nil { + opts.ui.StepPreparingFailed(i+1, err) return bytes.Buffer{}, bytes.Buffer{}, err } defer cleanup() @@ -256,6 +270,7 @@ func executeSingleStep( // Parse and render the step.Files. filesToMount, cleanup, err := createFilesToMount(opts.tempDir, step, stepContext) if err != nil { + opts.ui.StepPreparingFailed(i+1, err) return bytes.Buffer{}, bytes.Buffer{}, err } defer cleanup() @@ -263,14 +278,20 @@ func executeSingleStep( // Resolve step.Env given the current environment. stepEnv, err := step.Env.Resolve(os.Environ()) if err != nil { - return bytes.Buffer{}, bytes.Buffer{}, errors.Wrap(err, "resolving step environment") + err = errors.Wrap(err, "resolving step environment") + opts.ui.StepPreparingFailed(i+1, err) + return bytes.Buffer{}, bytes.Buffer{}, err } // Render the step.Env variables as templates. env, err := template.RenderStepMap(stepEnv, stepContext) if err != nil { - return bytes.Buffer{}, bytes.Buffer{}, errors.Wrap(err, "parsing step environment") + err = errors.Wrap(err, "parsing step environment") + opts.ui.StepPreparingFailed(i+1, err) + return bytes.Buffer{}, bytes.Buffer{}, err } + opts.ui.StepPreparingSuccess(i + 1) + // ---------- // EXECUTION // ---------- @@ -330,8 +351,14 @@ func executeSingleStep( } newStepFailedErr := func(wrappedErr error) stepFailedErr { + exitCode := -1 + exitErr := &exec.ExitError{} + if errors.As(wrappedErr, &exitErr) { + exitCode = exitErr.ExitCode() + } return stepFailedErr{ Err: wrappedErr, + ExitCode: exitCode, Args: cmd.Args, Run: runScript, Container: step.Container, @@ -570,7 +597,9 @@ type stepFailedErr struct { Stdout string Stderr string - Err error + // ExitCode of the command, or -1 if a non-command error occured. + ExitCode int + Err error } func (e stepFailedErr) Cause() error { return e.Err } @@ -607,8 +636,8 @@ func (e stepFailedErr) Error() string { printOutput(e.Stderr) } - if exitErr, ok := e.Err.(*exec.ExitError); ok { - out.WriteString(fmt.Sprintf("\nCommand failed with exit code %d.", exitErr.ExitCode())) + if e.ExitCode != -1 { + out.WriteString(fmt.Sprintf("\nCommand failed with exit code %d.", e.ExitCode)) } else { out.WriteString(fmt.Sprintf("\nCommand failed: %s", e.Err)) } diff --git a/internal/batches/executor/ui.go b/internal/batches/executor/ui.go index 0ff56b2f43..bf597876a7 100644 --- a/internal/batches/executor/ui.go +++ b/internal/batches/executor/ui.go @@ -11,6 +11,7 @@ import ( type TaskExecutionUI interface { Start([]*Task) Success() + Failed(err error) TaskStarted(*Task) TaskFinished(*Task, error) @@ -37,7 +38,9 @@ type StepsExecutionUI interface { StepSkipped(int) - StepPreparing(int) + StepPreparingStart(int) + StepPreparingSuccess(int) + StepPreparingFailed(int, error) StepStarted(stepIdx int, runScript string, env map[string]string) StepOutputWriter(context.Context, *Task, int) StepOutputWriter @@ -46,6 +49,7 @@ type StepsExecutionUI interface { CalculatingDiffFinished() StepFinished(idx int, diff []byte, changes *git.Changes, outputs map[string]interface{}) + StepFailed(idx int, err error, exitCode int) } // NoopStepsExecUI is an implementation of StepsExecutionUI that does nothing. @@ -57,7 +61,9 @@ func (noop NoopStepsExecUI) WorkspaceInitializationStarted() func (noop NoopStepsExecUI) WorkspaceInitializationFinished() {} func (noop NoopStepsExecUI) SkippingStepsUpto(startStep int) {} func (noop NoopStepsExecUI) StepSkipped(step int) {} -func (noop NoopStepsExecUI) StepPreparing(step int) {} +func (noop NoopStepsExecUI) StepPreparingStart(step int) {} +func (noop NoopStepsExecUI) StepPreparingSuccess(step int) {} +func (noop NoopStepsExecUI) StepPreparingFailed(step int, err error) {} func (noop NoopStepsExecUI) StepStarted(step int, runScript string, env map[string]string) {} func (noop NoopStepsExecUI) StepOutputWriter(ctx context.Context, task *Task, step int) StepOutputWriter { return NoopStepOutputWriter{} @@ -66,6 +72,8 @@ func (noop NoopStepsExecUI) CalculatingDiffStarted() {} func (noop NoopStepsExecUI) CalculatingDiffFinished() {} func (noop NoopStepsExecUI) StepFinished(idx int, diff []byte, changes *git.Changes, outputs map[string]interface{}) { } +func (noop NoopStepsExecUI) StepFailed(idx int, err error, exitCode int) { +} type NoopStepOutputWriter struct{} diff --git a/internal/batches/ui/json_lines.go b/internal/batches/ui/json_lines.go index da10f5d1bd..25a62f5fe4 100644 --- a/internal/batches/ui/json_lines.go +++ b/internal/batches/ui/json_lines.go @@ -239,6 +239,12 @@ func (ui *taskExecutionJSONLines) Success() { logOperationSuccess(batcheslib.LogEventOperationExecutingTasks, nil) } +func (ui *taskExecutionJSONLines) Failed(err error) { + logOperationFailure(batcheslib.LogEventOperationExecutingTasks, map[string]interface{}{ + "error": err.Error(), + }) +} + func (ui *taskExecutionJSONLines) TaskStarted(task *executor.Task) { lt, ok := ui.linesTasks[task] if !ok { @@ -259,7 +265,7 @@ func (ui *taskExecutionJSONLines) TaskFinished(task *executor.Task, err error) { if err != nil { logOperationFailure(batcheslib.LogEventOperationExecutingTask, map[string]interface{}{ "taskID": lt.ID, - "error": err, + "error": err.Error(), }) return } @@ -316,8 +322,16 @@ func (ui *stepsExecutionJSONLines) StepSkipped(step int) { logOperationProgress(batcheslib.LogEventOperationTaskStepSkipped, map[string]interface{}{"taskID": ui.linesTask.ID, "step": step}) } -func (ui *stepsExecutionJSONLines) StepPreparing(step int) { - logOperationProgress(batcheslib.LogEventOperationTaskPreparingStep, map[string]interface{}{"taskID": ui.linesTask.ID, "step": step}) +func (ui *stepsExecutionJSONLines) StepPreparingStart(step int) { + logOperationStart(batcheslib.LogEventOperationTaskPreparingStep, map[string]interface{}{"taskID": ui.linesTask.ID, "step": step}) +} + +func (ui *stepsExecutionJSONLines) StepPreparingSuccess(step int) { + logOperationSuccess(batcheslib.LogEventOperationTaskPreparingStep, map[string]interface{}{"taskID": ui.linesTask.ID, "step": step}) +} + +func (ui *stepsExecutionJSONLines) StepPreparingFailed(step int, err error) { + logOperationFailure(batcheslib.LogEventOperationTaskPreparingStep, map[string]interface{}{"taskID": ui.linesTask.ID, "step": step, "error": err.Error()}) } func (ui *stepsExecutionJSONLines) StepStarted(step int, runScript string, env map[string]string) { @@ -351,6 +365,18 @@ func (ui *stepsExecutionJSONLines) StepFinished(step int, diff []byte, changes * ) } +func (ui *stepsExecutionJSONLines) StepFailed(step int, err error, exitCode int) { + logOperationFailure( + batcheslib.LogEventOperationTaskStep, + map[string]interface{}{ + "taskID": ui.linesTask.ID, + "step": step, + "error": err.Error(), + "exitCode": exitCode, + }, + ) +} + func (ui *stepsExecutionJSONLines) CalculatingDiffStarted() { logOperationStart(batcheslib.LogEventOperationTaskCalculatingDiff, map[string]interface{}{"taskID": ui.linesTask.ID}) } diff --git a/internal/batches/ui/task_exec_tui.go b/internal/batches/ui/task_exec_tui.go index f73e332267..0238d8b1ae 100644 --- a/internal/batches/ui/task_exec_tui.go +++ b/internal/batches/ui/task_exec_tui.go @@ -149,6 +149,9 @@ func (ui *taskExecTUI) Start(tasks []*executor.Task) { func (ui *taskExecTUI) Success() { ui.progress.Complete() } +func (ui *taskExecTUI) Failed(err error) { + // noop right now +} func (ui *taskExecTUI) useFreeStatusBar(ts *taskStatus) (bar int, found bool) { for i := 0; i < ui.numStatusBars; i++ { @@ -451,9 +454,15 @@ func (ui stepsExecTUI) SkippingStepsUpto(startStep int) { func (ui stepsExecTUI) StepSkipped(step int) { ui.updateStatusBar(fmt.Sprintf("Skipping step %d", step)) } -func (ui stepsExecTUI) StepPreparing(step int) { +func (ui stepsExecTUI) StepPreparingStart(step int) { ui.updateStatusBar(fmt.Sprintf("Preparing %d", step)) } +func (ui stepsExecTUI) StepPreparingSuccess(step int) { + // noop right now +} +func (ui stepsExecTUI) StepPreparingFailed(step int, err error) { + // noop right now +} func (ui stepsExecTUI) StepStarted(step int, runScript string, _ map[string]string) { ui.updateStatusBar(runScript) } @@ -471,3 +480,6 @@ func (ui stepsExecTUI) CalculatingDiffFinished() { func (ui stepsExecTUI) StepFinished(idx int, diff []byte, changes *git.Changes, outputs map[string]interface{}) { // noop right now } +func (ui stepsExecTUI) StepFailed(idx int, err error, exitCode int) { + // noop right now +} From 86574d6e9e057d260d5afa1428b2e14d5f4be031 Mon Sep 17 00:00:00 2001 From: Erik Seliger Date: Mon, 27 Sep 2021 16:25:53 +0200 Subject: [PATCH 2/3] More stuff --- cmd/src/batch_common.go | 21 +- internal/batches/executor/run_steps.go | 2 +- internal/batches/executor/ui.go | 4 +- internal/batches/ui/exec_ui.go | 2 +- internal/batches/ui/json_lines.go | 263 ++++++++++++------------- internal/batches/ui/task_exec_tui.go | 2 +- internal/batches/ui/tui.go | 2 +- 7 files changed, 145 insertions(+), 151 deletions(-) diff --git a/cmd/src/batch_common.go b/cmd/src/batch_common.go index c32985babf..c0ab724f1b 100644 --- a/cmd/src/batch_common.go +++ b/cmd/src/batch_common.go @@ -357,22 +357,23 @@ func executeBatchSpec(ctx context.Context, opts executeBatchSpecOpts) (err error opts.ui.CreatingBatchSpec() id, url, err := svc.CreateBatchSpec(ctx, namespace, rawSpec, ids) - opts.ui.CreatingBatchSpecSuccess() if err != nil { return opts.ui.CreatingBatchSpecError(err) } + previewURL := cfg.Endpoint + url + opts.ui.CreatingBatchSpecSuccess(previewURL) - if opts.applyBatchSpec { - opts.ui.ApplyingBatchSpec() - batch, err := svc.ApplyBatchChange(ctx, id) - if err != nil { - return err - } - opts.ui.ApplyingBatchSpecSuccess(cfg.Endpoint + batch.URL) + if !opts.applyBatchSpec { + opts.ui.PreviewBatchSpec(previewURL) + return + } - } else { - opts.ui.PreviewBatchSpec(cfg.Endpoint + url) + opts.ui.ApplyingBatchSpec() + batch, err := svc.ApplyBatchChange(ctx, id) + if err != nil { + return err } + opts.ui.ApplyingBatchSpecSuccess(cfg.Endpoint + batch.URL) return nil } diff --git a/internal/batches/executor/run_steps.go b/internal/batches/executor/run_steps.go index 0aa3976e30..ab6bec2b7a 100644 --- a/internal/batches/executor/run_steps.go +++ b/internal/batches/executor/run_steps.go @@ -73,11 +73,11 @@ type executionOpts struct { func runSteps(ctx context.Context, opts *executionOpts) (result executionResult, stepResults []stepExecutionResult, err error) { opts.ui.ArchiveDownloadStarted() err = opts.task.Archive.Ensure(ctx) + opts.ui.ArchiveDownloadFinished(err) if err != nil { return executionResult{}, nil, errors.Wrap(err, "fetching repo") } defer opts.task.Archive.Close() - opts.ui.ArchiveDownloadFinished() opts.ui.WorkspaceInitializationStarted() workspace, err := opts.wc.Create(ctx, opts.task.Repository, opts.task.Steps, opts.task.Archive) diff --git a/internal/batches/executor/ui.go b/internal/batches/executor/ui.go index bf597876a7..f9fd449537 100644 --- a/internal/batches/executor/ui.go +++ b/internal/batches/executor/ui.go @@ -29,7 +29,7 @@ type StepOutputWriter interface { type StepsExecutionUI interface { ArchiveDownloadStarted() - ArchiveDownloadFinished() + ArchiveDownloadFinished(error) WorkspaceInitializationStarted() WorkspaceInitializationFinished() @@ -56,7 +56,7 @@ type StepsExecutionUI interface { type NoopStepsExecUI struct{} func (noop NoopStepsExecUI) ArchiveDownloadStarted() {} -func (noop NoopStepsExecUI) ArchiveDownloadFinished() {} +func (noop NoopStepsExecUI) ArchiveDownloadFinished(error) {} func (noop NoopStepsExecUI) WorkspaceInitializationStarted() {} func (noop NoopStepsExecUI) WorkspaceInitializationFinished() {} func (noop NoopStepsExecUI) SkippingStepsUpto(startStep int) {} diff --git a/internal/batches/ui/exec_ui.go b/internal/batches/ui/exec_ui.go index 4c26727625..52a5f91637 100644 --- a/internal/batches/ui/exec_ui.go +++ b/internal/batches/ui/exec_ui.go @@ -42,7 +42,7 @@ type ExecUI interface { UploadingChangesetSpecsSuccess(ids []graphql.ChangesetSpecID) CreatingBatchSpec() - CreatingBatchSpecSuccess() + CreatingBatchSpecSuccess(previewURL string) CreatingBatchSpecError(err error) error PreviewBatchSpec(previewURL string) diff --git a/internal/batches/ui/json_lines.go b/internal/batches/ui/json_lines.go index 25a62f5fe4..46c59a8f5c 100644 --- a/internal/batches/ui/json_lines.go +++ b/internal/batches/ui/json_lines.go @@ -25,76 +25,72 @@ var _ ExecUI = &JSONLines{} type JSONLines struct{} func (ui *JSONLines) ParsingBatchSpec() { - logOperationStart(batcheslib.LogEventOperationParsingBatchSpec, nil) + logOperationStart(batcheslib.LogEventOperationParsingBatchSpec, &batcheslib.ParsingBatchSpecMetadata{}) } func (ui *JSONLines) ParsingBatchSpecSuccess() { - logOperationSuccess(batcheslib.LogEventOperationParsingBatchSpec, nil) + logOperationSuccess(batcheslib.LogEventOperationParsingBatchSpec, &batcheslib.ParsingBatchSpecMetadata{}) } func (ui *JSONLines) ParsingBatchSpecFailure(err error) { - logOperationFailure(batcheslib.LogEventOperationParsingBatchSpec, map[string]interface{}{"error": err.Error()}) + logOperationFailure(batcheslib.LogEventOperationParsingBatchSpec, &batcheslib.ParsingBatchSpecMetadata{Error: err.Error()}) } func (ui *JSONLines) ResolvingNamespace() { - logOperationStart(batcheslib.LogEventOperationResolvingNamespace, nil) + logOperationStart(batcheslib.LogEventOperationResolvingNamespace, &batcheslib.ResolvingNamespaceMetadata{}) } func (ui *JSONLines) ResolvingNamespaceSuccess(namespace string) { - logOperationSuccess(batcheslib.LogEventOperationResolvingNamespace, map[string]interface{}{"namespaceID": namespace}) + logOperationSuccess(batcheslib.LogEventOperationResolvingNamespace, &batcheslib.ResolvingNamespaceMetadata{NamespaceID: namespace}) } func (ui *JSONLines) PreparingContainerImages() { - logOperationStart(batcheslib.LogEventOperationPreparingDockerImages, nil) + logOperationStart(batcheslib.LogEventOperationPreparingDockerImages, &batcheslib.PreparingDockerImagesMetadata{}) } func (ui *JSONLines) PreparingContainerImagesProgress(done, total int) { - logOperationProgress(batcheslib.LogEventOperationPreparingDockerImages, map[string]interface{}{"done": done, "total": total}) + logOperationProgress(batcheslib.LogEventOperationPreparingDockerImages, &batcheslib.PreparingDockerImagesMetadata{Done: done, Total: total}) } func (ui *JSONLines) PreparingContainerImagesSuccess() { - logOperationSuccess(batcheslib.LogEventOperationPreparingDockerImages, nil) + logOperationSuccess(batcheslib.LogEventOperationPreparingDockerImages, &batcheslib.PreparingDockerImagesMetadata{}) } func (ui *JSONLines) DeterminingWorkspaceCreatorType() { - logOperationStart(batcheslib.LogEventOperationDeterminingWorkspaceType, nil) + logOperationStart(batcheslib.LogEventOperationDeterminingWorkspaceType, &batcheslib.DeterminingWorkspaceTypeMetadata{}) } func (ui *JSONLines) DeterminingWorkspaceCreatorTypeSuccess(wt workspace.CreatorType) { + var t string switch wt { case workspace.CreatorTypeVolume: - logOperationSuccess(batcheslib.LogEventOperationDeterminingWorkspaceType, map[string]interface{}{"type": "VOLUME"}) + t = "VOLUME" case workspace.CreatorTypeBind: - logOperationSuccess(batcheslib.LogEventOperationDeterminingWorkspaceType, map[string]interface{}{"type": "BIND"}) + t = "BIND" } + logOperationSuccess(batcheslib.LogEventOperationDeterminingWorkspaceType, &batcheslib.DeterminingWorkspaceTypeMetadata{Type: t}) } func (ui *JSONLines) ResolvingRepositories() { - logOperationStart(batcheslib.LogEventOperationResolvingRepositories, nil) + logOperationStart(batcheslib.LogEventOperationResolvingRepositories, &batcheslib.ResolvingRepositoriesMetadata{}) } func (ui *JSONLines) ResolvingRepositoriesDone(repos []*graphql.Repository, unsupported batches.UnsupportedRepoSet, ignored batches.IgnoredRepoSet) { - if unsupported != nil && len(unsupported) != 0 { - logOperationSuccess(batcheslib.LogEventOperationResolvingRepositories, map[string]interface{}{"unsupported": len(unsupported)}) - } else if ignored != nil && len(ignored) != 0 { - logOperationSuccess(batcheslib.LogEventOperationResolvingRepositories, map[string]interface{}{"ignored": len(ignored)}) - } else { - logOperationSuccess(batcheslib.LogEventOperationResolvingRepositories, map[string]interface{}{"count": len(repos)}) - } + logOperationSuccess(batcheslib.LogEventOperationResolvingRepositories, &batcheslib.ResolvingRepositoriesMetadata{ + Unsupported: len(unsupported), + Ignored: len(ignored), + Count: len(repos), + }) } func (ui *JSONLines) DeterminingWorkspaces() { - logOperationStart(batcheslib.LogEventOperationDeterminingWorkspaces, nil) + logOperationStart(batcheslib.LogEventOperationDeterminingWorkspaces, &batcheslib.DeterminingWorkspacesMetadata{}) } func (ui *JSONLines) DeterminingWorkspacesSuccess(num int) { - metadata := map[string]interface{}{ - "count": num, - } - logOperationSuccess(batcheslib.LogEventOperationDeterminingWorkspaces, metadata) + logOperationSuccess(batcheslib.LogEventOperationDeterminingWorkspaces, &batcheslib.DeterminingWorkspacesMetadata{Count: num}) } func (ui *JSONLines) CheckingCache() { - logOperationStart(batcheslib.LogEventOperationCheckingCache, nil) + logOperationStart(batcheslib.LogEventOperationCheckingCache, &batcheslib.CheckingCacheMetadata{}) } func (ui *JSONLines) CheckingCacheSuccess(cachedSpecsFound int, tasksToExecute int) { - metadata := map[string]interface{}{ - "cachedSpecsFound": cachedSpecsFound, - "tasksToExecute": tasksToExecute, - } - logOperationSuccess(batcheslib.LogEventOperationCheckingCache, metadata) + logOperationSuccess(batcheslib.LogEventOperationCheckingCache, &batcheslib.CheckingCacheMetadata{ + CachedSpecsFound: cachedSpecsFound, + TasksToExecute: tasksToExecute, + }) } func (ui *JSONLines) ExecutingTasks(verbose bool, parallelism int) executor.TaskExecutionUI { @@ -102,12 +98,15 @@ func (ui *JSONLines) ExecutingTasks(verbose bool, parallelism int) executor.Task } func (ui *JSONLines) ExecutingTasksSkippingErrors(err error) { - logOperationSuccess(batcheslib.LogEventOperationExecutingTasks, map[string]interface{}{"skipped": true, "error": err.Error()}) + logOperationSuccess(batcheslib.LogEventOperationExecutingTasks, &batcheslib.ExecutingTasksMetadata{ + Skipped: true, + Error: err.Error(), + }) } func (ui *JSONLines) LogFilesKept(files []string) { - for _, file := range files { - logOperationSuccess(batcheslib.LogEventOperationLogFileKept, map[string]interface{}{"path": file}) + for _, path := range files { + logOperationSuccess(batcheslib.LogEventOperationLogFileKept, &batcheslib.LogFileKeptMetadata{Path: path}) } } @@ -116,91 +115,67 @@ func (ui *JSONLines) NoChangesetSpecs() { } func (ui *JSONLines) UploadingChangesetSpecs(num int) { - logOperationStart(batcheslib.LogEventOperationUploadingChangesetSpecs, map[string]interface{}{ - "total": num, + logOperationStart(batcheslib.LogEventOperationUploadingChangesetSpecs, &batcheslib.UploadingChangesetSpecsMetadata{ + Done: 0, + Total: num, }) } func (ui *JSONLines) UploadingChangesetSpecsProgress(done, total int) { - logOperationProgress(batcheslib.LogEventOperationUploadingChangesetSpecs, map[string]interface{}{ - "done": done, - "total": total, + logOperationProgress(batcheslib.LogEventOperationUploadingChangesetSpecs, &batcheslib.UploadingChangesetSpecsMetadata{ + Done: done, + Total: total, }) } func (ui *JSONLines) UploadingChangesetSpecsSuccess(ids []graphql.ChangesetSpecID) { - logOperationSuccess(batcheslib.LogEventOperationUploadingChangesetSpecs, map[string]interface{}{ - "ids": ids, + sIDs := make([]string, len(ids)) + for i, id := range ids { + sIDs[i] = string(id) + } + logOperationSuccess(batcheslib.LogEventOperationUploadingChangesetSpecs, &batcheslib.UploadingChangesetSpecsMetadata{ + Done: len(ids), + Total: len(ids), + IDs: sIDs, }) } func (ui *JSONLines) CreatingBatchSpec() { - logOperationStart(batcheslib.LogEventOperationCreatingBatchSpec, nil) + logOperationStart(batcheslib.LogEventOperationCreatingBatchSpec, &batcheslib.CreatingBatchSpecMetadata{}) } -func (ui *JSONLines) CreatingBatchSpecSuccess() { +func (ui *JSONLines) CreatingBatchSpecSuccess(batchSpecURL string) { + logOperationSuccess(batcheslib.LogEventOperationCreatingBatchSpec, &batcheslib.CreatingBatchSpecMetadata{ + PreviewURL: batchSpecURL, + }) } func (ui *JSONLines) CreatingBatchSpecError(err error) error { + logOperationFailure(batcheslib.LogEventOperationCreatingBatchSpec, &batcheslib.CreatingBatchSpecMetadata{}) return err } func (ui *JSONLines) PreviewBatchSpec(batchSpecURL string) { - logOperationSuccess(batcheslib.LogEventOperationCreatingBatchSpec, map[string]interface{}{"batchSpecURL": batchSpecURL}) + // Covered by CreatingBatchSpecSuccess. } func (ui *JSONLines) ApplyingBatchSpec() { - logOperationStart(batcheslib.LogEventOperationApplyingBatchSpec, nil) + logOperationStart(batcheslib.LogEventOperationApplyingBatchSpec, &batcheslib.ApplyingBatchSpecMetadata{}) } func (ui *JSONLines) ApplyingBatchSpecSuccess(batchChangeURL string) { - logOperationSuccess(batcheslib.LogEventOperationApplyingBatchSpec, map[string]interface{}{"batchChangeURL": batchChangeURL}) + logOperationSuccess(batcheslib.LogEventOperationApplyingBatchSpec, &batcheslib.ApplyingBatchSpecMetadata{BatchChangeURL: batchChangeURL}) } func (ui *JSONLines) ExecutionError(err error) { - logOperationFailure(batcheslib.LogEventOperationBatchSpecExecution, map[string]interface{}{"error": err.Error()}) -} - -func logOperationStart(op batcheslib.LogEventOperation, metadata map[string]interface{}) { - logEvent(batcheslib.LogEvent{Operation: op, Status: batcheslib.LogEventStatusStarted, Metadata: metadata}) -} - -func logOperationSuccess(op batcheslib.LogEventOperation, metadata map[string]interface{}) { - logEvent(batcheslib.LogEvent{Operation: op, Status: batcheslib.LogEventStatusSuccess, Metadata: metadata}) -} - -func logOperationFailure(op batcheslib.LogEventOperation, metadata map[string]interface{}) { - logEvent(batcheslib.LogEvent{Operation: op, Status: batcheslib.LogEventStatusFailure, Metadata: metadata}) -} - -func logOperationProgress(op batcheslib.LogEventOperation, metadata map[string]interface{}) { - logEvent(batcheslib.LogEvent{Operation: op, Status: batcheslib.LogEventStatusProgress, Metadata: metadata}) -} - -func logEvent(e batcheslib.LogEvent) { - e.Timestamp = time.Now().UTC().Truncate(time.Millisecond) - err := json.NewEncoder(os.Stdout).Encode(e) - if err != nil { - fmt.Fprintln(os.Stderr, err) - } -} - -// TODO: Until we've figured out what exactly we want to expose, we create -// these smaller UI-specific structs. -type jsonLinesTask struct { - ID string `json:"id"` - Repository string `json:"repository"` - Workspace string `json:"workspace"` - Steps []batcheslib.Step `json:"steps"` - CachedStepResultsFound bool `json:"cachedStepResultFound"` - StartStep int `json:"startStep"` + logOperationFailure(batcheslib.LogEventOperationBatchSpecExecution, &batcheslib.BatchSpecExecutionMetadata{Error: err.Error()}) } type taskExecutionJSONLines struct { verbose bool parallelism int - linesTasks map[*executor.Task]jsonLinesTask + linesTasks map[*executor.Task]batcheslib.JSONLinesTask } // seededRand is used in randomID() to generate a "random" number. @@ -212,14 +187,14 @@ func randomID() (string, error) { } func (ui *taskExecutionJSONLines) Start(tasks []*executor.Task) { - ui.linesTasks = make(map[*executor.Task]jsonLinesTask, len(tasks)) - linesTasks := []jsonLinesTask{} + ui.linesTasks = make(map[*executor.Task]batcheslib.JSONLinesTask, len(tasks)) + linesTasks := []batcheslib.JSONLinesTask{} for _, t := range tasks { id, err := randomID() if err != nil { panic(err) } - linesTask := jsonLinesTask{ + linesTask := batcheslib.JSONLinesTask{ ID: id, Repository: t.Repository.Name, Workspace: t.Path, @@ -231,18 +206,16 @@ func (ui *taskExecutionJSONLines) Start(tasks []*executor.Task) { linesTasks = append(linesTasks, linesTask) } - logOperationStart(batcheslib.LogEventOperationExecutingTasks, map[string]interface{}{ - "tasks": linesTasks, + logOperationStart(batcheslib.LogEventOperationExecutingTasks, &batcheslib.ExecutingTasksMetadata{ + Tasks: linesTasks, }) } func (ui *taskExecutionJSONLines) Success() { - logOperationSuccess(batcheslib.LogEventOperationExecutingTasks, nil) + logOperationSuccess(batcheslib.LogEventOperationExecutingTasks, &batcheslib.ExecutingTasksMetadata{}) } func (ui *taskExecutionJSONLines) Failed(err error) { - logOperationFailure(batcheslib.LogEventOperationExecutingTasks, map[string]interface{}{ - "error": err.Error(), - }) + logOperationFailure(batcheslib.LogEventOperationExecutingTasks, &batcheslib.ExecutingTasksMetadata{Error: err.Error()}) } func (ui *taskExecutionJSONLines) TaskStarted(task *executor.Task) { @@ -251,9 +224,7 @@ func (ui *taskExecutionJSONLines) TaskStarted(task *executor.Task) { panic("unknown task started") } - logOperationStart(batcheslib.LogEventOperationExecutingTask, map[string]interface{}{ - "taskID": lt.ID, - }) + logOperationStart(batcheslib.LogEventOperationExecutingTask, &batcheslib.ExecutingTaskMetadata{TaskID: lt.ID}) } func (ui *taskExecutionJSONLines) TaskFinished(task *executor.Task, err error) { @@ -263,16 +234,14 @@ func (ui *taskExecutionJSONLines) TaskFinished(task *executor.Task, err error) { } if err != nil { - logOperationFailure(batcheslib.LogEventOperationExecutingTask, map[string]interface{}{ - "taskID": lt.ID, - "error": err.Error(), + logOperationFailure(batcheslib.LogEventOperationExecutingTask, &batcheslib.ExecutingTaskMetadata{ + TaskID: lt.ID, + Error: err.Error(), }) return } - logOperationSuccess(batcheslib.LogEventOperationExecutingTask, map[string]interface{}{ - "taskID": lt.ID, - }) + logOperationSuccess(batcheslib.LogEventOperationExecutingTask, &batcheslib.ExecutingTaskMetadata{TaskID: lt.ID}) } func (ui *taskExecutionJSONLines) TaskChangesetSpecsBuilt(task *executor.Task, specs []*batcheslib.ChangesetSpec) { @@ -280,9 +249,8 @@ func (ui *taskExecutionJSONLines) TaskChangesetSpecsBuilt(task *executor.Task, s if !ok { panic("unknown task started") } - logOperationSuccess(batcheslib.LogEventOperationTaskBuildChangesetSpecs, map[string]interface{}{ - "taskID": lt.ID, - }) + + logOperationSuccess(batcheslib.LogEventOperationTaskBuildChangesetSpecs, &batcheslib.TaskBuildChangesetSpecsMetadata{TaskID: lt.ID}) } func (ui *taskExecutionJSONLines) StepsExecutionUI(task *executor.Task) executor.StepsExecutionUI { @@ -295,57 +263,59 @@ func (ui *taskExecutionJSONLines) StepsExecutionUI(task *executor.Task) executor } type stepsExecutionJSONLines struct { - linesTask *jsonLinesTask + linesTask *batcheslib.JSONLinesTask } const stepFlushDuration = 500 * time.Millisecond func (ui *stepsExecutionJSONLines) ArchiveDownloadStarted() { - logOperationStart(batcheslib.LogEventOperationTaskDownloadingArchive, map[string]interface{}{"taskID": ui.linesTask.ID}) + logOperationStart(batcheslib.LogEventOperationTaskDownloadingArchive, &batcheslib.TaskDownloadingArchiveMetadata{TaskID: ui.linesTask.ID}) } - -func (ui *stepsExecutionJSONLines) ArchiveDownloadFinished() { - logOperationSuccess(batcheslib.LogEventOperationTaskDownloadingArchive, map[string]interface{}{"taskID": ui.linesTask.ID}) +func (ui *stepsExecutionJSONLines) ArchiveDownloadFinished(err error) { + if err != nil { + logOperationFailure(batcheslib.LogEventOperationTaskDownloadingArchive, &batcheslib.TaskDownloadingArchiveMetadata{TaskID: ui.linesTask.ID, Error: err.Error()}) + } else { + logOperationSuccess(batcheslib.LogEventOperationTaskDownloadingArchive, &batcheslib.TaskDownloadingArchiveMetadata{TaskID: ui.linesTask.ID}) + } } + func (ui *stepsExecutionJSONLines) WorkspaceInitializationStarted() { - logOperationStart(batcheslib.LogEventOperationTaskInitializingWorkspace, map[string]interface{}{"taskID": ui.linesTask.ID}) + logOperationStart(batcheslib.LogEventOperationTaskInitializingWorkspace, &batcheslib.TaskInitializingWorkspaceMetadata{TaskID: ui.linesTask.ID}) } func (ui *stepsExecutionJSONLines) WorkspaceInitializationFinished() { - logOperationSuccess(batcheslib.LogEventOperationTaskInitializingWorkspace, map[string]interface{}{"taskID": ui.linesTask.ID}) + logOperationSuccess(batcheslib.LogEventOperationTaskInitializingWorkspace, &batcheslib.TaskInitializingWorkspaceMetadata{TaskID: ui.linesTask.ID}) } func (ui *stepsExecutionJSONLines) SkippingStepsUpto(startStep int) { - logOperationProgress(batcheslib.LogEventOperationTaskSkippingSteps, map[string]interface{}{"taskID": ui.linesTask.ID, "startStep": startStep}) + logOperationProgress(batcheslib.LogEventOperationTaskSkippingSteps, &batcheslib.TaskSkippingStepsMetadata{TaskID: ui.linesTask.ID, StartStep: startStep}) } func (ui *stepsExecutionJSONLines) StepSkipped(step int) { - logOperationProgress(batcheslib.LogEventOperationTaskStepSkipped, map[string]interface{}{"taskID": ui.linesTask.ID, "step": step}) + logOperationProgress(batcheslib.LogEventOperationTaskStepSkipped, &batcheslib.TaskStepSkippedMetadata{TaskID: ui.linesTask.ID, Step: step}) } func (ui *stepsExecutionJSONLines) StepPreparingStart(step int) { - logOperationStart(batcheslib.LogEventOperationTaskPreparingStep, map[string]interface{}{"taskID": ui.linesTask.ID, "step": step}) + logOperationStart(batcheslib.LogEventOperationTaskPreparingStep, &batcheslib.TaskPreparingStepMetadata{TaskID: ui.linesTask.ID, Step: step}) } - func (ui *stepsExecutionJSONLines) StepPreparingSuccess(step int) { - logOperationSuccess(batcheslib.LogEventOperationTaskPreparingStep, map[string]interface{}{"taskID": ui.linesTask.ID, "step": step}) + logOperationSuccess(batcheslib.LogEventOperationTaskPreparingStep, &batcheslib.TaskPreparingStepMetadata{TaskID: ui.linesTask.ID, Step: step}) } - func (ui *stepsExecutionJSONLines) StepPreparingFailed(step int, err error) { - logOperationFailure(batcheslib.LogEventOperationTaskPreparingStep, map[string]interface{}{"taskID": ui.linesTask.ID, "step": step, "error": err.Error()}) + logOperationFailure(batcheslib.LogEventOperationTaskPreparingStep, &batcheslib.TaskPreparingStepMetadata{TaskID: ui.linesTask.ID, Step: step, Error: err.Error()}) } func (ui *stepsExecutionJSONLines) StepStarted(step int, runScript string, env map[string]string) { - logOperationStart(batcheslib.LogEventOperationTaskStep, map[string]interface{}{"taskID": ui.linesTask.ID, "step": step, "runScript": runScript, "env": env}) + logOperationStart(batcheslib.LogEventOperationTaskStep, &batcheslib.TaskStepMetadata{TaskID: ui.linesTask.ID, Step: step, Env: env}) } func (ui *stepsExecutionJSONLines) StepOutputWriter(ctx context.Context, task *executor.Task, step int) executor.StepOutputWriter { sink := func(data string) { logOperationProgress( batcheslib.LogEventOperationTaskStep, - map[string]interface{}{ - "taskID": ui.linesTask.ID, - "step": step, - "out": data, + &batcheslib.TaskStepMetadata{ + TaskID: ui.linesTask.ID, + Step: step, + Out: data, }, ) } @@ -355,12 +325,11 @@ func (ui *stepsExecutionJSONLines) StepOutputWriter(ctx context.Context, task *e func (ui *stepsExecutionJSONLines) StepFinished(step int, diff []byte, changes *git.Changes, outputs map[string]interface{}) { logOperationSuccess( batcheslib.LogEventOperationTaskStep, - map[string]interface{}{ - "taskID": ui.linesTask.ID, - "step": step, - "diff": string(diff), - "changes": changes, - "outputs": outputs, + &batcheslib.TaskStepMetadata{ + TaskID: ui.linesTask.ID, + Step: step, + Diff: string(diff), + Outputs: outputs, }, ) } @@ -368,18 +337,42 @@ func (ui *stepsExecutionJSONLines) StepFinished(step int, diff []byte, changes * func (ui *stepsExecutionJSONLines) StepFailed(step int, err error, exitCode int) { logOperationFailure( batcheslib.LogEventOperationTaskStep, - map[string]interface{}{ - "taskID": ui.linesTask.ID, - "step": step, - "error": err.Error(), - "exitCode": exitCode, + &batcheslib.TaskStepMetadata{ + TaskID: ui.linesTask.ID, + Step: step, + Error: err.Error(), + ExitCode: exitCode, }, ) } func (ui *stepsExecutionJSONLines) CalculatingDiffStarted() { - logOperationStart(batcheslib.LogEventOperationTaskCalculatingDiff, map[string]interface{}{"taskID": ui.linesTask.ID}) + logOperationStart(batcheslib.LogEventOperationTaskCalculatingDiff, &batcheslib.TaskCalculatingDiffMetadata{TaskID: ui.linesTask.ID}) } func (ui *stepsExecutionJSONLines) CalculatingDiffFinished() { - logOperationSuccess(batcheslib.LogEventOperationTaskCalculatingDiff, map[string]interface{}{"taskID": ui.linesTask.ID}) + logOperationSuccess(batcheslib.LogEventOperationTaskCalculatingDiff, &batcheslib.TaskCalculatingDiffMetadata{TaskID: ui.linesTask.ID}) +} + +func logOperationStart(op batcheslib.LogEventOperation, metadata interface{}) { + logEvent(batcheslib.LogEvent{Operation: op, Status: batcheslib.LogEventStatusStarted, Metadata: metadata}) +} + +func logOperationSuccess(op batcheslib.LogEventOperation, metadata interface{}) { + logEvent(batcheslib.LogEvent{Operation: op, Status: batcheslib.LogEventStatusSuccess, Metadata: metadata}) +} + +func logOperationFailure(op batcheslib.LogEventOperation, metadata interface{}) { + logEvent(batcheslib.LogEvent{Operation: op, Status: batcheslib.LogEventStatusFailure, Metadata: metadata}) +} + +func logOperationProgress(op batcheslib.LogEventOperation, metadata interface{}) { + logEvent(batcheslib.LogEvent{Operation: op, Status: batcheslib.LogEventStatusProgress, Metadata: metadata}) +} + +func logEvent(e batcheslib.LogEvent) { + e.Timestamp = time.Now().UTC().Truncate(time.Millisecond) + err := json.NewEncoder(os.Stdout).Encode(e) + if err != nil { + fmt.Fprintln(os.Stderr, err) + } } diff --git a/internal/batches/ui/task_exec_tui.go b/internal/batches/ui/task_exec_tui.go index 0238d8b1ae..845b9c1445 100644 --- a/internal/batches/ui/task_exec_tui.go +++ b/internal/batches/ui/task_exec_tui.go @@ -437,7 +437,7 @@ type stepsExecTUI struct { func (ui stepsExecTUI) ArchiveDownloadStarted() { ui.updateStatusBar("Downloading archive") } -func (ui stepsExecTUI) ArchiveDownloadFinished() {} +func (ui stepsExecTUI) ArchiveDownloadFinished(err error) {} func (ui stepsExecTUI) WorkspaceInitializationStarted() { ui.updateStatusBar("Initializing workspace") } diff --git a/internal/batches/ui/tui.go b/internal/batches/ui/tui.go index 8013185c3c..1e511ccefa 100644 --- a/internal/batches/ui/tui.go +++ b/internal/batches/ui/tui.go @@ -192,7 +192,7 @@ func (ui *TUI) CreatingBatchSpec() { ui.pending = batchCreatePending(ui.Out, "Creating batch spec on Sourcegraph") } -func (ui *TUI) CreatingBatchSpecSuccess() { +func (ui *TUI) CreatingBatchSpecSuccess(previewURL string) { batchCompletePending(ui.pending, "Creating batch spec on Sourcegraph") } From 3e576329b17a2ce50c1b5888b9b657477d55308f Mon Sep 17 00:00:00 2001 From: Erik Seliger Date: Wed, 29 Sep 2021 14:27:27 +0200 Subject: [PATCH 3/3] Use latest lib --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index 946efc097b..3f21bfb592 100644 --- a/go.mod +++ b/go.mod @@ -21,7 +21,7 @@ require ( github.com/pkg/browser v0.0.0-20180916011732-0a3d74bf9ce4 github.com/sourcegraph/go-diff v0.6.1 github.com/sourcegraph/jsonx v0.0.0-20200629203448-1a936bd500cf - github.com/sourcegraph/sourcegraph/lib v0.0.0-20210920114500-3eabeb8208ef + github.com/sourcegraph/sourcegraph/lib v0.0.0-20210929121718-d5efc9330247 github.com/ssor/bom v0.0.0-20170718123548-6386211fdfcf // indirect github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb // indirect golang.org/x/net v0.0.0-20210614182718-04defd469f4e diff --git a/go.sum b/go.sum index 021eb0d08f..5777c5f8eb 100644 --- a/go.sum +++ b/go.sum @@ -259,8 +259,8 @@ github.com/sourcegraph/go-diff v0.6.1 h1:hmA1LzxW0n1c3Q4YbrFgg4P99GSnebYa3x8gr0H github.com/sourcegraph/go-diff v0.6.1/go.mod h1:iBszgVvyxdc8SFZ7gm69go2KDdt3ag071iBaWPF6cjs= github.com/sourcegraph/jsonx v0.0.0-20200629203448-1a936bd500cf h1:oAdWFqhStsWiiMP/vkkHiMXqFXzl1XfUNOdxKJbd6bI= github.com/sourcegraph/jsonx v0.0.0-20200629203448-1a936bd500cf/go.mod h1:ppFaPm6kpcHnZGqQTFhUIAQRIEhdQDWP1PCv4/ON354= -github.com/sourcegraph/sourcegraph/lib v0.0.0-20210920114500-3eabeb8208ef h1:NVbGTt8WfgPflixd3d1AFKZt+UgOevTE3rUz+8HEM6A= -github.com/sourcegraph/sourcegraph/lib v0.0.0-20210920114500-3eabeb8208ef/go.mod h1:9vLg5fQL9Q3iktfqu96OrswbOq7yqMesMJER9DCy8vk= +github.com/sourcegraph/sourcegraph/lib v0.0.0-20210929121718-d5efc9330247 h1:U1qXWB+6i/YeQ73kirisIEsxCBgNXw4td4QYdYlBeKM= +github.com/sourcegraph/sourcegraph/lib v0.0.0-20210929121718-d5efc9330247/go.mod h1:9vLg5fQL9Q3iktfqu96OrswbOq7yqMesMJER9DCy8vk= github.com/sourcegraph/yaml v1.0.1-0.20200714132230-56936252f152 h1:z/MpntplPaW6QW95pzcAR/72Z5TWDyDnSo0EOcyij9o= github.com/sourcegraph/yaml v1.0.1-0.20200714132230-56936252f152/go.mod h1:GIjDIg/heH5DOkXY3YJ/wNhfHsQHoXGjl8G8amsYQ1I= github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ=