diff --git a/cli/internal/login/login.go b/cli/internal/login/login.go index d0a24067e0eae..65438cd67a267 100644 --- a/cli/internal/login/login.go +++ b/cli/internal/login/login.go @@ -3,16 +3,14 @@ package login import ( "context" "fmt" - "log" "net/http" "net/url" "os" - "os/exec" - "runtime" "strings" "turbo/internal/config" "turbo/internal/ui" "turbo/internal/util" + "turbo/internal/util/browser" "github.com/fatih/color" "github.com/hashicorp/go-hclog" @@ -53,7 +51,7 @@ func (c *LoginCommand) Run(args []string) int { loginUrl := fmt.Sprintf("%v/turborepo/token?redirect_uri=%v", c.Config.LoginUrl, redirectUrl) c.Ui.Info(util.Sprintf(">>> Opening browser to %v", c.Config.LoginUrl)) s := ui.NewSpinner(os.Stdout) - openbrowser(loginUrl) + browser.OpenBrowser(loginUrl) s.Start("Waiting for your authorization...") var query url.Values @@ -127,22 +125,3 @@ func (c *LoginCommand) logFatal(log hclog.Logger, prefix string, err error) { c.Ui.Error(fmt.Sprintf("%s%s%s", ui.ERROR_PREFIX, prefix, color.RedString(" %v", err))) os.Exit(1) } - -func openbrowser(url string) { - var err error - - switch runtime.GOOS { - case "linux": - err = exec.Command("xdg-open", url).Start() - case "windows": - err = exec.Command("rundll32", "url.dll,FileProtocolHandler", url).Start() - case "darwin": - err = exec.Command("open", url).Start() - default: - err = fmt.Errorf("unsupported platform") - } - if err != nil { - log.Fatal(err) - } - -} diff --git a/cli/internal/run/run.go b/cli/internal/run/run.go index a4f730252ca9e..d612c424783df 100644 --- a/cli/internal/run/run.go +++ b/cli/internal/run/run.go @@ -8,7 +8,6 @@ import ( "log" "os" "os/exec" - "path" "path/filepath" "sort" "strconv" @@ -24,13 +23,13 @@ import ( "turbo/internal/scm" "turbo/internal/ui" "turbo/internal/util" + "turbo/internal/util/browser" "github.com/pyr-sh/dag" "github.com/fatih/color" glob "github.com/gobwas/glob" "github.com/hashicorp/go-hclog" - "github.com/mattn/go-isatty" "github.com/mitchellh/cli" "github.com/pkg/errors" ) @@ -613,9 +612,39 @@ func (c *RunCommand) Run(args []string) int { Verbose: true, DrawCycles: true, })) + ext := filepath.Ext(runOptions.dotGraph) + if ext == ".html" { + f, err := os.Create(filepath.Join(cwd, runOptions.dotGraph)) + if err != nil { + c.logError(c.Config.Logger, "", fmt.Errorf("error writing graph: %w", err)) + return 1 + } + defer f.Close() + f.WriteString(` + + + + Graph + + + + + + + `) + c.Ui.Output("") + c.Ui.Output(fmt.Sprintf("✔ Generated task graph in %s", ui.Bold(runOptions.dotGraph))) + if ui.IsTTY { + browser.OpenBrowser(filepath.Join(cwd, runOptions.dotGraph)) + } + return 0 + } hasDot := hasGraphViz() if hasDot { - dotArgs := []string{"-T" + path.Ext(runOptions.dotGraph)[1:], "-o", runOptions.dotGraph} + dotArgs := []string{"-T" + ext[1:], "-o", runOptions.dotGraph} cmd := exec.Command("dot", dotArgs...) cmd.Stdin = strings.NewReader(graphString) if err := cmd.Run(); err != nil { @@ -808,7 +837,7 @@ func parseRunArgs(args []string, cwd string) (*RunOptions, error) { } // Force streaming output in CI/CD non-interactive mode - if !isatty.IsTerminal(os.Stdout.Fd()) || os.Getenv("CI") != "" { + if !ui.IsTTY || ui.IsCI { runOptions.stream = true } diff --git a/cli/internal/util/browser/open.go b/cli/internal/util/browser/open.go new file mode 100644 index 0000000000000..291ec30f55c28 --- /dev/null +++ b/cli/internal/util/browser/open.go @@ -0,0 +1,27 @@ +package browser + +import ( + "fmt" + "log" + "os/exec" + "runtime" +) + +func OpenBrowser(url string) { + var err error + + switch runtime.GOOS { + case "linux": + err = exec.Command("xdg-open", url).Start() + case "windows": + err = exec.Command("rundll32", "url.dll,FileProtocolHandler", url).Start() + case "darwin": + err = exec.Command("open", url).Start() + default: + err = fmt.Errorf("unsupported platform") + } + if err != nil { + log.Fatal(err) + } + +} diff --git a/docs/pages/docs/reference/command-line-reference.mdx b/docs/pages/docs/reference/command-line-reference.mdx index 0d555b977bce1..5e5be2cc7326d 100644 --- a/docs/pages/docs/reference/command-line-reference.mdx +++ b/docs/pages/docs/reference/command-line-reference.mdx @@ -82,7 +82,7 @@ Let's say you have packages A, B, C, and D where A depends on B and C depends on `type: string` -If [Graphviz](https://graphviz.org) is installed, this command will generate an svg, png, jpg, pdf, json, or [other supported output formats](https://graphviz.org/doc/info/output.html) of the current task graph. +If [Graphviz](https://graphviz.org) is installed, this command will generate an svg, png, jpg, pdf, json, html, or [other supported output formats](https://graphviz.org/doc/info/output.html) of the current task graph. The output file format can be controlled with the filename's extension if it is specified. If a filename is not specified, `graph-.jpg` is outputted. If Graphviz is not installed, this command prints the dot graph to `stdout`. @@ -93,6 +93,7 @@ turbo run build test lint --graph=my-graph.svg turbo run build test lint --graph=my-json-graph.json turbo run build test lint --graph=my-graph.pdf turbo run build test lint --graph=my-graph.png +turbo run build test lint --graph=my-graph.html ```