From ea3641f91c73fa217bde39e047103913eb79b774 Mon Sep 17 00:00:00 2001 From: Mehul Kar Date: Wed, 29 Mar 2023 11:24:17 -0700 Subject: [PATCH 1/5] Log the location of the summary file in the execution summary --- cli/internal/run/real_run.go | 2 +- cli/internal/run/run.go | 1 + .../runsummary/format_execution_summary.go | 31 ++++++++++++++++--- cli/internal/runsummary/run_summary.go | 31 +++++++++++++------ 4 files changed, 50 insertions(+), 15 deletions(-) diff --git a/cli/internal/run/real_run.go b/cli/internal/run/real_run.go index 50725e539cc5e..150afbdf2dac3 100644 --- a/cli/internal/run/real_run.go +++ b/cli/internal/run/real_run.go @@ -167,7 +167,7 @@ func RealRun( } } - runSummary.Close(exitCode, base.RepoRoot) + runSummary.Close(exitCode) if exitCode != 0 { return &process.ChildExit{ diff --git a/cli/internal/run/run.go b/cli/internal/run/run.go index 2d43446e28302..5acb3d3a94cbc 100644 --- a/cli/internal/run/run.go +++ b/cli/internal/run/run.go @@ -352,6 +352,7 @@ func (r *run) run(ctx gocontext.Context, targets []string) error { summary := runsummary.NewRunSummary( startAt, r.base.UI, + r.base.RepoRoot, rs.Opts.runOpts.singlePackage, rs.Opts.runOpts.profile, r.base.TurboVersion, diff --git a/cli/internal/runsummary/format_execution_summary.go b/cli/internal/runsummary/format_execution_summary.go index 647bddb3fd032..3000cb7f21398 100644 --- a/cli/internal/runsummary/format_execution_summary.go +++ b/cli/internal/runsummary/format_execution_summary.go @@ -37,11 +37,32 @@ func (rsm *Meta) printExecutionSummary() { ui.Warn("No tasks were executed as part of this run.") } - ui.Output("") // Clear the line + ui.Output("") // Clear the line + spacer := " " // 4 chars + + // We'll start with some default lines + lines := []string{ + util.Sprintf("${BOLD} Tasks:${BOLD_GREEN}%s%v successful${RESET}${GRAY}, %v total${RESET}", spacer, success, attempted), + util.Sprintf("${BOLD}Cached:%s%v cached${RESET}${GRAY}, %v total${RESET}", spacer, cached, attempted), + util.Sprintf("${BOLD} Time:%s%v${RESET} %v${RESET}", spacer, duration, maybeFullTurbo), + } + + // If we have a run summary file and we can get a + if rsm.getPath().FileExists() { + if relativePath, err := rsm.repoRoot.PathTo(rsm.getPath()); err == nil { + lines = []string{ + util.Sprintf("${BOLD} Tasks:${BOLD_GREEN}%s%v successful${RESET}${GRAY}, %v total${RESET}", spacer, successful, attempted), + util.Sprintf("${BOLD} Cached:%s%v cached${RESET}${GRAY}, %v total${RESET}", spacer, cached, attempted), + util.Sprintf("${BOLD} Time:%s%v${RESET} %v${RESET}", spacer, duration, maybeFullTurbo), + util.Sprintf("${BOLD}Summary:%s%s${RESET}", spacer, relativePath), + } + } + } + + // Print the real thing + for _, line := range lines { + ui.Output(line) + } - // The whitespaces in the string are to align the UI in a nice way. - ui.Output(util.Sprintf("${BOLD} Tasks:${BOLD_GREEN} %v successful${RESET}${GRAY}, %v total${RESET}", successful, attempted)) - ui.Output(util.Sprintf("${BOLD}Cached: %v cached${RESET}${GRAY}, %v total${RESET}", cached, attempted)) - ui.Output(util.Sprintf("${BOLD} Time: %v${RESET} %v${RESET}", duration, maybeFullTurbo)) ui.Output("") } diff --git a/cli/internal/runsummary/run_summary.go b/cli/internal/runsummary/run_summary.go index 250cf6e5ada03..9c012921c7d83 100644 --- a/cli/internal/runsummary/run_summary.go +++ b/cli/internal/runsummary/run_summary.go @@ -31,6 +31,7 @@ const tasksEndpoint = "/v0/spaces/%s/runs/%s/tasks" type Meta struct { RunSummary *RunSummary ui cli.Ui + repoRoot turbopath.AbsoluteSystemPath // used to write run summary singlePackage bool shouldSave bool apiClient *client.APIClient @@ -59,6 +60,7 @@ type singlePackageRunSummary struct { func NewRunSummary( startAt time.Time, terminal cli.Ui, + repoRoot turbopath.AbsoluteSystemPath, singlePackage bool, profile string, turboVersion string, @@ -81,6 +83,7 @@ func NewRunSummary( GlobalHashSummary: globalHashSummary, }, ui: terminal, + repoRoot: repoRoot, singlePackage: singlePackage, shouldSave: shouldSave, apiClient: apiClient, @@ -88,8 +91,16 @@ func NewRunSummary( } } +// getPath returns a path to where the runSummary is written. +// The returned path will always be relative to the dir passsed in. +// We don't do a lot of validation, so `../../` paths are allowed. +func (rsm *Meta) getPath() turbopath.AbsoluteSystemPath { + filename := fmt.Sprintf("%s.json", rsm.RunSummary.ID) + return rsm.repoRoot.UntypedJoin(filepath.Join(".turbo", "runs"), filename) +} + // Close wraps up the RunSummary at the end of a `turbo run`. -func (rsm *Meta) Close(exitCode int, dir turbopath.AbsoluteSystemPath) { +func (rsm *Meta) Close(exitCode int) { rsm.RunSummary.ExecutionSummary.exitCode = exitCode rsm.RunSummary.ExecutionSummary.endedAt = time.Now() @@ -102,19 +113,24 @@ func (rsm *Meta) Close(exitCode int, dir turbopath.AbsoluteSystemPath) { // are all the same thng, we should use a strategy similar to cache save/upload to // do this in parallel. - rsm.printExecutionSummary() - + // Otherwise, attempt to save the summary + // Warn on the error, but we don't need to throw an error if rsm.shouldSave { - if err := rsm.save(dir); err != nil { + if err := rsm.save(); err != nil { rsm.ui.Warn(fmt.Sprintf("Error writing run summary: %v", err)) } + } + rsm.printExecutionSummary() + + if rsm.shouldSave { if rsm.spaceID != "" && rsm.apiClient.IsLinked() { if err := rsm.record(); err != nil { rsm.ui.Warn(fmt.Sprintf("Error recording Run to Vercel: %v", err)) } } } + } // TrackTask makes it possible for the consumer to send information about the execution of a task. @@ -123,7 +139,7 @@ func (summary *RunSummary) TrackTask(taskID string) (func(outcome executionEvent } // Save saves the run summary to a file -func (rsm *Meta) save(dir turbopath.AbsoluteSystemPath) error { +func (rsm *Meta) save() error { json, err := rsm.FormatJSON() if err != nil { return err @@ -131,10 +147,7 @@ func (rsm *Meta) save(dir turbopath.AbsoluteSystemPath) error { // summaryPath will always be relative to the dir passsed in. // We don't do a lot of validation, so `../../` paths are allowed - summaryPath := dir.UntypedJoin( - filepath.Join(".turbo", "runs"), - fmt.Sprintf("%s.json", rsm.RunSummary.ID), - ) + summaryPath := rsm.getPath() if err := summaryPath.EnsureDir(); err != nil { return err From e8fd9b868ac292f420ac876b12c5941eb74d8460 Mon Sep 17 00:00:00 2001 From: Mehul Kar Date: Wed, 29 Mar 2023 11:31:33 -0700 Subject: [PATCH 2/5] Add test --- .../basic_monorepo/run_summary/discovery.t | 21 +++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 cli/integration_tests/basic_monorepo/run_summary/discovery.t diff --git a/cli/integration_tests/basic_monorepo/run_summary/discovery.t b/cli/integration_tests/basic_monorepo/run_summary/discovery.t new file mode 100644 index 0000000000000..1f6f4df10dc22 --- /dev/null +++ b/cli/integration_tests/basic_monorepo/run_summary/discovery.t @@ -0,0 +1,21 @@ +Setup + $ . ${TESTDIR}/../../setup.sh + $ . ${TESTDIR}/../setup.sh $(pwd) + $ rm -rf .turbo/runs + + $ ${TURBO} run build --summarize=true --filter=my-app + \xe2\x80\xa2 Packages in scope: my-app (esc) + \xe2\x80\xa2 Running build in 1 packages (esc) + \xe2\x80\xa2 Remote caching disabled (esc) + my-app:build: cache miss, executing 2f192ed93e20f940 + my-app:build: + my-app:build: > build + my-app:build: > echo 'building' + my-app:build: + my-app:build: building + + Tasks: 1 successful, 1 total + Cached: 0 cached, 1 total + Time:\s*[\.0-9]+m?s (re) + Summary: .turbo/runs/[a-zA-Z0-9]+.json (re) + \ No newline at end of file From 0ec0b097711ffda911badc6a8a2650345b582c08 Mon Sep 17 00:00:00 2001 From: Mehul Kar Date: Wed, 29 Mar 2023 12:48:42 -0700 Subject: [PATCH 3/5] print absolute path --- .../basic_monorepo/run_summary/discovery.t | 2 +- .../runsummary/format_execution_summary.go | 17 ++++++++--------- 2 files changed, 9 insertions(+), 10 deletions(-) diff --git a/cli/integration_tests/basic_monorepo/run_summary/discovery.t b/cli/integration_tests/basic_monorepo/run_summary/discovery.t index 1f6f4df10dc22..79e629f03a6d0 100644 --- a/cli/integration_tests/basic_monorepo/run_summary/discovery.t +++ b/cli/integration_tests/basic_monorepo/run_summary/discovery.t @@ -17,5 +17,5 @@ Setup Tasks: 1 successful, 1 total Cached: 0 cached, 1 total Time:\s*[\.0-9]+m?s (re) - Summary: .turbo/runs/[a-zA-Z0-9]+.json (re) + Summary: .+\.turbo\/runs\/[a-zA-Z0-9]+.json (re) \ No newline at end of file diff --git a/cli/internal/runsummary/format_execution_summary.go b/cli/internal/runsummary/format_execution_summary.go index 3000cb7f21398..8fb63f892948e 100644 --- a/cli/internal/runsummary/format_execution_summary.go +++ b/cli/internal/runsummary/format_execution_summary.go @@ -42,20 +42,19 @@ func (rsm *Meta) printExecutionSummary() { // We'll start with some default lines lines := []string{ - util.Sprintf("${BOLD} Tasks:${BOLD_GREEN}%s%v successful${RESET}${GRAY}, %v total${RESET}", spacer, success, attempted), + util.Sprintf("${BOLD} Tasks:${BOLD_GREEN}%s%v successful${RESET}${GRAY}, %v total${RESET}", spacer, successful, attempted), util.Sprintf("${BOLD}Cached:%s%v cached${RESET}${GRAY}, %v total${RESET}", spacer, cached, attempted), util.Sprintf("${BOLD} Time:%s%v${RESET} %v${RESET}", spacer, duration, maybeFullTurbo), } - // If we have a run summary file and we can get a + // If we have a run summary file, add that in. We have to do some whitespace adjusting, so just + // duplicate the lines above instead of using some fancy tabbibg/spacing mechanism. if rsm.getPath().FileExists() { - if relativePath, err := rsm.repoRoot.PathTo(rsm.getPath()); err == nil { - lines = []string{ - util.Sprintf("${BOLD} Tasks:${BOLD_GREEN}%s%v successful${RESET}${GRAY}, %v total${RESET}", spacer, successful, attempted), - util.Sprintf("${BOLD} Cached:%s%v cached${RESET}${GRAY}, %v total${RESET}", spacer, cached, attempted), - util.Sprintf("${BOLD} Time:%s%v${RESET} %v${RESET}", spacer, duration, maybeFullTurbo), - util.Sprintf("${BOLD}Summary:%s%s${RESET}", spacer, relativePath), - } + lines = []string{ + util.Sprintf("${BOLD} Tasks:${BOLD_GREEN}%s%v successful${RESET}${GRAY}, %v total${RESET}", spacer, successful, attempted), + util.Sprintf("${BOLD} Cached:%s%v cached${RESET}${GRAY}, %v total${RESET}", spacer, cached, attempted), + util.Sprintf("${BOLD} Time:%s%v${RESET} %v${RESET}", spacer, duration, maybeFullTurbo), + util.Sprintf("${BOLD}Summary:%s%s${RESET}", spacer, rsm.getPath()), } } From c26ffbf86e2ff52bf2af863f7e34f8be00331d9e Mon Sep 17 00:00:00 2001 From: Mehul Kar Date: Wed, 29 Mar 2023 14:01:01 -0700 Subject: [PATCH 4/5] else --- .../runsummary/format_execution_summary.go | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/cli/internal/runsummary/format_execution_summary.go b/cli/internal/runsummary/format_execution_summary.go index 8fb63f892948e..37092beb06a1b 100644 --- a/cli/internal/runsummary/format_execution_summary.go +++ b/cli/internal/runsummary/format_execution_summary.go @@ -40,15 +40,12 @@ func (rsm *Meta) printExecutionSummary() { ui.Output("") // Clear the line spacer := " " // 4 chars - // We'll start with some default lines - lines := []string{ - util.Sprintf("${BOLD} Tasks:${BOLD_GREEN}%s%v successful${RESET}${GRAY}, %v total${RESET}", spacer, successful, attempted), - util.Sprintf("${BOLD}Cached:%s%v cached${RESET}${GRAY}, %v total${RESET}", spacer, cached, attempted), - util.Sprintf("${BOLD} Time:%s%v${RESET} %v${RESET}", spacer, duration, maybeFullTurbo), - } + var lines []string - // If we have a run summary file, add that in. We have to do some whitespace adjusting, so just - // duplicate the lines above instead of using some fancy tabbibg/spacing mechanism. + // The only difference between these two branches is that when there is a run summary + // we print the path to that file and we adjust the whitespace in the printed text so it aligns. + // We could just always align to account for the summary line, but that would require a whole + // bunch of test output assertions to change. if rsm.getPath().FileExists() { lines = []string{ util.Sprintf("${BOLD} Tasks:${BOLD_GREEN}%s%v successful${RESET}${GRAY}, %v total${RESET}", spacer, successful, attempted), @@ -56,6 +53,12 @@ func (rsm *Meta) printExecutionSummary() { util.Sprintf("${BOLD} Time:%s%v${RESET} %v${RESET}", spacer, duration, maybeFullTurbo), util.Sprintf("${BOLD}Summary:%s%s${RESET}", spacer, rsm.getPath()), } + } else { + lines = []string{ + util.Sprintf("${BOLD} Tasks:${BOLD_GREEN}%s%v successful${RESET}${GRAY}, %v total${RESET}", spacer, successful, attempted), + util.Sprintf("${BOLD}Cached:%s%v cached${RESET}${GRAY}, %v total${RESET}", spacer, cached, attempted), + util.Sprintf("${BOLD} Time:%s%v${RESET} %v${RESET}", spacer, duration, maybeFullTurbo), + } } // Print the real thing From f260680da132ff5ec9762b33ecfab6bde49dbb36 Mon Sep 17 00:00:00 2001 From: Mehul Kar Date: Wed, 29 Mar 2023 14:02:41 -0700 Subject: [PATCH 5/5] conver tback --- cli/internal/runsummary/format_execution_summary.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/cli/internal/runsummary/format_execution_summary.go b/cli/internal/runsummary/format_execution_summary.go index 37092beb06a1b..961cc265a49c3 100644 --- a/cli/internal/runsummary/format_execution_summary.go +++ b/cli/internal/runsummary/format_execution_summary.go @@ -55,9 +55,9 @@ func (rsm *Meta) printExecutionSummary() { } } else { lines = []string{ - util.Sprintf("${BOLD} Tasks:${BOLD_GREEN}%s%v successful${RESET}${GRAY}, %v total${RESET}", spacer, successful, attempted), - util.Sprintf("${BOLD}Cached:%s%v cached${RESET}${GRAY}, %v total${RESET}", spacer, cached, attempted), - util.Sprintf("${BOLD} Time:%s%v${RESET} %v${RESET}", spacer, duration, maybeFullTurbo), + util.Sprintf("${BOLD} Tasks:${BOLD_GREEN} %v successful${RESET}${GRAY}, %v total${RESET}", successful, attempted), + util.Sprintf("${BOLD}Cached: %v cached${RESET}${GRAY}, %v total${RESET}", cached, attempted), + util.Sprintf("${BOLD} Time: %v${RESET} %v${RESET}", duration, maybeFullTurbo), } }