From 389ff73a2619fffa8f27eb5977bea42308892ca4 Mon Sep 17 00:00:00 2001 From: Loyalsoldier <10487845+Loyalsoldier@users.noreply.github.com> Date: Wed, 24 Mar 2021 11:49:32 +0800 Subject: [PATCH] Feat: vprotogen adds version detector (#819) * Feat: vprotogen adds version detector to block generation code from old protobuf version * Chore: update .gitignore --- .gitignore | 1 + infra/vprotogen/main.go | 77 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 78 insertions(+) diff --git a/.gitignore b/.gitignore index 8b4741025..436682076 100644 --- a/.gitignore +++ b/.gitignore @@ -22,3 +22,4 @@ v2ray v2ctl mockgen vprotogen +!infra/vprotogen/ diff --git a/infra/vprotogen/main.go b/infra/vprotogen/main.go index e7d6efe6d..4e1e7f892 100644 --- a/infra/vprotogen/main.go +++ b/infra/vprotogen/main.go @@ -3,11 +3,15 @@ package main import ( "fmt" "go/build" + "io" "io/ioutil" + "net/http" "os" "os/exec" "path/filepath" + "regexp" "runtime" + "strconv" "strings" ) @@ -77,7 +81,62 @@ func GetGOBIN() string { 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() { + 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() if wdErr != nil { fmt.Println("Can not get current working directory.") @@ -103,6 +162,24 @@ func main() { 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) walkErr := filepath.Walk("./", func(path string, info os.FileInfo, err error) error { if err != nil {