EnsureCli builds the CLI using 'go build' if it does not already exist. note: this will always deliberately build the CLI the first time you invoke it, just in case you have an existing out-of-date binary lying around from some prior thing
()
| 112 | // note: this will always deliberately build the CLI the first time you invoke it, just in case |
| 113 | // you have an existing out-of-date binary lying around from some prior thing |
| 114 | func EnsureCli() (cliPath string, cliDir string, err error) { |
| 115 | cliPath, cliDir, err = GetCliPath() |
| 116 | if err != nil { |
| 117 | return |
| 118 | } |
| 119 | |
| 120 | shouldCompile := !ensureCliHasRun |
| 121 | _, err = os.Stat(cliPath) |
| 122 | if err != nil { |
| 123 | if os.IsNotExist(err) { |
| 124 | shouldCompile = true |
| 125 | err = nil // not really an error as we're going to recover it by compiling the app |
| 126 | } else { |
| 127 | return |
| 128 | } |
| 129 | } |
| 130 | |
| 131 | if shouldCompile { |
| 132 | capturedStdout, capturedStderr, runErr := runExecutable("go", []string{"build", "."}, cliDir, os.Environ()) |
| 133 | |
| 134 | // typically the go compiler doesn't emit any output, so don't expect anything here |
| 135 | // always print stdout/stderr even if the process failed |
| 136 | fmt.Println(capturedStdout) |
| 137 | if len(capturedStderr) > 0 { |
| 138 | fmt.Println(output.Red(capturedStderr)) |
| 139 | } |
| 140 | |
| 141 | if runErr != nil { |
| 142 | if exiterr, ok := runErr.(*exec.ExitError); ok { |
| 143 | err = fmt.Errorf("go build failed with exit code %d", exiterr.ExitCode()) |
| 144 | } |
| 145 | return // fail |
| 146 | } |
| 147 | } |
| 148 | |
| 149 | ensureCliHasRun = true |
| 150 | return |
| 151 | } |
| 152 | |
| 153 | func createEnvForCli(space string) []string { |
| 154 | return []string{ |
no test coverage detected