github.com/arieschain/arieschain@v0.0.0-20191023063405-37c074544356/internal/build/util.go (about) 1 package build 2 3 import ( 4 "bytes" 5 "flag" 6 "fmt" 7 "io" 8 "io/ioutil" 9 "log" 10 "os" 11 "os/exec" 12 "path" 13 "path/filepath" 14 "runtime" 15 "strings" 16 "text/template" 17 ) 18 19 var DryRunFlag = flag.Bool("n", false, "dry run, don't execute commands") 20 21 // MustRun executes the given command and exits the host process for 22 // any error. 23 func MustRun(cmd *exec.Cmd) { 24 fmt.Println(">>>", strings.Join(cmd.Args, " ")) 25 if !*DryRunFlag { 26 cmd.Stderr = os.Stderr 27 cmd.Stdout = os.Stdout 28 if err := cmd.Run(); err != nil { 29 log.Fatal(err) 30 } 31 } 32 } 33 34 func MustRunCommand(cmd string, args ...string) { 35 MustRun(exec.Command(cmd, args...)) 36 } 37 38 // GOPATH returns the value that the GOPATH environment 39 // variable should be set to. 40 func GOPATH() string { 41 if os.Getenv("GOPATH") == "" { 42 log.Fatal("GOPATH is not set") 43 } 44 return os.Getenv("GOPATH") 45 } 46 47 // VERSION returns the content of the VERSION file. 48 func VERSION() string { 49 version, err := ioutil.ReadFile("VERSION") 50 if err != nil { 51 log.Fatal(err) 52 } 53 return string(bytes.TrimSpace(version)) 54 } 55 56 var warnedAboutGit bool 57 58 // RunGit runs a git subcommand and returns its output. 59 // The command must complete successfully. 60 func RunGit(args ...string) string { 61 cmd := exec.Command("git", args...) 62 var stdout, stderr bytes.Buffer 63 cmd.Stdout, cmd.Stderr = &stdout, &stderr 64 if err := cmd.Run(); err == exec.ErrNotFound { 65 if !warnedAboutGit { 66 log.Println("Warning: can't find 'git' in PATH") 67 warnedAboutGit = true 68 } 69 return "" 70 } else if err != nil { 71 log.Fatal(strings.Join(cmd.Args, " "), ": ", err, "\n", stderr.String()) 72 } 73 return strings.TrimSpace(stdout.String()) 74 } 75 76 // readGitFile returns content of file in .git directory. 77 func readGitFile(file string) string { 78 content, err := ioutil.ReadFile(path.Join(".git", file)) 79 if err != nil { 80 return "" 81 } 82 return strings.TrimSpace(string(content)) 83 } 84 85 // Render renders the given template file into outputFile. 86 func Render(templateFile, outputFile string, outputPerm os.FileMode, x interface{}) { 87 tpl := template.Must(template.ParseFiles(templateFile)) 88 render(tpl, outputFile, outputPerm, x) 89 } 90 91 // RenderString renders the given template string into outputFile. 92 func RenderString(templateContent, outputFile string, outputPerm os.FileMode, x interface{}) { 93 tpl := template.Must(template.New("").Parse(templateContent)) 94 render(tpl, outputFile, outputPerm, x) 95 } 96 97 func render(tpl *template.Template, outputFile string, outputPerm os.FileMode, x interface{}) { 98 if err := os.MkdirAll(filepath.Dir(outputFile), 0755); err != nil { 99 log.Fatal(err) 100 } 101 out, err := os.OpenFile(outputFile, os.O_CREATE|os.O_WRONLY|os.O_EXCL, outputPerm) 102 if err != nil { 103 log.Fatal(err) 104 } 105 if err := tpl.Execute(out, x); err != nil { 106 log.Fatal(err) 107 } 108 if err := out.Close(); err != nil { 109 log.Fatal(err) 110 } 111 } 112 113 // CopyFile copies a file. 114 func CopyFile(dst, src string, mode os.FileMode) { 115 if err := os.MkdirAll(filepath.Dir(dst), 0755); err != nil { 116 log.Fatal(err) 117 } 118 destFile, err := os.OpenFile(dst, os.O_CREATE|os.O_WRONLY|os.O_TRUNC, mode) 119 if err != nil { 120 log.Fatal(err) 121 } 122 defer destFile.Close() 123 124 srcFile, err := os.Open(src) 125 if err != nil { 126 log.Fatal(err) 127 } 128 defer srcFile.Close() 129 130 if _, err := io.Copy(destFile, srcFile); err != nil { 131 log.Fatal(err) 132 } 133 } 134 135 // GoTool returns the command that runs a go tool. This uses go from GOROOT instead of PATH 136 // so that go commands executed by build use the same version of Go as the 'host' that runs 137 // build code. e.g. 138 // 139 // /usr/lib/go-1.8/bin/go run build/ci.go ... 140 // 141 // runs using go 1.8 and invokes go 1.8 tools from the same GOROOT. This is also important 142 // because runtime.Version checks on the host should match the tools that are run. 143 func GoTool(tool string, args ...string) *exec.Cmd { 144 args = append([]string{tool}, args...) 145 return exec.Command(filepath.Join(runtime.GOROOT(), "bin", "go"), args...) 146 } 147 148 // ExpandPackagesNoVendor expands a cmd/go import path pattern, skipping 149 // vendored packages. 150 func ExpandPackagesNoVendor(patterns []string) []string { 151 expand := false 152 for _, pkg := range patterns { 153 if strings.Contains(pkg, "...") { 154 expand = true 155 } 156 } 157 if expand { 158 cmd := GoTool("list", patterns...) 159 out, err := cmd.CombinedOutput() 160 if err != nil { 161 log.Fatalf("package listing failed: %v\n%s", err, string(out)) 162 } 163 var packages []string 164 for _, line := range strings.Split(string(out), "\n") { 165 if !strings.Contains(line, "/vendor/") { 166 packages = append(packages, strings.TrimSpace(line)) 167 } 168 } 169 return packages 170 } 171 return patterns 172 }