Version.php 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133
  1. <?php
  2. namespace ba;
  3. /**
  4. * 版本类
  5. */
  6. class Version
  7. {
  8. /**
  9. * 比较两个版本号
  10. * @param $v1 string 要求的版本号
  11. * @param $v2 string | bool 被比较版本号
  12. * @return bool 是否达到要求的版本号
  13. */
  14. public static function compare(string $v1, $v2): bool
  15. {
  16. if (!$v2) {
  17. return false;
  18. }
  19. // 删除开头的 V
  20. if (strtolower($v1[0]) == 'v') {
  21. $v1 = substr($v1, 1);
  22. }
  23. if (strtolower($v2[0]) == 'v') {
  24. $v2 = substr($v2, 1);
  25. }
  26. if ($v1 == "*" || $v1 == $v2) {
  27. return true;
  28. }
  29. // 丢弃'-'后面的内容
  30. if (strpos($v1, '-') !== false) $v1 = explode('-', $v1)[0];
  31. if (strpos($v2, '-') !== false) $v2 = explode('-', $v2)[0];
  32. $v1 = explode('.', $v1);
  33. $v2 = explode('.', $v2);
  34. // 将号码逐个进行比较
  35. for ($i = 0; $i < count($v1); $i++) {
  36. if (!isset($v2[$i])) {
  37. break;
  38. }
  39. if ($v1[$i] == $v2[$i]) {
  40. continue;
  41. }
  42. if ($v1[$i] > $v2[$i]) {
  43. return false;
  44. }
  45. if ($v1[$i] < $v2[$i]) {
  46. return true;
  47. }
  48. }
  49. if (count($v1) != count($v2)) {
  50. return !(count($v1) > count($v2));
  51. }
  52. return false;
  53. }
  54. /**
  55. * 是否是一个数字版本号
  56. * @param $version
  57. * @return bool
  58. */
  59. public static function checkDigitalVersion($version): bool
  60. {
  61. if (!$version) {
  62. return false;
  63. }
  64. if (strtolower($version[0]) == 'v') {
  65. $version = substr($version, 1);
  66. }
  67. $rule1 = '/\.{2,10}/'; // 是否有两个的`.`
  68. $rule2 = '/^\d+(\.\d+){0,10}$/';
  69. if (!preg_match($rule1, (string)$version)) {
  70. return !!preg_match($rule2, (string)$version);
  71. }
  72. return false;
  73. }
  74. /**
  75. * @return string
  76. */
  77. public static function getCnpmVersion(): string
  78. {
  79. $execOut = Terminal::getOutputFromProc('version.cnpm');
  80. if ($execOut) {
  81. $preg = '/cnpm@(.+?) \(/is';
  82. preg_match($preg, $execOut, $result);
  83. return $result[1] ?? '';
  84. } else {
  85. return '';
  86. }
  87. }
  88. /**
  89. * 获取依赖版本号
  90. * @param string $name 支持:npm、cnpm、yarn、pnpm、node
  91. * @return string
  92. */
  93. public static function getVersion(string $name): string
  94. {
  95. if ($name == 'cnpm') {
  96. return self::getCnpmVersion();
  97. } elseif (in_array($name, ['npm', 'yarn', 'pnpm', 'node'])) {
  98. $execOut = Terminal::getOutputFromProc('version.' . $name);
  99. if ($execOut) {
  100. if (strripos($execOut, 'npm WARN') !== false) {
  101. $preg = '/\d+(\.\d+){0,2}/';
  102. preg_match($preg, $execOut, $matches);
  103. if (isset($matches[0]) && self::checkDigitalVersion($matches[0])) {
  104. return $matches[0];
  105. }
  106. }
  107. $execOut = preg_split('/\r\n|\r|\n/', $execOut);
  108. // 检测两行,第一行可能会是个警告消息
  109. for ($i = 0; $i < 2; $i++) {
  110. if (isset($execOut[$i]) && self::checkDigitalVersion($execOut[$i])) {
  111. return $execOut[$i];
  112. }
  113. }
  114. } else {
  115. return '';
  116. }
  117. }
  118. return '';
  119. }
  120. }