trpc.group/trpc-go/trpc-cmdline@v1.0.9/util/pb/protoc_version.go (about)

     1  // Tencent is pleased to support the open source community by making tRPC available.
     2  //
     3  // Copyright (C) 2023 THL A29 Limited, a Tencent company.
     4  // All rights reserved.
     5  //
     6  // If you have downloaded a copy of the tRPC source code from Tencent,
     7  // please note that tRPC source code is licensed under the  Apache 2.0 License,
     8  // A copy of the Apache 2.0 License is included in this file.
     9  
    10  package pb
    11  
    12  import (
    13  	"fmt"
    14  	"os/exec"
    15  	"strconv"
    16  	"strings"
    17  )
    18  
    19  func protocVersion() (version string, err error) {
    20  	// check installed or not
    21  	_, err = exec.LookPath("protoc")
    22  	if err != nil {
    23  		return "", fmt.Errorf("protoc not found, %v", err)
    24  	}
    25  
    26  	// print version
    27  	cmd := exec.Command("protoc", "--version")
    28  	output, err := cmd.CombinedOutput()
    29  	if err != nil {
    30  		return
    31  	}
    32  
    33  	version = strings.TrimPrefix(strings.TrimSpace(string(output)), "libprotoc ")
    34  	return
    35  }
    36  
    37  const (
    38  	requireProtoVersion = "v3.6.0"
    39  )
    40  
    41  func isOldProtocVersion() (old bool, err error) {
    42  	version, err := protocVersion()
    43  	if err != nil {
    44  		return
    45  	}
    46  	return oldVersion(version)
    47  }
    48  
    49  func oldVersion(version string) (old bool, err error) {
    50  	return !CheckVersionGreaterThanOrEqualTo(version, requireProtoVersion), nil
    51  }
    52  
    53  // CheckVersionGreaterThanOrEqualTo check if version meet the requirement
    54  func CheckVersionGreaterThanOrEqualTo(version, required string) bool {
    55  	version = getVersion(version)
    56  	required = getVersion(required)
    57  
    58  	m1, n1, r1 := semanticVersion(version)
    59  	m2, n2, r2 := semanticVersion(required)
    60  
    61  	if m1 != m2 {
    62  		return m1 > m2
    63  	}
    64  	if n1 != n2 {
    65  		return n1 > n2
    66  	}
    67  	return r1 >= r2
    68  }
    69  
    70  func getVersion(version string) string {
    71  	if len(version) != 0 && (version[0] == 'v' || version[0] == 'V') {
    72  		version = version[1:]
    73  	}
    74  	return version
    75  }
    76  
    77  // semanticVersion extract the major, minor and revision (patching) version
    78  func semanticVersion(ver string) (major, minor, revision int) {
    79  	vv := strings.Split(ver, ".")
    80  
    81  	resultList := make([]int, 3)
    82  	for i := 0; i < len(resultList) && i < len(vv); i++ {
    83  		num, err := strconv.Atoi(vv[i])
    84  		if err != nil {
    85  			break
    86  		}
    87  		resultList[i] = num
    88  	}
    89  
    90  	major = resultList[0]
    91  	minor = resultList[1]
    92  	revision = resultList[2]
    93  
    94  	return
    95  }