pypi.scm 8.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216
  1. ;;; GNU Guix --- Functional package management for GNU
  2. ;;; Copyright © 2014 David Thompson <davet@gnu.org>
  3. ;;; Copyright © 2016 Ricardo Wurmus <rekado@elephly.net>
  4. ;;;
  5. ;;; This file is part of GNU Guix.
  6. ;;;
  7. ;;; GNU Guix is free software; you can redistribute it and/or modify it
  8. ;;; under the terms of the GNU General Public License as published by
  9. ;;; the Free Software Foundation; either version 3 of the License, or (at
  10. ;;; your option) any later version.
  11. ;;;
  12. ;;; GNU Guix is distributed in the hope that it will be useful, but
  13. ;;; WITHOUT ANY WARRANTY; without even the implied warranty of
  14. ;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  15. ;;; GNU General Public License for more details.
  16. ;;;
  17. ;;; You should have received a copy of the GNU General Public License
  18. ;;; along with GNU Guix. If not, see <http://www.gnu.org/licenses/>.
  19. (define-module (test-pypi)
  20. #:use-module (guix import pypi)
  21. #:use-module (guix base32)
  22. #:use-module (guix hash)
  23. #:use-module (guix tests)
  24. #:use-module (guix build-system python)
  25. #:use-module ((guix build utils) #:select (delete-file-recursively which))
  26. #:use-module (srfi srfi-64)
  27. #:use-module (ice-9 match))
  28. (define test-json
  29. "{
  30. \"info\": {
  31. \"version\": \"1.0.0\",
  32. \"name\": \"foo\",
  33. \"license\": \"GNU LGPL\",
  34. \"summary\": \"summary\",
  35. \"home_page\": \"http://example.com\",
  36. },
  37. \"releases\": {
  38. \"1.0.0\": [
  39. {
  40. \"url\": \"https://example.com/foo-1.0.0.egg\",
  41. \"packagetype\": \"bdist_egg\",
  42. }, {
  43. \"url\": \"https://example.com/foo-1.0.0.tar.gz\",
  44. \"packagetype\": \"sdist\",
  45. }, {
  46. \"url\": \"https://example.com/foo-1.0.0-py2.py3-none-any.whl\",
  47. \"packagetype\": \"bdist_wheel\",
  48. }
  49. ]
  50. }
  51. }")
  52. (define test-source-hash
  53. "")
  54. (define test-requirements
  55. "# A comment
  56. # A comment after a space
  57. bar
  58. baz > 13.37")
  59. (define test-metadata
  60. "{
  61. \"run_requires\": [
  62. {
  63. \"requires\": [
  64. \"bar\",
  65. \"baz (>13.37)\"
  66. ]
  67. }
  68. ]
  69. }")
  70. (test-begin "pypi")
  71. (test-equal "guix-package->pypi-name, old URL style"
  72. "psutil"
  73. (guix-package->pypi-name
  74. (dummy-package "foo"
  75. (source (dummy-origin
  76. (uri
  77. "https://pypi.io/packages/source/p/psutil/psutil-4.3.0.tar.gz"))))))
  78. (test-equal "guix-package->pypi-name, new URL style"
  79. "certbot"
  80. (guix-package->pypi-name
  81. (dummy-package "foo"
  82. (source (dummy-origin
  83. (uri
  84. "https://pypi.python.org/packages/a2/3b/4756e6a0ceb14e084042a2a65c615d68d25621c6fd446d0fc10d14c4ce7d/certbot-0.8.1.tar.gz"))))))
  85. (test-equal "guix-package->pypi-name, several URLs"
  86. "cram"
  87. (guix-package->pypi-name
  88. (dummy-package "foo"
  89. (source
  90. (dummy-origin
  91. (uri (list "https://bitheap.org/cram/cram-0.7.tar.gz"
  92. (pypi-uri "cram" "0.7"))))))))
  93. (test-assert "pypi->guix-package"
  94. ;; Replace network resources with sample data.
  95. (mock ((guix import utils) url-fetch
  96. (lambda (url file-name)
  97. (match url
  98. ("https://example.com/foo-1.0.0.tar.gz"
  99. (begin
  100. (mkdir "foo-1.0.0")
  101. (with-output-to-file "foo-1.0.0/requirements.txt"
  102. (lambda ()
  103. (display test-requirements)))
  104. (system* "tar" "czvf" file-name "foo-1.0.0/")
  105. (delete-file-recursively "foo-1.0.0")
  106. (set! test-source-hash
  107. (call-with-input-file file-name port-sha256))))
  108. ("https://example.com/foo-1.0.0-py2.py3-none-any.whl" #f)
  109. (_ (error "Unexpected URL: " url)))))
  110. (mock ((guix http-client) http-fetch
  111. (lambda (url . rest)
  112. (match url
  113. ("https://pypi.python.org/pypi/foo/json"
  114. (values (open-input-string test-json)
  115. (string-length test-json)))
  116. ("https://example.com/foo-1.0.0-py2.py3-none-any.whl" #f)
  117. (_ (error "Unexpected URL: " url)))))
  118. (match (pypi->guix-package "foo")
  119. (('package
  120. ('name "python-foo")
  121. ('version "1.0.0")
  122. ('source ('origin
  123. ('method 'url-fetch)
  124. ('uri ('pypi-uri "foo" 'version))
  125. ('sha256
  126. ('base32
  127. (? string? hash)))))
  128. ('build-system 'python-build-system)
  129. ('propagated-inputs
  130. ('quasiquote
  131. (("python-bar" ('unquote 'python-bar))
  132. ("python-baz" ('unquote 'python-baz)))))
  133. ('home-page "http://example.com")
  134. ('synopsis "summary")
  135. ('description "summary")
  136. ('license 'license:lgpl2.0))
  137. (string=? (bytevector->nix-base32-string
  138. test-source-hash)
  139. hash))
  140. (x
  141. (pk 'fail x #f))))))
  142. (test-skip (if (which "zip") 0 1))
  143. (test-assert "pypi->guix-package, wheels"
  144. ;; Replace network resources with sample data.
  145. (mock ((guix import utils) url-fetch
  146. (lambda (url file-name)
  147. (match url
  148. ("https://example.com/foo-1.0.0.tar.gz"
  149. (begin
  150. (mkdir "foo-1.0.0")
  151. (with-output-to-file "foo-1.0.0/requirements.txt"
  152. (lambda ()
  153. (display test-requirements)))
  154. (system* "tar" "czvf" file-name "foo-1.0.0/")
  155. (delete-file-recursively "foo-1.0.0")
  156. (set! test-source-hash
  157. (call-with-input-file file-name port-sha256))))
  158. ("https://example.com/foo-1.0.0-py2.py3-none-any.whl"
  159. (begin
  160. (mkdir "foo-1.0.0.dist-info")
  161. (with-output-to-file "foo-1.0.0.dist-info/metadata.json"
  162. (lambda ()
  163. (display test-metadata)))
  164. (let ((zip-file (string-append file-name ".zip")))
  165. ;; zip always adds a "zip" extension to the file it creates,
  166. ;; so we need to rename it.
  167. (system* "zip" zip-file "foo-1.0.0.dist-info/metadata.json")
  168. (rename-file zip-file file-name))
  169. (delete-file-recursively "foo-1.0.0.dist-info")))
  170. (_ (error "Unexpected URL: " url)))))
  171. (mock ((guix http-client) http-fetch
  172. (lambda (url . rest)
  173. (match url
  174. ("https://pypi.python.org/pypi/foo/json"
  175. (values (open-input-string test-json)
  176. (string-length test-json)))
  177. ("https://example.com/foo-1.0.0-py2.py3-none-any.whl" #f)
  178. (_ (error "Unexpected URL: " url)))))
  179. (match (pypi->guix-package "foo")
  180. (('package
  181. ('name "python-foo")
  182. ('version "1.0.0")
  183. ('source ('origin
  184. ('method 'url-fetch)
  185. ('uri ('pypi-uri "foo" 'version))
  186. ('sha256
  187. ('base32
  188. (? string? hash)))))
  189. ('build-system 'python-build-system)
  190. ('propagated-inputs
  191. ('quasiquote
  192. (("python-bar" ('unquote 'python-bar))
  193. ("python-baz" ('unquote 'python-baz)))))
  194. ('home-page "http://example.com")
  195. ('synopsis "summary")
  196. ('description "summary")
  197. ('license 'license:lgpl2.0))
  198. (string=? (bytevector->nix-base32-string
  199. test-source-hash)
  200. hash))
  201. (x
  202. (pk 'fail x #f))))))
  203. (test-end "pypi")