Version.vala 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139
  1. namespace Usm {
  2. public class Version {
  3. public int[] version_nums { get; set; }
  4. public int? release { get; set; }
  5. public Version.from_string(string ver) throws ManifestError {
  6. var ver_rel = ver.chomp().chug().split("+", 2);
  7. if(ver_rel.length == 2) {
  8. var release = 0;
  9. if(!int.try_parse(ver_rel[1], out release)) {
  10. throw new ManifestError.INVALID_VERSION("Could not parse release number");
  11. }
  12. this.release = release;
  13. }
  14. if(ver_rel[0].length == 0) {
  15. if(this.release == null) {
  16. throw new ManifestError.INVALID_VERSION("Version string must have a version number or release number at minimum");
  17. }
  18. return;
  19. }
  20. var version_strs = ver_rel[0].split(".");
  21. version_nums = new int[version_strs.length];
  22. for(int i = 0; i < version_nums.length; i++) {
  23. var num = 0;
  24. if(!int.try_parse(version_strs[i], out num)) {
  25. throw new ManifestError.INVALID_VERSION(@"Could not parse version number part $i");
  26. }
  27. version_nums[i] = num;
  28. }
  29. }
  30. public string to_string() {
  31. var str = "";
  32. bool first = true;
  33. foreach (var num in version_nums) {
  34. if(first) {
  35. first = false;
  36. }
  37. else {
  38. str += ".";
  39. }
  40. str += num.to_string();
  41. }
  42. if(release != null) {
  43. str += @"+$release";
  44. }
  45. return str;
  46. }
  47. public bool equals(Version other) {
  48. var parts = int.min(other.version_nums.length, version_nums.length);
  49. for(int i = 0; i < parts; i++) {
  50. if(version_nums[i] != other.version_nums[i]) {
  51. return false;
  52. }
  53. }
  54. return release == other.release;
  55. }
  56. /**
  57. * Prefix-tolerant numeric equality ignoring `+release` suffixes:
  58. * 0.31 matches 0.31.0, and 0.31+2 matches 0.31. Resource-level
  59. * versions (soname tails, .pc `Version:` fields) never carry
  60. * packaging releases and upstreams disagree about component
  61. * counts, so this is the equality resource constraints use.
  62. */
  63. public bool matches_numeric(Version other) {
  64. var mine = version_nums ?? new int[0];
  65. var theirs = other.version_nums ?? new int[0];
  66. var parts = int.min(theirs.length, mine.length);
  67. for(int i = 0; i < parts; i++) {
  68. if(mine[i] != theirs[i]) {
  69. return false;
  70. }
  71. }
  72. return true;
  73. }
  74. public bool greater_than(Version other) {
  75. var parts = int.min(other.version_nums.length, version_nums.length);
  76. for(int i = 0; i < parts; i++) {
  77. if(version_nums[i] > other.version_nums[i]) {
  78. return true;
  79. }
  80. if(version_nums[i] < other.version_nums[i]) {
  81. return false;
  82. }
  83. }
  84. // So far, equal
  85. if(release == null && other.release == null) {
  86. return false;
  87. }
  88. if(release == null && other.release != null) {
  89. return false;
  90. }
  91. if(release != null && other.release == null) {
  92. return true;
  93. }
  94. return release > other.release;
  95. }
  96. public bool less_than(Version other) {
  97. var parts = int.min(other.version_nums.length, version_nums.length);
  98. for(int i = 0; i < parts; i++) {
  99. if(version_nums[i] < other.version_nums[i]) {
  100. return true;
  101. }
  102. if(version_nums[i] > other.version_nums[i]) {
  103. return false;
  104. }
  105. }
  106. // So far, equal
  107. if(release == null && other.release == null) {
  108. return false;
  109. }
  110. if(release == null && other.release != null) {
  111. return true;
  112. }
  113. if(release != null && other.release == null) {
  114. return false;
  115. }
  116. return release < other.release;
  117. }
  118. public int compare(Version other) {
  119. if(less_than(other)) {
  120. return -1;
  121. }
  122. if(greater_than(other)) {
  123. return 1;
  124. }
  125. return 0;
  126. }
  127. }
  128. }