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