contentdb.scm 8.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228
  1. ;;; GNU Guix --- Functional package management for GNU
  2. ;;; Copyright © 2021 Maxime Devos <maximedevos@telenet.be>
  3. ;;;
  4. ;;; This file is part of GNU Guix.
  5. ;;;
  6. ;;; GNU Guix 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 (at
  9. ;;; your option) any later version.
  10. ;;;
  11. ;;; GNU Guix 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
  14. ;;; GNU General Public License for more details.
  15. ;;;
  16. ;;; You should have received a copy of the GNU General Public License
  17. ;;; along with GNU Guix. If not, see <http://www.gnu.org/licenses/>.
  18. (define-module (test-contentdb)
  19. #:use-module (guix memoization)
  20. #:use-module (guix import contentdb)
  21. #:use-module (guix import utils)
  22. #:use-module (guix tests)
  23. #:use-module (json)
  24. #:use-module (ice-9 match)
  25. #:use-module (srfi srfi-1)
  26. #:use-module (srfi srfi-64))
  27. ;; Some procedures for populating a ‘fake’ ContentDB server.
  28. (define* (make-package-sexp #:key
  29. (guix-name "minetest-foo")
  30. (home-page "https://example.org/foo")
  31. (repo "https://example.org/foo.git")
  32. (synopsis "synopsis")
  33. (guix-description "description")
  34. (guix-license '(list license:cc-by-sa4.0 license:lgpl3))
  35. (inputs '())
  36. #:allow-other-keys)
  37. `(package
  38. (name ,guix-name)
  39. ;; This is not a proper version number but ContentDB does not include
  40. ;; version numbers.
  41. (version "2021-07-25")
  42. (source
  43. (origin
  44. (method git-fetch)
  45. (uri (git-reference
  46. (url ,(and (not (eq? repo 'null)) repo))
  47. (commit #f)))
  48. (sha256
  49. (base32 #f))
  50. (file-name (git-file-name name version))))
  51. (build-system minetest-mod-build-system)
  52. ,@(maybe-propagated-inputs inputs)
  53. (home-page ,home-page)
  54. (synopsis ,synopsis)
  55. (description ,guix-description)
  56. (license ,guix-license)))
  57. (define* (make-package-json #:key
  58. (author "Author")
  59. (name "foo")
  60. (media-license "CC BY-SA 4.0")
  61. (license "LGPLv3")
  62. (short-description "synopsis")
  63. (long-description "description")
  64. (repo "https://example.org/foo.git")
  65. (website "https://example.org/foo")
  66. (forums 321)
  67. #:allow-other-keys)
  68. `(("author" . ,author)
  69. ("content_warnings" . #())
  70. ("created_at" . "2018-05-23T19:58:07.422108")
  71. ("downloads" . 123)
  72. ("forums" . ,forums)
  73. ("issue_tracker" . "https://example.org/foo/issues")
  74. ("license" . ,license)
  75. ("long_description" . ,long-description)
  76. ("maintainers" . #("maintainer"))
  77. ("media_license" . ,media-license)
  78. ("name" . ,name)
  79. ("provides" . #("stuff"))
  80. ("release" . 456)
  81. ("repo" . ,repo)
  82. ("score" . ,987.654)
  83. ("screenshots" . #())
  84. ("short_description" . ,short-description)
  85. ("state" . "APPROVED")
  86. ("tags" . #("some" "tags"))
  87. ("thumbnail" . null)
  88. ("title" . "The name")
  89. ("type" . "mod")
  90. ("url" . ,(string-append "https://content.minetest.net/packages/"
  91. author "/" name "/download/"))
  92. ("website" . ,website)))
  93. (define* (make-releases-json #:key (commit #f) (title "") #:allow-other-keys)
  94. `#((("commit" . ,commit)
  95. ("downloads" . 469)
  96. ("id" . 8614)
  97. ("max_minetest_version" . null)
  98. ("min_minetest_version" . null)
  99. ("release_date" . "2021-07-25T01:10:23.207584")
  100. ("title" . "2021-07-25"))))
  101. (define* (make-dependencies-json #:key (author "Author")
  102. (name "foo")
  103. (requirements '(("default" #f ())))
  104. #:allow-other-keys)
  105. `((,(string-append author "/" name)
  106. . ,(list->vector
  107. (map (match-lambda
  108. ((symbolic-name optional? implementations)
  109. `(("is_optional" . ,optional?)
  110. ("name" . ,symbolic-name)
  111. ("packages" . ,(list->vector implementations)))))
  112. requirements)))
  113. ("something/else" . #())))
  114. (define (call-with-packages thunk . argument-lists)
  115. (mock ((guix http-client) http-fetch
  116. (lambda* (url #:key headers)
  117. (unless (string-prefix? "mock://api/packages/" url)
  118. (error "the URL ~a should not be used" url))
  119. (define resource
  120. (substring url (string-length "mock://api/packages/")))
  121. (define components (string-split resource #\/))
  122. (unless (>= (length components) 2)
  123. (error "the URL ~a should have an author and name component" url))
  124. (define requested-author (list-ref components 0))
  125. (define requested-name (list-ref components 1))
  126. (define rest (cddr components))
  127. (define relevant-argument-list
  128. (any (lambda (argument-list)
  129. (apply (lambda* (#:key (author "Author") (name "foo")
  130. #:allow-other-keys)
  131. (and (equal? requested-author author)
  132. (equal? requested-name name)
  133. argument-list))
  134. argument-list))
  135. argument-lists))
  136. (when (not relevant-argument-list)
  137. (error "the package ~a/~a should be irrelevant, but ~a is fetched"
  138. requested-author requested-name url))
  139. (define (scm->json-port scm)
  140. (open-input-string (scm->json-string scm)))
  141. (scm->json-port
  142. (apply (match rest
  143. (("") make-package-json)
  144. (("dependencies" "") make-dependencies-json)
  145. (("releases" "") make-releases-json)
  146. (_ (error "TODO ~a" rest)))
  147. relevant-argument-list))))
  148. (parameterize ((%contentdb-api "mock://api/"))
  149. (thunk))))
  150. (define* (contentdb->guix-package* #:key (author "Author") (name "foo")
  151. #:allow-other-keys)
  152. (contentdb->guix-package author name))
  153. (define (imported-package-sexp . extra-arguments)
  154. (call-with-packages
  155. (lambda ()
  156. ;; Don't reuse results from previous tests.
  157. (invalidate-memoization! contentdb->guix-package)
  158. (apply contentdb->guix-package* extra-arguments))
  159. extra-arguments))
  160. (define-syntax-rule (test-package test-case . extra-arguments)
  161. (test-equal test-case
  162. (make-package-sexp . extra-arguments)
  163. (imported-package-sexp . extra-arguments)))
  164. (test-begin "contentdb")
  165. ;; Package names
  166. (test-package "contentdb->guix-package")
  167. (test-package "contentdb->guix-package, _ → - in package name"
  168. #:name "foo_bar"
  169. #:guix-name "minetest-foo-bar")
  170. ;; Determining the home page
  171. (test-package "contentdb->guix-package, website is used as home page"
  172. #:home-page "web://site"
  173. #:website "web://site")
  174. (test-package "contentdb->guix-package, if absent, the forum is used"
  175. #:home-page '(minetest-topic 628)
  176. #:forums 628
  177. #:website 'null)
  178. (test-package "contentdb->guix-package, if absent, the git repo is used"
  179. #:home-page "https://github.com/minetest-mods/mesecons"
  180. #:forums 'null
  181. #:website 'null
  182. #:repo "https://github.com/minetest-mods/mesecons")
  183. (test-package "contentdb->guix-package, all home page information absent"
  184. #:home-page #f
  185. #:forums 'null
  186. #:website 'null
  187. #:repo 'null)
  188. ;; Dependencies
  189. (test-package "contentdb->guix-package, dependency"
  190. #:requirements '(("mesecons" #f
  191. ("Jeija/mesecons"
  192. "some-modpack/containing-mese")))
  193. #:inputs '("minetest-mesecons"))
  194. (test-package "contentdb->guix-package, optional dependency"
  195. #:requirements '(("mesecons" #t
  196. ("Jeija/mesecons"
  197. "some-modpack/containing-mese")))
  198. #:inputs '())
  199. ;; License
  200. (test-package "contentdb->guix-package, identical licenses"
  201. #:guix-license 'license:lgpl3
  202. #:license "LGPLv3"
  203. #:media-license "LGPLv3")
  204. (test-end "contentdb")