hackage.scm 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422
  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 ('string-append
  163. "https://hackage.haskell.org/package/foo/foo-"
  164. 'version
  165. ".tar.gz"))
  166. ('sha256
  167. ('base32
  168. (? string? hash)))))
  169. ('build-system 'haskell-build-system)
  170. ('inputs ('list 'ghc-http))
  171. ('home-page "http://test.org")
  172. ('synopsis (? string?))
  173. ('description (? string?))
  174. ('license 'license:bsd-3)))
  175. (define* (eval-test-with-cabal test-cabal matcher #:key (cabal-environment '()))
  176. (define port (open-input-string test-cabal))
  177. (matcher (hackage->guix-package "foo" #:port port #:cabal-environment cabal-environment)))
  178. (test-assert "hackage->guix-package test 1"
  179. (eval-test-with-cabal test-cabal-1 match-ghc-foo))
  180. (test-assert "hackage->guix-package test 2"
  181. (eval-test-with-cabal test-cabal-2 match-ghc-foo))
  182. (test-assert "hackage->guix-package test 3"
  183. (eval-test-with-cabal test-cabal-3 match-ghc-foo
  184. #:cabal-environment '(("impl" . "ghc-7.8"))))
  185. (test-assert "hackage->guix-package test 4"
  186. (eval-test-with-cabal test-cabal-4 match-ghc-foo
  187. #:cabal-environment '(("impl" . "ghc-7.8"))))
  188. (test-assert "hackage->guix-package test 5"
  189. (eval-test-with-cabal test-cabal-5 match-ghc-foo
  190. #:cabal-environment '(("impl" . "ghc-7.8"))))
  191. (define-package-matcher match-ghc-foo-6
  192. ('package
  193. ('name "ghc-foo")
  194. ('version "1.0.0")
  195. ('source
  196. ('origin
  197. ('method 'url-fetch)
  198. ('uri ('string-append
  199. "https://hackage.haskell.org/package/foo/foo-"
  200. 'version
  201. ".tar.gz"))
  202. ('sha256
  203. ('base32
  204. (? string? hash)))))
  205. ('build-system 'haskell-build-system)
  206. ('inputs ('list 'ghc-b 'ghc-http))
  207. ('native-inputs ('list 'ghc-haskell-gi))
  208. ('home-page "http://test.org")
  209. ('synopsis (? string?))
  210. ('description (? string?))
  211. ('license 'license:bsd-3)))
  212. (test-assert "hackage->guix-package test 6"
  213. (eval-test-with-cabal test-cabal-6 match-ghc-foo-6))
  214. ;; Check multi-line layouted description.
  215. (define test-cabal-multiline-layout
  216. "name: foo
  217. version: 1.0.0
  218. homepage: http://test.org
  219. synopsis: synopsis
  220. description: first line
  221. second line
  222. license: BSD3
  223. executable cabal
  224. build-depends:
  225. HTTP >= 4000.2.5 && < 4000.3,
  226. mtl >= 2.0 && < 3
  227. ")
  228. (test-assert "hackage->guix-package test multiline desc (layout)"
  229. (eval-test-with-cabal test-cabal-multiline-layout match-ghc-foo))
  230. ;; Check multi-line braced description.
  231. (define test-cabal-multiline-braced
  232. "name: foo
  233. version: 1.0.0
  234. homepage: http://test.org
  235. synopsis: synopsis
  236. description: {
  237. first line
  238. second line
  239. }
  240. license: BSD3
  241. executable cabal
  242. build-depends:
  243. HTTP >= 4000.2.5 && < 4000.3,
  244. mtl >= 2.0 && < 3
  245. ")
  246. (test-assert "hackage->guix-package test multiline desc (braced)"
  247. (eval-test-with-cabal test-cabal-multiline-braced match-ghc-foo))
  248. ;; Check mixed layout. Compare e.g. warp.
  249. (define test-cabal-mixed-layout
  250. "name: foo
  251. version: 1.0.0
  252. homepage: http://test.org
  253. synopsis: synopsis
  254. description: description
  255. license: BSD3
  256. executable cabal
  257. build-depends:
  258. HTTP >= 4000.2.5 && < 4000.3,
  259. mtl >= 2.0 && < 3
  260. ghc-options: -Wall
  261. ")
  262. ;; Fails: https://debbugs.gnu.org/cgi/bugreport.cgi?bug=35743
  263. (test-expect-fail 1)
  264. (test-assert "hackage->guix-package test mixed layout"
  265. (eval-test-with-cabal test-cabal-mixed-layout match-ghc-foo))
  266. ;; Check flag executable. Compare e.g. darcs.
  267. (define test-cabal-flag-executable
  268. "name: foo
  269. version: 1.0.0
  270. homepage: http://test.org
  271. synopsis: synopsis
  272. description: description
  273. license: BSD3
  274. flag executable
  275. description: Build executable
  276. default: True
  277. executable cabal
  278. if !flag(executable)
  279. buildable: False
  280. else
  281. buildable: True
  282. build-depends:
  283. HTTP >= 4000.2.5 && < 4000.3,
  284. mtl >= 2.0 && < 3
  285. ")
  286. (test-assert "hackage->guix-package test flag executable"
  287. (eval-test-with-cabal test-cabal-flag-executable match-ghc-foo))
  288. ;; Check Hackage Cabal revisions.
  289. (define test-cabal-revision
  290. "name: foo
  291. version: 1.0.0
  292. x-revision: 2
  293. homepage: http://test.org
  294. synopsis: synopsis
  295. description: description
  296. license: BSD3
  297. executable cabal
  298. build-depends:
  299. HTTP >= 4000.2.5 && < 4000.3,
  300. mtl >= 2.0 && < 3
  301. ")
  302. (define-package-matcher match-ghc-foo-revision
  303. ('package
  304. ('name "ghc-foo")
  305. ('version "1.0.0")
  306. ('source
  307. ('origin
  308. ('method 'url-fetch)
  309. ('uri ('string-append
  310. "https://hackage.haskell.org/package/foo/foo-"
  311. 'version
  312. ".tar.gz"))
  313. ('sha256
  314. ('base32
  315. (? string? hash)))))
  316. ('build-system 'haskell-build-system)
  317. ('inputs ('list 'ghc-http))
  318. ('arguments
  319. ('quasiquote
  320. ('#:cabal-revision
  321. ("2" "0xxd88fb659f0krljidbvvmkh9ppjnx83j0nqzx8whcg4n5qbyng"))))
  322. ('home-page "http://test.org")
  323. ('synopsis (? string?))
  324. ('description (? string?))
  325. ('license 'license:bsd-3)))
  326. (test-assert "hackage->guix-package test cabal revision"
  327. (eval-test-with-cabal test-cabal-revision match-ghc-foo-revision))
  328. (test-assert "read-cabal test 1"
  329. (match (call-with-input-string test-read-cabal-1 read-cabal)
  330. ((("name" ("test-me"))
  331. ('section 'library
  332. (('if ('flag "base4point8")
  333. (("build-depends" ("base >= 4.8 && < 5")))
  334. (('if ('flag "base4")
  335. (("build-depends" ("base >= 4 && < 4.8")))
  336. (('if ('flag "base3")
  337. (("build-depends" ("base >= 3 && < 4")))
  338. (("build-depends" ("base < 3"))))))))
  339. ('if ('or ('flag "base4point8")
  340. ('and ('flag "base4") ('flag "base3")))
  341. (("build-depends" ("random")))
  342. ())
  343. ("build-depends" ("containers"))
  344. ("exposed-modules" ("Test.QuickCheck.Exception")))))
  345. #t)
  346. (x (pk 'fail x #f))))
  347. (define test-cabal-import
  348. "name: foo
  349. version: 1.0.0
  350. homepage: http://test.org
  351. synopsis: synopsis
  352. description: description
  353. license: BSD3
  354. common commons
  355. build-depends:
  356. HTTP >= 4000.2.5 && < 4000.3,
  357. mtl >= 2.0 && < 3
  358. executable cabal
  359. import: commons
  360. ")
  361. (define-package-matcher match-ghc-foo-import
  362. ('package
  363. ('name "ghc-foo")
  364. ('version "1.0.0")
  365. ('source
  366. ('origin
  367. ('method 'url-fetch)
  368. ('uri ('string-append
  369. "https://hackage.haskell.org/package/foo/foo-"
  370. 'version
  371. ".tar.gz"))
  372. ('sha256
  373. ('base32
  374. (? string? hash)))))
  375. ('build-system 'haskell-build-system)
  376. ('inputs ('list 'ghc-http))
  377. ('home-page "http://test.org")
  378. ('synopsis (? string?))
  379. ('description (? string?))
  380. ('license 'license:bsd-3)))
  381. (test-assert "hackage->guix-package test cabal import"
  382. (eval-test-with-cabal test-cabal-import match-ghc-foo-import))
  383. (test-end "hackage")