|
@@ -3,11 +3,15 @@ package main
|
|
|
import (
|
|
import (
|
|
|
"fmt"
|
|
"fmt"
|
|
|
"go/build"
|
|
"go/build"
|
|
|
|
|
+ "io"
|
|
|
"io/ioutil"
|
|
"io/ioutil"
|
|
|
|
|
+ "net/http"
|
|
|
"os"
|
|
"os"
|
|
|
"os/exec"
|
|
"os/exec"
|
|
|
"path/filepath"
|
|
"path/filepath"
|
|
|
|
|
+ "regexp"
|
|
|
"runtime"
|
|
"runtime"
|
|
|
|
|
+ "strconv"
|
|
|
"strings"
|
|
"strings"
|
|
|
)
|
|
)
|
|
|
|
|
|
|
@@ -77,7 +81,62 @@ func GetGOBIN() string {
|
|
|
return GOBIN
|
|
return GOBIN
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+func getProjectProtocVersion(url string) (string, error) {
|
|
|
|
|
+ resp, err := http.Get(url)
|
|
|
|
|
+ if err != nil {
|
|
|
|
|
+ return "", fmt.Errorf("can not get the version of protobuf used in V2Ray project")
|
|
|
|
|
+ }
|
|
|
|
|
+ defer resp.Body.Close()
|
|
|
|
|
+ body, err := io.ReadAll(resp.Body)
|
|
|
|
|
+ if err != nil {
|
|
|
|
|
+ return "", fmt.Errorf("can not read from body")
|
|
|
|
|
+ }
|
|
|
|
|
+ versionRegexp := regexp.MustCompile(`\/\/\s*protoc\s*v(\d+\.\d+\.\d+)`)
|
|
|
|
|
+ matched := versionRegexp.FindStringSubmatch(string(body))
|
|
|
|
|
+ return matched[1], nil
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+func getInstalledProtocVersion(protocPath string) (string, error) {
|
|
|
|
|
+ cmd := exec.Command(protocPath, "--version")
|
|
|
|
|
+ cmd.Env = append(cmd.Env, os.Environ()...)
|
|
|
|
|
+ output, cmdErr := cmd.CombinedOutput()
|
|
|
|
|
+ if cmdErr != nil {
|
|
|
|
|
+ return "", cmdErr
|
|
|
|
|
+ }
|
|
|
|
|
+ versionRegexp := regexp.MustCompile(`protoc\s*(\d+\.\d+\.\d+)`)
|
|
|
|
|
+ matched := versionRegexp.FindStringSubmatch(string(output))
|
|
|
|
|
+ return matched[1], nil
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+func parseVersion(s string, width int) int64 {
|
|
|
|
|
+ strList := strings.Split(s, ".")
|
|
|
|
|
+ format := fmt.Sprintf("%%s%%0%ds", width)
|
|
|
|
|
+ v := ""
|
|
|
|
|
+ for _, value := range strList {
|
|
|
|
|
+ v = fmt.Sprintf(format, v, value)
|
|
|
|
|
+ }
|
|
|
|
|
+ var result int64
|
|
|
|
|
+ var err error
|
|
|
|
|
+ if result, err = strconv.ParseInt(v, 10, 64); err != nil {
|
|
|
|
|
+ return 0
|
|
|
|
|
+ }
|
|
|
|
|
+ return result
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+func needToUpdate(targetedVersion, installedVersion string) bool {
|
|
|
|
|
+ vt := parseVersion(targetedVersion, 4)
|
|
|
|
|
+ vi := parseVersion(installedVersion, 4)
|
|
|
|
|
+
|
|
|
|
|
+ return vt > vi
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
func main() {
|
|
func main() {
|
|
|
|
|
+ targetedVersion, err := getProjectProtocVersion("https://raw.githubusercontent.com/v2fly/v2ray-core/HEAD/config.pb.go")
|
|
|
|
|
+ if err != nil {
|
|
|
|
|
+ fmt.Println(err)
|
|
|
|
|
+ os.Exit(1)
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
pwd, wdErr := os.Getwd()
|
|
pwd, wdErr := os.Getwd()
|
|
|
if wdErr != nil {
|
|
if wdErr != nil {
|
|
|
fmt.Println("Can not get current working directory.")
|
|
fmt.Println("Can not get current working directory.")
|
|
@@ -103,6 +162,24 @@ func main() {
|
|
|
protoc = path
|
|
protoc = path
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+ installedVersion, err := getInstalledProtocVersion(protoc)
|
|
|
|
|
+ if err != nil {
|
|
|
|
|
+ fmt.Println(err)
|
|
|
|
|
+ os.Exit(1)
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ if needToUpdate(targetedVersion, installedVersion) {
|
|
|
|
|
+ fmt.Printf(`
|
|
|
|
|
+You are using an old protobuf version. Please update to v%s or later.
|
|
|
|
|
+Download it from https://github.com/protocolbuffers/protobuf/releases
|
|
|
|
|
+
|
|
|
|
|
+ * Protobuf version used in V2Ray project: v%s
|
|
|
|
|
+ * Protobuf version you have installed: v%s
|
|
|
|
|
+
|
|
|
|
|
+`, targetedVersion, targetedVersion, installedVersion)
|
|
|
|
|
+ os.Exit(1)
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
protoFilesMap := make(map[string][]string)
|
|
protoFilesMap := make(map[string][]string)
|
|
|
walkErr := filepath.Walk("./", func(path string, info os.FileInfo, err error) error {
|
|
walkErr := filepath.Walk("./", func(path string, info os.FileInfo, err error) error {
|
|
|
if err != nil {
|
|
if err != nil {
|