gstr_version.go 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174
  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. package gstr
  7. import (
  8. "strings"
  9. "github.com/gogf/gf/v2/util/gconv"
  10. )
  11. // IsGNUVersion checks and returns whether given `version` is valid GNU version string.
  12. func IsGNUVersion(version string) bool {
  13. if version != "" && (version[0] == 'v' || version[0] == 'V') {
  14. version = version[1:]
  15. }
  16. if version == "" {
  17. return false
  18. }
  19. var array = strings.Split(version, ".")
  20. if len(array) > 3 {
  21. return false
  22. }
  23. for _, v := range array {
  24. if v == "" {
  25. return false
  26. }
  27. if !IsNumeric(v) {
  28. return false
  29. }
  30. if v[0] == '-' || v[0] == '+' {
  31. return false
  32. }
  33. }
  34. return true
  35. }
  36. // CompareVersion compares `a` and `b` as standard GNU version.
  37. // It returns 1 if `a` > `b`.
  38. // It returns -1 if `a` < `b`.
  39. // It returns 0 if `a` = `b`.
  40. // GNU standard version is like:
  41. // v1.0
  42. // 1
  43. // 1.0.0
  44. // v1.0.1
  45. // v2.10.8
  46. // 10.2.0
  47. // etc.
  48. func CompareVersion(a, b string) int {
  49. if a != "" && a[0] == 'v' {
  50. a = a[1:]
  51. }
  52. if b != "" && b[0] == 'v' {
  53. b = b[1:]
  54. }
  55. var (
  56. array1 = strings.Split(a, ".")
  57. array2 = strings.Split(b, ".")
  58. diff int
  59. )
  60. diff = len(array2) - len(array1)
  61. for i := 0; i < diff; i++ {
  62. array1 = append(array1, "0")
  63. }
  64. diff = len(array1) - len(array2)
  65. for i := 0; i < diff; i++ {
  66. array2 = append(array2, "0")
  67. }
  68. v1 := 0
  69. v2 := 0
  70. for i := 0; i < len(array1); i++ {
  71. v1 = gconv.Int(array1[i])
  72. v2 = gconv.Int(array2[i])
  73. if v1 > v2 {
  74. return 1
  75. }
  76. if v1 < v2 {
  77. return -1
  78. }
  79. }
  80. return 0
  81. }
  82. // CompareVersionGo compares `a` and `b` as standard Golang version.
  83. // It returns 1 if `a` > `b`.
  84. // It returns -1 if `a` < `b`.
  85. // It returns 0 if `a` = `b`.
  86. // Golang standard version is like:
  87. // 1.0.0
  88. // v1.0.1
  89. // v2.10.8
  90. // 10.2.0
  91. // v0.0.0-20190626092158-b2ccc519800e
  92. // v4.20.0+incompatible
  93. // etc.
  94. func CompareVersionGo(a, b string) int {
  95. a = Trim(a)
  96. b = Trim(b)
  97. if a != "" && a[0] == 'v' {
  98. a = a[1:]
  99. }
  100. if b != "" && b[0] == 'v' {
  101. b = b[1:]
  102. }
  103. var (
  104. rawA = a
  105. rawB = b
  106. )
  107. if Count(a, "-") > 1 {
  108. if i := PosR(a, "-"); i > 0 {
  109. a = a[:i]
  110. }
  111. }
  112. if Count(b, "-") > 1 {
  113. if i := PosR(b, "-"); i > 0 {
  114. b = b[:i]
  115. }
  116. }
  117. if i := Pos(a, "+"); i > 0 {
  118. a = a[:i]
  119. }
  120. if i := Pos(b, "+"); i > 0 {
  121. b = b[:i]
  122. }
  123. a = Replace(a, "-", ".")
  124. b = Replace(b, "-", ".")
  125. var (
  126. array1 = strings.Split(a, ".")
  127. array2 = strings.Split(b, ".")
  128. diff int
  129. )
  130. // Specially in Golang:
  131. // "v1.12.2-0.20200413154443-b17e3a6804fa" < "v1.12.2"
  132. if len(array1) > 3 && len(array2) <= 3 {
  133. return -1
  134. }
  135. if len(array1) <= 3 && len(array2) > 3 {
  136. return 1
  137. }
  138. diff = len(array2) - len(array1)
  139. for i := 0; i < diff; i++ {
  140. array1 = append(array1, "0")
  141. }
  142. diff = len(array1) - len(array2)
  143. for i := 0; i < diff; i++ {
  144. array2 = append(array2, "0")
  145. }
  146. v1 := 0
  147. v2 := 0
  148. for i := 0; i < len(array1); i++ {
  149. v1 = gconv.Int(array1[i])
  150. v2 = gconv.Int(array2[i])
  151. if v1 > v2 {
  152. return 1
  153. }
  154. if v1 < v2 {
  155. return -1
  156. }
  157. }
  158. // Specially in Golang:
  159. // "v4.20.1+incompatible" < "v4.20.1"
  160. if Contains(rawA, "incompatible") {
  161. return -1
  162. }
  163. if Contains(rawB, "incompatible") {
  164. return 1
  165. }
  166. return 0
  167. }