go.chromium.org/luci@v0.0.0-20240309015107-7cdc2e660f33/tools/cmd/gorun/main.go (about) 1 // Copyright 2016 The LUCI Authors. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 // Package main defines the `gorun` tool, a shorthand tool to extend the 16 // "go run"-like convenience to packages. 17 // 18 // Unfortunately, "go run" is hard to use when the target has more than one 19 // ".go" file, and even harder when the target has "_test.go" files. 20 // 21 // This is just a bootstrap to "go build /path/to/X && /path/to/X" using a 22 // temporary directory for build storage. 23 package main 24 25 import ( 26 "io/ioutil" 27 "os" 28 "os/exec" 29 "path/filepath" 30 "runtime" 31 32 "go.chromium.org/luci/common/errors" 33 "go.chromium.org/luci/common/system/exitcode" 34 ) 35 36 func mainImpl(args []string) (int, error) { 37 if len(args) < 1 { 38 return 1, errors.New("accepts one argument: package") 39 } 40 pkg, args := args[0], args[1:] 41 42 // Create a temporary output directory to build into. 43 tmpdir, err := ioutil.TempDir("", "luci-gorun") 44 if err != nil { 45 return 1, errors.Annotate(err, "failed to create temporary directory").Err() 46 } 47 defer os.RemoveAll(tmpdir) 48 49 exePath := filepath.Join(tmpdir, "gorun_target") 50 if runtime.GOOS == "windows" { 51 exePath += ".exe" 52 } 53 54 // Build the package. 55 cmd := exec.Command("go", "build", "-o", exePath, pkg) 56 cmd.Stdout = os.Stdout 57 cmd.Stderr = os.Stderr 58 if err := cmd.Run(); err != nil { 59 return 1, errors.Annotate(err, "failed to build: %s", pkg).Err() 60 } 61 62 // Run the package. 63 cmd = exec.Command(exePath, args...) 64 cmd.Stdin = os.Stdin 65 cmd.Stdout = os.Stdout 66 cmd.Stderr = os.Stderr 67 if err := cmd.Run(); err != nil { 68 if rc, ok := exitcode.Get(err); ok { 69 return rc, nil 70 } 71 return 1, errors.Annotate(err, "failed to run: %s", pkg).Err() 72 } 73 74 return 0, nil 75 } 76 77 func main() { 78 rc, err := mainImpl(os.Args[1:]) 79 if err != nil { 80 for _, line := range errors.RenderStack(err) { 81 os.Stderr.WriteString(line + "\n") 82 } 83 } 84 os.Exit(rc) 85 }