matcher.scm 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181
  1. ;;; guile-semver --- Semantic Version tooling for guile
  2. ;;; Copyright © 2017 Jelle Dirk Licht <jlicht@fsfe.org>
  3. ;;;
  4. ;;; This file is part of guile-semver.
  5. ;;;
  6. ;;; guile-semver is free software; you can redistribute it and/or modify it
  7. ;;; under the terms of the GNU General Public License as published by
  8. ;;; the Free Software Foundation; either version 3 of the License, or
  9. ;;; (at your option) any later version.
  10. ;;;
  11. ;;; guile-semver is distributed in the hope that it will be useful, but
  12. ;;; WITHOUT ANY WARRANTY; without even the implied warranty of
  13. ;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  14. ;;; General Public License for more details.
  15. ;;;
  16. ;;; You should have received a copy of the GNU General Public License
  17. ;;; along with guile-semver. If not, see <http://www.gnu.org/licenses/>.
  18. (define-module (semver matcher)
  19. #:use-module (srfi srfi-9)
  20. #:use-module (srfi srfi-1)
  21. #:use-module (srfi srfi-9 gnu)
  22. #:use-module (srfi srfi-67)
  23. #:use-module (ice-9 format)
  24. #:use-module (ice-9 match)
  25. #:use-module (ice-9 peg)
  26. #:use-module (oop goops)
  27. #:use-module (rnrs enums)
  28. #:use-module (semver structs)
  29. #:use-module (semver comparator)
  30. #:export (semver-range-eq
  31. semver-range-gt
  32. semver-range-gte
  33. semver-range-lt
  34. semver-range-lte
  35. semver-range-hyphen
  36. semver-range-caret
  37. semver-range-tilde
  38. semver-range-partial
  39. semver-range-or
  40. semver-range-and
  41. semver-range-matcher))
  42. (define-immutable-record-type <semver-range>
  43. (make-semver-range matcher min max)
  44. semver-range?
  45. (matcher semver-range-matcher set-semver-range-matcher) ; (<semantic-version> -> bool)
  46. (min semver-range-min set-semver-range-min) ; (<semantic-version>)
  47. (max semver-range-max set-semver-range-max)) ; (<semantic-version>)
  48. ;; Helpers
  49. (define (semver-range-eq version)
  50. (make-semver-range (lambda (v)
  51. (= 0 (semantic-version-compare version v)))
  52. version
  53. (inc-semantic-version version)))
  54. (define (tiniest-min semver-range1 semver-range2)
  55. (let ((m1 (semver-range-min semver-range1))
  56. (m2 (semver-range-min semver-range2)))
  57. (match (semantic-version-compare m1 m2)
  58. ((-1) m1)
  59. ((1) m2)
  60. (else m1))))
  61. (define (biggest-max semver-range1 semver-range2)
  62. (let ((m1 (semver-range-max semver-range1))
  63. (m2 (semver-range-max semver-range2)))
  64. (match (semantic-version-compare m1 m2)
  65. ((-1) m2)
  66. ((1) m1)
  67. (else m1))))
  68. (define (semver-range-and semver-range1 semver-range2)
  69. (make-semver-range (lambda (v)
  70. (and ((semver-range-matcher semver-range1) v)
  71. ((semver-range-matcher semver-range2) v)))
  72. (tiniest-min semver-range1 semver-range2)
  73. (biggest-max semver-range1 semver-range2)))
  74. (define (semver-range-or semver-range1 semver-range2)
  75. (make-semver-range (lambda (v)
  76. (or ((semver-range-matcher semver-range1) v)
  77. ((semver-range-matcher semver-range2) v)))
  78. (tiniest-min semver-range1 semver-range2)
  79. (biggest-max semver-range1 semver-range2)))
  80. (define (semver-range-gt-base version)
  81. (make-semver-range (lambda (v)
  82. (= -1 (semantic-version-compare version v)))
  83. version
  84. *semantic-version-max*))
  85. (define (semver-range-gte-base version)
  86. (semver-range-or (semver-range-gt-base version)
  87. (semver-range-eq version)))
  88. (define (semver-range-lt-base version)
  89. (make-semver-range (lambda (v)
  90. (= 1 (semantic-version-compare version v)))
  91. *semantic-version-min*
  92. version))
  93. ;; (define (semver-range-lte-base version)
  94. ;; (semver-range-or (semver-range-lt-base version)
  95. ;; (semver-range-eq version)))
  96. (define (semver-range-min-max min max)
  97. (make-semver-range (lambda (v)
  98. (and
  99. (= -1 (semantic-version-compare v max))
  100. (not (= -1 (semantic-version-compare v min)))))
  101. min
  102. max))
  103. (define (semver-range-partial . rest)
  104. (semver-range-min-max (apply semantic-version-wildcard-min rest)
  105. (apply semantic-version-wildcard-max rest)))
  106. (define (semver-range-lt semver-range)
  107. ;; maximum of new range is minimum of old range
  108. (let ((max (semver-range-min semver-range)))
  109. (make-semver-range (lambda (v)
  110. (= 1
  111. (semantic-version-compare max v)))
  112. *semantic-version-min*
  113. max)))
  114. (define (semver-range-gt semver-range)
  115. ;; minimum of new range is maximum of old range
  116. (let ((min (semver-range-max semver-range)))
  117. (make-semver-range (lambda (v)
  118. (not (= -1
  119. (semantic-version-compare v min))))
  120. min
  121. *semantic-version-max*)))
  122. (define (semver-range-lte semver-range)
  123. (semver-range-lt-base (inc-semantic-version (semver-range-max semver-range))))
  124. (define (semver-range-gte semver-range)
  125. (semver-range-gte-base (semver-range-min semver-range)))
  126. (define (semver-range-hyphen semver-range1 semver-range2)
  127. (let ((min (semver-range-min semver-range1))
  128. (max (semver-range-max semver-range2)))
  129. (semver-range-min-max min max)))
  130. (define (was-wildcard? min max)
  131. (not (= 0 (semantic-version-compare (inc-semantic-version min) max))))
  132. (define (semver-range-tilde semver-range)
  133. (let ((min (semver-range-min semver-range))
  134. (max (semver-range-max semver-range)))
  135. (if (was-wildcard? min max)
  136. semver-range
  137. (semver-range-min-max min (inc-semantic-version max 'minor)))))
  138. (define (left-most-nz version)
  139. (cond
  140. ((not (zero? (semantic-version-major version)))
  141. 'major)
  142. ((not (zero? (semantic-version-minor version)))
  143. 'minor)
  144. ((not (zero? (semantic-version-patch version))) 'patch)
  145. (else 'patch)))
  146. (define (major-minor-zero? version)
  147. (and (zero? (semantic-version-major version))
  148. (zero? (semantic-version-minor version))))
  149. (define (semver-range-caret semver-range)
  150. (let ((min (semver-range-min semver-range))
  151. (max (semver-range-max semver-range)))
  152. (if (and (was-wildcard? min max) (major-minor-zero? min))
  153. (semver-range-min-max min (inc-semantic-version min 'minor))
  154. (semver-range-min-max min (inc-semantic-version min (left-most-nz min))))))