main.go 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180
  1. package main
  2. import (
  3. "fmt"
  4. "go/build"
  5. "io/ioutil"
  6. "os"
  7. "os/exec"
  8. "path/filepath"
  9. "runtime"
  10. "strings"
  11. )
  12. // envFile returns the name of the Go environment configuration file.
  13. // Copy from https://github.com/golang/go/blob/c4f2a9788a7be04daf931ac54382fbe2cb754938/src/cmd/go/internal/cfg/cfg.go#L150-L166
  14. func envFile() (string, error) {
  15. if file := os.Getenv("GOENV"); file != "" {
  16. if file == "off" {
  17. return "", fmt.Errorf("GOENV=off")
  18. }
  19. return file, nil
  20. }
  21. dir, err := os.UserConfigDir()
  22. if err != nil {
  23. return "", err
  24. }
  25. if dir == "" {
  26. return "", fmt.Errorf("missing user-config dir")
  27. }
  28. return filepath.Join(dir, "go", "env"), nil
  29. }
  30. // GetRuntimeEnv returns the value of runtime environment variable,
  31. // that is set by running following command: `go env -w key=value`.
  32. func GetRuntimeEnv(key string) (string, error) {
  33. file, err := envFile()
  34. if err != nil {
  35. return "", err
  36. }
  37. if file == "" {
  38. return "", fmt.Errorf("missing runtime env file")
  39. }
  40. var data []byte
  41. var runtimeEnv string
  42. data, readErr := ioutil.ReadFile(file)
  43. if readErr != nil {
  44. return "", readErr
  45. }
  46. envStrings := strings.Split(string(data), "\n")
  47. for _, envItem := range envStrings {
  48. envItem = strings.TrimSuffix(envItem, "\r")
  49. envKeyValue := strings.Split(envItem, "=")
  50. if strings.EqualFold(strings.TrimSpace(envKeyValue[0]), key) {
  51. runtimeEnv = strings.TrimSpace(envKeyValue[1])
  52. }
  53. }
  54. return runtimeEnv, nil
  55. }
  56. // GetGOBIN returns GOBIN environment variable as a string. It will NOT be empty.
  57. func GetGOBIN() string {
  58. // The one set by user explicitly by `export GOBIN=/path` or `env GOBIN=/path command`
  59. GOBIN := os.Getenv("GOBIN")
  60. if GOBIN == "" {
  61. var err error
  62. // The one set by user by running `go env -w GOBIN=/path`
  63. GOBIN, err = GetRuntimeEnv("GOBIN")
  64. if err != nil {
  65. // The default one that Golang uses
  66. return filepath.Join(build.Default.GOPATH, "bin")
  67. }
  68. if GOBIN == "" {
  69. return filepath.Join(build.Default.GOPATH, "bin")
  70. }
  71. return GOBIN
  72. }
  73. return GOBIN
  74. }
  75. func Run(binary string, args []string) (string, error) {
  76. cmd := exec.Command(binary, args...)
  77. cmd.Env = append(cmd.Env, os.Environ()...)
  78. output, cmdErr := cmd.CombinedOutput()
  79. if cmdErr != nil {
  80. return "", cmdErr
  81. }
  82. if len(output) > 0 {
  83. return string(output), nil
  84. }
  85. return "", nil
  86. }
  87. func RunMany(binary string, args, files []string) {
  88. fmt.Println("Processing...")
  89. for _, file := range files {
  90. args2 := append(args, file)
  91. output, err := Run(binary, args2)
  92. if err != nil {
  93. fmt.Println(err)
  94. continue
  95. }
  96. if len(output) > 0 {
  97. fmt.Println(output)
  98. }
  99. }
  100. }
  101. func main() {
  102. pwd, err := os.Getwd()
  103. if err != nil {
  104. fmt.Println("Can not get current working directory.")
  105. os.Exit(1)
  106. }
  107. GOBIN := GetGOBIN()
  108. binPath := os.Getenv("PATH")
  109. pathSlice := []string{pwd, GOBIN, binPath}
  110. binPath = strings.Join(pathSlice, string(os.PathListSeparator))
  111. os.Setenv("PATH", binPath)
  112. suffix := ""
  113. if runtime.GOOS == "windows" {
  114. suffix = ".exe"
  115. }
  116. gofmt := "gofmt" + suffix
  117. goimports := "goimports" + suffix
  118. if gofmtPath, err := exec.LookPath(gofmt); err != nil {
  119. fmt.Println("Can not find", gofmt, "in system path or current working directory.")
  120. os.Exit(1)
  121. } else {
  122. gofmt = gofmtPath
  123. }
  124. if goimportsPath, err := exec.LookPath(goimports); err != nil {
  125. fmt.Println("Can not find", goimports, "in system path or current working directory.")
  126. os.Exit(1)
  127. } else {
  128. goimports = goimportsPath
  129. }
  130. rawFilesSlice := make([]string, 0)
  131. walkErr := filepath.Walk("./", func(path string, info os.FileInfo, err error) error {
  132. if err != nil {
  133. fmt.Println(err)
  134. return err
  135. }
  136. if info.IsDir() {
  137. return nil
  138. }
  139. dir := filepath.Dir(path)
  140. filename := filepath.Base(path)
  141. if strings.HasSuffix(filename, ".go") &&
  142. !strings.HasSuffix(filename, ".pb.go") &&
  143. !strings.Contains(dir, filepath.Join("testing", "mocks")) {
  144. rawFilesSlice = append(rawFilesSlice, path)
  145. }
  146. return nil
  147. })
  148. if walkErr != nil {
  149. fmt.Println(walkErr)
  150. os.Exit(1)
  151. }
  152. gofmtArgs := []string{
  153. "-s", "-l", "-e", "-w",
  154. }
  155. goimportsArgs := []string{
  156. "-w",
  157. "-local", "github.com/v2fly/v2ray-core",
  158. }
  159. RunMany(gofmt, gofmtArgs, rawFilesSlice)
  160. RunMany(goimports, goimportsArgs, rawFilesSlice)
  161. fmt.Println("Do NOT forget to commit file changes.")
  162. }