github.com/gogf/gf/v2@v2.7.4/text/gstr/gstr_version.go (about) 1 // Copyright GoFrame Author(https://goframe.org). All Rights Reserved. 2 // 3 // This Source Code Form is subject to the terms of the MIT License. 4 // If a copy of the MIT was not distributed with this file, 5 // You can obtain one at https://github.com/gogf/gf. 6 7 package gstr 8 9 import ( 10 "strings" 11 12 "github.com/gogf/gf/v2/util/gconv" 13 ) 14 15 // IsGNUVersion checks and returns whether given `version` is valid GNU version string. 16 func IsGNUVersion(version string) bool { 17 if version != "" && (version[0] == 'v' || version[0] == 'V') { 18 version = version[1:] 19 } 20 if version == "" { 21 return false 22 } 23 var array = strings.Split(version, ".") 24 if len(array) > 3 { 25 return false 26 } 27 for _, v := range array { 28 if v == "" { 29 return false 30 } 31 if !IsNumeric(v) { 32 return false 33 } 34 if v[0] == '-' || v[0] == '+' { 35 return false 36 } 37 } 38 return true 39 } 40 41 // CompareVersion compares `a` and `b` as standard GNU version. 42 // 43 // It returns 1 if `a` > `b`. 44 // 45 // It returns -1 if `a` < `b`. 46 // 47 // It returns 0 if `a` = `b`. 48 // 49 // GNU standard version is like: 50 // v1.0 51 // 1 52 // 1.0.0 53 // v1.0.1 54 // v2.10.8 55 // 10.2.0 56 // etc. 57 func CompareVersion(a, b string) int { 58 if a != "" && a[0] == 'v' { 59 a = a[1:] 60 } 61 if b != "" && b[0] == 'v' { 62 b = b[1:] 63 } 64 var ( 65 array1 = strings.Split(a, ".") 66 array2 = strings.Split(b, ".") 67 diff int 68 ) 69 diff = len(array2) - len(array1) 70 for i := 0; i < diff; i++ { 71 array1 = append(array1, "0") 72 } 73 diff = len(array1) - len(array2) 74 for i := 0; i < diff; i++ { 75 array2 = append(array2, "0") 76 } 77 v1 := 0 78 v2 := 0 79 for i := 0; i < len(array1); i++ { 80 v1 = gconv.Int(array1[i]) 81 v2 = gconv.Int(array2[i]) 82 if v1 > v2 { 83 return 1 84 } 85 if v1 < v2 { 86 return -1 87 } 88 } 89 return 0 90 } 91 92 // CompareVersionGo compares `a` and `b` as standard Golang version. 93 // 94 // It returns 1 if `a` > `b`. 95 // 96 // It returns -1 if `a` < `b`. 97 // 98 // It returns 0 if `a` = `b`. 99 // 100 // Golang standard version is like: 101 // 1.0.0 102 // v1.0.1 103 // v2.10.8 104 // 10.2.0 105 // v0.0.0-20190626092158-b2ccc519800e 106 // v1.12.2-0.20200413154443-b17e3a6804fa 107 // v4.20.0+incompatible 108 // etc. 109 // 110 // Docs: https://go.dev/doc/modules/version-numbers 111 func CompareVersionGo(a, b string) int { 112 a = Trim(a) 113 b = Trim(b) 114 if a != "" && a[0] == 'v' { 115 a = a[1:] 116 } 117 if b != "" && b[0] == 'v' { 118 b = b[1:] 119 } 120 var ( 121 rawA = a 122 rawB = b 123 ) 124 if Count(a, "-") > 1 { 125 if i := PosR(a, "-"); i > 0 { 126 a = a[:i] 127 } 128 } 129 if Count(b, "-") > 1 { 130 if i := PosR(b, "-"); i > 0 { 131 b = b[:i] 132 } 133 } 134 if i := Pos(a, "+"); i > 0 { 135 a = a[:i] 136 } 137 if i := Pos(b, "+"); i > 0 { 138 b = b[:i] 139 } 140 a = Replace(a, "-", ".") 141 b = Replace(b, "-", ".") 142 var ( 143 array1 = strings.Split(a, ".") 144 array2 = strings.Split(b, ".") 145 diff = len(array1) - len(array2) 146 ) 147 148 for i := diff; i < 0; i++ { 149 array1 = append(array1, "0") 150 } 151 for i := 0; i < diff; i++ { 152 array2 = append(array2, "0") 153 } 154 155 // check Major.Minor.Patch first 156 v1, v2 := 0, 0 157 for i := 0; i < len(array1); i++ { 158 v1, v2 = gconv.Int(array1[i]), gconv.Int(array2[i]) 159 // Specially in Golang: 160 // "v1.12.2-0.20200413154443-b17e3a6804fa" < "v1.12.2" 161 // "v1.12.3-0.20200413154443-b17e3a6804fa" > "v1.12.2" 162 if i == 4 && v1 != v2 && (v1 == 0 || v2 == 0) { 163 if v1 > v2 { 164 return -1 165 } else { 166 return 1 167 } 168 } 169 170 if v1 > v2 { 171 return 1 172 } 173 if v1 < v2 { 174 return -1 175 } 176 } 177 178 // Specially in Golang: 179 // "v4.20.1+incompatible" < "v4.20.1" 180 inA, inB := Contains(rawA, "+incompatible"), Contains(rawB, "+incompatible") 181 if inA && !inB { 182 return -1 183 } 184 if !inA && inB { 185 return 1 186 } 187 188 return 0 189 }