structs.scm 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151
  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 structs)
  19. #:use-module (srfi srfi-9)
  20. #:use-module (srfi srfi-9 gnu)
  21. #:use-module (ice-9 format)
  22. #:use-module (ice-9 match)
  23. #:export (make-semantic-version
  24. semantic-version-major
  25. semantic-version-minor
  26. semantic-version-patch
  27. semantic-version-pre-release
  28. semantic-version-build-metadata
  29. make-semantic-version*
  30. inc-semantic-version))
  31. (define-immutable-record-type <semantic-version>
  32. (make-semantic-version major minor patch pre-release build-metadata)
  33. semantic-version?
  34. (major semantic-version-major set-semantic-version-major) ;; integer
  35. (minor semantic-version-minor set-semantic-version-minor) ;; integer
  36. (patch semantic-version-patch set-semantic-version-patch) ;; integer
  37. (pre-release semantic-version-pre-release
  38. set-semantic-version-pre-release) ;; list<int|string>
  39. (build-metadata semantic-version-build-metadata
  40. set-semantic-version-build-metadata)) ;; list<int|string>
  41. (define* (make-semantic-version* major
  42. #:optional
  43. (minor "0")
  44. (patch "0")
  45. (pre-release '()) (build '()))
  46. (make-semantic-version (string->number major)
  47. (string->number minor)
  48. (string->number patch)
  49. pre-release
  50. build))
  51. (define (print-semantic-version record port)
  52. (define (object->string* object)
  53. (if (string? object)
  54. object
  55. (object->string object)))
  56. (write-char #\[ port)
  57. (display (semantic-version-major record) port)
  58. (display #\. port)
  59. (display (semantic-version-minor record) port)
  60. (display #\. port)
  61. (display (semantic-version-patch record) port)
  62. (let ((pre-release (semantic-version-pre-release record)))
  63. (when (not (null? pre-release))
  64. (display #\- port)
  65. (display (string-join (map object->string* pre-release) ".") port)))
  66. (let ((build-metadata (semantic-version-build-metadata record)))
  67. (when (not (null? build-metadata))
  68. (display #\+ port)
  69. (display (string-join (map object->string* build-metadata) ".") port)))
  70. (write-char #\] port))
  71. (set-record-type-printer! <semantic-version> print-semantic-version)
  72. (define (inc-prerelease-list lst)
  73. "Ontological increment of LST. Increment right-most number by one,
  74. or append the number 0 to lst."
  75. (let loop ((acc '()) (done #f) (rest (reverse lst)))
  76. (cond
  77. ((and (null? rest) (not done))
  78. (append lst '(0)))
  79. ((null? rest)
  80. acc)
  81. (else
  82. (apply loop
  83. (let ((head (car rest)))
  84. (if (number? head)
  85. (list (cons (+ 1 head) acc)
  86. #t
  87. (cdr rest))
  88. (list (cons head acc)
  89. done
  90. (cdr rest)))))))))
  91. (define* (inc-semantic-version semver #:optional (level 'patch))
  92. "Increment the LEVEL part of SEMVER to the subsequent ontological
  93. value. Valid values of LEVEL are 'major, 'minor, 'patch, 'premajor, 'preminor,
  94. 'prepatch or 'prerelease. The default is 'patch."
  95. (if (not (semantic-version? semver))
  96. (error (format #f "~a is not a semantic-version record" semver))
  97. (match level
  98. ('major
  99. (make-semantic-version (+ 1 (semantic-version-major semver))
  100. 0
  101. 0
  102. '()
  103. '()))
  104. ('minor
  105. (make-semantic-version (semantic-version-major semver)
  106. (+ 1 (semantic-version-minor semver))
  107. 0
  108. '()
  109. '()))
  110. ('patch
  111. (make-semantic-version (semantic-version-major semver)
  112. (semantic-version-minor semver)
  113. (+ 1 (semantic-version-patch semver))
  114. '()
  115. '()))
  116. ('premajor
  117. (make-semantic-version (+ 1 (semantic-version-major semver))
  118. 0
  119. 0
  120. '(0)
  121. '()))
  122. ('preminor
  123. (make-semantic-version (semantic-version-major semver)
  124. (+ 1 (semantic-version-minor semver))
  125. 0
  126. '(0)
  127. '()))
  128. ('prepatch
  129. (make-semantic-version (semantic-version-major semver)
  130. (semantic-version-minor semver)
  131. (+ 1 (semantic-version-patch semver))
  132. '(0)
  133. '()))
  134. ('prerelease
  135. (make-semantic-version (semantic-version-major semver)
  136. (semantic-version-minor semver)
  137. (semantic-version-patch semver)
  138. (inc-prerelease-list
  139. (semantic-version-pre-release semver))
  140. '()))
  141. (_
  142. (error (format #f "Undefined inc-level: ~a" level))))))