hackage.scm 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410
  1. ;;; GNU Guix --- Functional package management for GNU
  2. ;;; Copyright © 2015 Federico Beffa <beffa@fbengineering.ch>
  3. ;;; Copyright © 2019 Robert Vollmert <rob@vllmrt.net>
  4. ;;; Copyright © 2021 Xinglu Chen <public@yoctocell.xyz>
  5. ;;; Copyright © 2021 Sarah Morgensen <iskarian@mgsn.dev>
  6. ;;;
  7. ;;; This file is part of GNU Guix.
  8. ;;;
  9. ;;; GNU Guix is free software; you can redistribute it and/or modify it
  10. ;;; under the terms of the GNU General Public License as published by
  11. ;;; the Free Software Foundation; either version 3 of the License, or (at
  12. ;;; your option) any later version.
  13. ;;;
  14. ;;; GNU Guix is distributed in the hope that it will be useful, but
  15. ;;; WITHOUT ANY WARRANTY; without even the implied warranty of
  16. ;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  17. ;;; GNU General Public License for more details.
  18. ;;;
  19. ;;; You should have received a copy of the GNU General Public License
  20. ;;; along with GNU Guix. If not, see <http://www.gnu.org/licenses/>.
  21. (define-module (test-hackage)
  22. #:use-module (guix import cabal)
  23. #:use-module (guix import hackage)
  24. #:use-module (guix tests)
  25. #:use-module (srfi srfi-64)
  26. #:use-module (ice-9 match))
  27. (define test-cabal-1
  28. "name: foo
  29. version: 1.0.0
  30. homepage: http://test.org
  31. synopsis: synopsis
  32. description: description
  33. license: BSD3
  34. executable cabal
  35. build-depends:
  36. HTTP >= 4000.2.5 && < 4000.3,
  37. mtl >= 2.0 && < 3
  38. ")
  39. (define test-cabal-2
  40. "name: foo
  41. version: 1.0.0
  42. homepage: http://test.org
  43. synopsis: synopsis
  44. description: description
  45. license: BSD3
  46. executable cabal {
  47. build-depends:
  48. HTTP >= 4000.2.5 && < 4000.3,
  49. mtl >= 2.0 && < 3
  50. }
  51. ")
  52. ;; Check compiler implementation test with and without spaces.
  53. (define test-cabal-3
  54. "name: foo
  55. version: 1.0.0
  56. homepage: http://test.org
  57. synopsis: synopsis
  58. description: description
  59. license: BSD3
  60. library
  61. if impl(ghc >= 7.2 && < 7.6)
  62. Build-depends: ghc-a
  63. if impl(ghc>=7.2&&<7.6)
  64. Build-depends: ghc-b
  65. if impl(ghc == 7.8)
  66. Build-depends:
  67. HTTP >= 4000.2.5 && < 4000.3,
  68. mtl >= 2.0 && < 3
  69. ")
  70. ;; Check "-any", "-none" when name is different.
  71. (define test-cabal-4
  72. "name: foo
  73. version: 1.0.0
  74. homepage: http://test.org
  75. synopsis: synopsis
  76. description: description
  77. license: BSD3
  78. library
  79. if impl(ghcjs -any)
  80. Build-depends: ghc-a
  81. if impl(ghc>=7.2&&<7.6)
  82. Build-depends: ghc-b
  83. if impl(ghc == 7.8)
  84. Build-depends:
  85. HTTP >= 4000.2.5 && < 4000.3,
  86. mtl >= 2.0 && < 3
  87. ")
  88. ;; Check "-any", "-none".
  89. (define test-cabal-5
  90. "name: foo
  91. version: 1.0.0
  92. homepage: http://test.org
  93. synopsis: synopsis
  94. description: description
  95. license: BSD3
  96. library
  97. if impl(ghc == 7.8)
  98. Build-depends:
  99. HTTP >= 4000.2.5 && < 4000.3,
  100. if impl(ghc -any)
  101. Build-depends: mtl >= 2.0 && < 3
  102. if impl(ghc>=7.2&&<7.6)
  103. Build-depends: ghc-b
  104. ")
  105. ;; Check "custom-setup".
  106. (define test-cabal-6
  107. "name: foo
  108. build-type: Custom
  109. version: 1.0.0
  110. homepage: http://test.org
  111. synopsis: synopsis
  112. description: description
  113. license: BSD3
  114. custom-setup
  115. setup-depends: base >= 4.7 && < 5,
  116. Cabal >= 1.24,
  117. haskell-gi == 0.21.*
  118. library
  119. if impl(ghc>=7.2&&<7.6)
  120. Build-depends: ghc-b
  121. if impl(ghc == 7.8)
  122. Build-depends:
  123. HTTP >= 4000.2.5 && < 4000.3,
  124. mtl >= 2.0 && < 3
  125. ")
  126. ;; A fragment of a real Cabal file with minor modification to check precedence
  127. ;; of 'and' over 'or', missing final newline, spaces between keywords and
  128. ;; parentheses and between key and column.
  129. (define test-read-cabal-1
  130. "name: test-me
  131. library
  132. -- Choose which library versions to use.
  133. if flag(base4point8)
  134. Build-depends: base >= 4.8 && < 5
  135. else
  136. if flag(base4)
  137. Build-depends: base >= 4 && < 4.8
  138. else
  139. if flag(base3)
  140. Build-depends: base >= 3 && < 4
  141. else
  142. Build-depends: base < 3
  143. if flag(base4point8) || flag (base4) && flag(base3)
  144. Build-depends: random
  145. Build-depends : containers
  146. -- Modules that are always built.
  147. Exposed-Modules:
  148. Test.QuickCheck.Exception")
  149. (test-begin "hackage")
  150. (define-syntax-rule (define-package-matcher name pattern)
  151. (define* (name obj)
  152. (match obj
  153. (pattern #t)
  154. (x (pk 'fail x #f)))))
  155. (define-package-matcher match-ghc-foo
  156. ('package
  157. ('name "ghc-foo")
  158. ('version "1.0.0")
  159. ('source
  160. ('origin
  161. ('method 'url-fetch)
  162. ('uri ('hackage-uri "foo" 'version))
  163. ('sha256
  164. ('base32
  165. (? string? hash)))))
  166. ('build-system 'haskell-build-system)
  167. ('inputs ('list 'ghc-http))
  168. ('home-page "http://test.org")
  169. ('synopsis (? string?))
  170. ('description (? string?))
  171. ('license 'license:bsd-3)))
  172. (define* (eval-test-with-cabal test-cabal matcher #:key (cabal-environment '()))
  173. (define port (open-input-string test-cabal))
  174. (matcher (hackage->guix-package "foo" #:port port #:cabal-environment cabal-environment)))
  175. (test-assert "hackage->guix-package test 1"
  176. (eval-test-with-cabal test-cabal-1 match-ghc-foo))
  177. (test-assert "hackage->guix-package test 2"
  178. (eval-test-with-cabal test-cabal-2 match-ghc-foo))
  179. (test-assert "hackage->guix-package test 3"
  180. (eval-test-with-cabal test-cabal-3 match-ghc-foo
  181. #:cabal-environment '(("impl" . "ghc-7.8"))))
  182. (test-assert "hackage->guix-package test 4"
  183. (eval-test-with-cabal test-cabal-4 match-ghc-foo
  184. #:cabal-environment '(("impl" . "ghc-7.8"))))
  185. (test-assert "hackage->guix-package test 5"
  186. (eval-test-with-cabal test-cabal-5 match-ghc-foo
  187. #:cabal-environment '(("impl" . "ghc-7.8"))))
  188. (define-package-matcher match-ghc-foo-6
  189. ('package
  190. ('name "ghc-foo")
  191. ('version "1.0.0")
  192. ('source
  193. ('origin
  194. ('method 'url-fetch)
  195. ('uri ('hackage-uri "foo" 'version))
  196. ('sha256
  197. ('base32
  198. (? string? hash)))))
  199. ('build-system 'haskell-build-system)
  200. ('inputs ('list 'ghc-b 'ghc-http))
  201. ('native-inputs ('list 'ghc-haskell-gi))
  202. ('home-page "http://test.org")
  203. ('synopsis (? string?))
  204. ('description (? string?))
  205. ('license 'license:bsd-3)))
  206. (test-assert "hackage->guix-package test 6"
  207. (eval-test-with-cabal test-cabal-6 match-ghc-foo-6))
  208. ;; Check multi-line layouted description.
  209. (define test-cabal-multiline-layout
  210. "name: foo
  211. version: 1.0.0
  212. homepage: http://test.org
  213. synopsis: synopsis
  214. description: first line
  215. second line
  216. license: BSD3
  217. executable cabal
  218. build-depends:
  219. HTTP >= 4000.2.5 && < 4000.3,
  220. mtl >= 2.0 && < 3
  221. ")
  222. (test-assert "hackage->guix-package test multiline desc (layout)"
  223. (eval-test-with-cabal test-cabal-multiline-layout match-ghc-foo))
  224. ;; Check multi-line braced description.
  225. (define test-cabal-multiline-braced
  226. "name: foo
  227. version: 1.0.0
  228. homepage: http://test.org
  229. synopsis: synopsis
  230. description: {
  231. first line
  232. second line
  233. }
  234. license: BSD3
  235. executable cabal
  236. build-depends:
  237. HTTP >= 4000.2.5 && < 4000.3,
  238. mtl >= 2.0 && < 3
  239. ")
  240. (test-assert "hackage->guix-package test multiline desc (braced)"
  241. (eval-test-with-cabal test-cabal-multiline-braced match-ghc-foo))
  242. ;; Check mixed layout. Compare e.g. warp.
  243. (define test-cabal-mixed-layout
  244. "name: foo
  245. version: 1.0.0
  246. homepage: http://test.org
  247. synopsis: synopsis
  248. description: description
  249. license: BSD3
  250. executable cabal
  251. build-depends:
  252. HTTP >= 4000.2.5 && < 4000.3,
  253. mtl >= 2.0 && < 3
  254. ghc-options: -Wall
  255. ")
  256. ;; Fails: https://debbugs.gnu.org/cgi/bugreport.cgi?bug=35743
  257. (test-expect-fail 1)
  258. (test-assert "hackage->guix-package test mixed layout"
  259. (eval-test-with-cabal test-cabal-mixed-layout match-ghc-foo))
  260. ;; Check flag executable. Compare e.g. darcs.
  261. (define test-cabal-flag-executable
  262. "name: foo
  263. version: 1.0.0
  264. homepage: http://test.org
  265. synopsis: synopsis
  266. description: description
  267. license: BSD3
  268. flag executable
  269. description: Build executable
  270. default: True
  271. executable cabal
  272. if !flag(executable)
  273. buildable: False
  274. else
  275. buildable: True
  276. build-depends:
  277. HTTP >= 4000.2.5 && < 4000.3,
  278. mtl >= 2.0 && < 3
  279. ")
  280. (test-assert "hackage->guix-package test flag executable"
  281. (eval-test-with-cabal test-cabal-flag-executable match-ghc-foo))
  282. ;; Check Hackage Cabal revisions.
  283. (define test-cabal-revision
  284. "name: foo
  285. version: 1.0.0
  286. x-revision: 2
  287. homepage: http://test.org
  288. synopsis: synopsis
  289. description: description
  290. license: BSD3
  291. executable cabal
  292. build-depends:
  293. HTTP >= 4000.2.5 && < 4000.3,
  294. mtl >= 2.0 && < 3
  295. ")
  296. (define-package-matcher match-ghc-foo-revision
  297. ('package
  298. ('name "ghc-foo")
  299. ('version "1.0.0")
  300. ('source
  301. ('origin
  302. ('method 'url-fetch)
  303. ('uri ('hackage-uri "foo" 'version))
  304. ('sha256
  305. ('base32
  306. (? string? hash)))))
  307. ('build-system 'haskell-build-system)
  308. ('inputs ('list 'ghc-http))
  309. ('arguments
  310. ('quasiquote
  311. ('#:cabal-revision
  312. ("2" "0xxd88fb659f0krljidbvvmkh9ppjnx83j0nqzx8whcg4n5qbyng"))))
  313. ('home-page "http://test.org")
  314. ('synopsis (? string?))
  315. ('description (? string?))
  316. ('license 'license:bsd-3)))
  317. (test-assert "hackage->guix-package test cabal revision"
  318. (eval-test-with-cabal test-cabal-revision match-ghc-foo-revision))
  319. (test-assert "read-cabal test 1"
  320. (match (call-with-input-string test-read-cabal-1 read-cabal)
  321. ((("name" ("test-me"))
  322. ('section 'library
  323. (('if ('flag "base4point8")
  324. (("build-depends" ("base >= 4.8 && < 5")))
  325. (('if ('flag "base4")
  326. (("build-depends" ("base >= 4 && < 4.8")))
  327. (('if ('flag "base3")
  328. (("build-depends" ("base >= 3 && < 4")))
  329. (("build-depends" ("base < 3"))))))))
  330. ('if ('or ('flag "base4point8")
  331. ('and ('flag "base4") ('flag "base3")))
  332. (("build-depends" ("random")))
  333. ())
  334. ("build-depends" ("containers"))
  335. ("exposed-modules" ("Test.QuickCheck.Exception")))))
  336. #t)
  337. (x (pk 'fail x #f))))
  338. (define test-cabal-import
  339. "name: foo
  340. version: 1.0.0
  341. homepage: http://test.org
  342. synopsis: synopsis
  343. description: description
  344. license: BSD3
  345. common commons
  346. build-depends:
  347. HTTP >= 4000.2.5 && < 4000.3,
  348. mtl >= 2.0 && < 3
  349. executable cabal
  350. import: commons
  351. ")
  352. (define-package-matcher match-ghc-foo-import
  353. ('package
  354. ('name "ghc-foo")
  355. ('version "1.0.0")
  356. ('source
  357. ('origin
  358. ('method 'url-fetch)
  359. ('uri ('hackage-uri "foo" 'version))
  360. ('sha256
  361. ('base32
  362. (? string? hash)))))
  363. ('build-system 'haskell-build-system)
  364. ('inputs ('list 'ghc-http))
  365. ('home-page "http://test.org")
  366. ('synopsis (? string?))
  367. ('description (? string?))
  368. ('license 'license:bsd-3)))
  369. (test-assert "hackage->guix-package test cabal import"
  370. (eval-test-with-cabal test-cabal-import match-ghc-foo-import))
  371. (test-end "hackage")