style.scm 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367
  1. ;;; GNU Guix --- Functional package management for GNU
  2. ;;; Copyright © 2021 Ludovic Courtès <ludo@gnu.org>
  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 (tests-style)
  19. #:use-module (guix packages)
  20. #:use-module (guix scripts style)
  21. #:use-module ((guix utils) #:select (call-with-temporary-directory))
  22. #:use-module ((guix build utils) #:select (substitute*))
  23. #:use-module (guix diagnostics)
  24. #:use-module (gnu packages acl)
  25. #:use-module (gnu packages multiprecision)
  26. #:use-module (srfi srfi-1)
  27. #:use-module (srfi srfi-64)
  28. #:use-module (ice-9 match)
  29. #:use-module (ice-9 rdelim)
  30. #:use-module (ice-9 pretty-print))
  31. (define (call-with-test-package inputs proc)
  32. (call-with-temporary-directory
  33. (lambda (directory)
  34. (call-with-output-file (string-append directory "/my-packages.scm")
  35. (lambda (port)
  36. (pretty-print
  37. `(begin
  38. (define-module (my-packages)
  39. #:use-module (guix)
  40. #:use-module (guix licenses)
  41. #:use-module (gnu packages acl)
  42. #:use-module (gnu packages base)
  43. #:use-module (gnu packages multiprecision)
  44. #:use-module (srfi srfi-1))
  45. (define base
  46. (package
  47. (inherit coreutils)
  48. (inputs '())
  49. (native-inputs '())
  50. (propagated-inputs '())))
  51. (define (sdl-union . lst)
  52. (package
  53. (inherit base)
  54. (name "sdl-union")))
  55. (define-public my-coreutils
  56. (package
  57. (inherit base)
  58. ,@inputs
  59. (name "my-coreutils"))))
  60. port)))
  61. (proc directory))))
  62. (define test-directory
  63. ;; Directory where the package definition lives.
  64. (make-parameter #f))
  65. (define-syntax-rule (with-test-package fields exp ...)
  66. (call-with-test-package fields
  67. (lambda (directory)
  68. (define file
  69. (string-append directory "/my-packages.scm"))
  70. ;; Run as a separate process to make sure FILE is reloaded.
  71. (system* "guix" "style" "-L" directory "my-coreutils")
  72. (system* "cat" file)
  73. (load file)
  74. (parameterize ((test-directory directory))
  75. exp ...))))
  76. (define* (read-lines port line #:optional (count 1))
  77. "Read COUNT lines from PORT, starting from LINE."
  78. (let loop ((lines '())
  79. (count count))
  80. (cond ((< (port-line port) (- line 1))
  81. (read-char port)
  82. (loop lines count))
  83. ((zero? count)
  84. (string-concatenate-reverse lines))
  85. (else
  86. (match (read-line port 'concat)
  87. ((? eof-object?)
  88. (loop lines 0))
  89. (line
  90. (loop (cons line lines) (- count 1))))))))
  91. (define* (read-package-field package field #:optional (count 1))
  92. (let* ((location (package-field-location package field))
  93. (file (location-file location))
  94. (line (location-line location)))
  95. (call-with-input-file (if (string-prefix? "/" file)
  96. file
  97. (string-append (test-directory) "/"
  98. file))
  99. (lambda (port)
  100. (read-lines port line count)))))
  101. (test-begin "style")
  102. (test-equal "nothing to rewrite"
  103. '()
  104. (with-test-package '()
  105. (package-direct-inputs (@ (my-packages) my-coreutils))))
  106. (test-equal "input labels, mismatch"
  107. (list `(("foo" ,gmp) ("bar" ,acl))
  108. " (inputs `((\"foo\" ,gmp) (\"bar\" ,acl)))\n")
  109. (with-test-package '((inputs `(("foo" ,gmp) ("bar" ,acl))))
  110. (list (package-direct-inputs (@ (my-packages) my-coreutils))
  111. (read-package-field (@ (my-packages) my-coreutils) 'inputs))))
  112. (test-equal "input labels, simple"
  113. (list `(("gmp" ,gmp) ("acl" ,acl))
  114. " (inputs (list gmp acl))\n")
  115. (with-test-package '((inputs `(("gmp" ,gmp) ("acl" ,acl))))
  116. (list (package-direct-inputs (@ (my-packages) my-coreutils))
  117. (read-package-field (@ (my-packages) my-coreutils) 'inputs))))
  118. (test-equal "input labels, long list with one item per line"
  119. (list (concatenate (make-list 4 `(("gmp" ,gmp) ("acl" ,acl))))
  120. "\
  121. (list gmp
  122. acl
  123. gmp
  124. acl
  125. gmp
  126. acl
  127. gmp
  128. acl))\n")
  129. (with-test-package '((inputs `(("gmp" ,gmp) ("acl" ,acl)
  130. ("gmp" ,gmp) ("acl" ,acl)
  131. ("gmp" ,gmp) ("acl" ,acl)
  132. ("gmp" ,gmp) ("acl" ,acl))))
  133. (list (package-direct-inputs (@ (my-packages) my-coreutils))
  134. (read-package-field (@ (my-packages) my-coreutils) 'inputs 8))))
  135. (test-equal "input labels, sdl-union"
  136. "\
  137. (list gmp acl
  138. (sdl-union 1 2 3 4)))\n"
  139. (with-test-package '((inputs `(("gmp" ,gmp) ("acl" ,acl)
  140. ("sdl-union" ,(sdl-union 1 2 3 4)))))
  141. (read-package-field (@ (my-packages) my-coreutils) 'inputs 2)))
  142. (test-equal "input labels, output"
  143. (list `(("gmp" ,gmp "debug") ("acl" ,acl))
  144. " (inputs (list `(,gmp \"debug\") acl))\n")
  145. (with-test-package '((inputs `(("gmp" ,gmp "debug") ("acl" ,acl))))
  146. (list (package-direct-inputs (@ (my-packages) my-coreutils))
  147. (read-package-field (@ (my-packages) my-coreutils) 'inputs))))
  148. (test-equal "input labels, prepend"
  149. (list `(("gmp" ,gmp) ("acl" ,acl))
  150. "\
  151. (modify-inputs (package-propagated-inputs coreutils)
  152. (prepend gmp acl)))\n")
  153. (with-test-package '((inputs `(("gmp" ,gmp) ("acl" ,acl)
  154. ,@(package-propagated-inputs coreutils))))
  155. (list (package-inputs (@ (my-packages) my-coreutils))
  156. (read-package-field (@ (my-packages) my-coreutils) 'inputs 2))))
  157. (test-equal "input labels, prepend + delete"
  158. (list `(("gmp" ,gmp) ("acl" ,acl))
  159. "\
  160. (modify-inputs (package-propagated-inputs coreutils)
  161. (delete \"gmp\")
  162. (prepend gmp acl)))\n")
  163. (with-test-package '((inputs `(("gmp" ,gmp)
  164. ("acl" ,acl)
  165. ,@(alist-delete "gmp"
  166. (package-propagated-inputs coreutils)))))
  167. (list (package-inputs (@ (my-packages) my-coreutils))
  168. (read-package-field (@ (my-packages) my-coreutils) 'inputs 3))))
  169. (test-equal "input labels, prepend + delete multiple"
  170. (list `(("gmp" ,gmp) ("acl" ,acl))
  171. "\
  172. (modify-inputs (package-propagated-inputs coreutils)
  173. (delete \"foo\" \"bar\" \"baz\")
  174. (prepend gmp acl)))\n")
  175. (with-test-package '((inputs `(("gmp" ,gmp)
  176. ("acl" ,acl)
  177. ,@(fold alist-delete
  178. (package-propagated-inputs coreutils)
  179. '("foo" "bar" "baz")))))
  180. (list (package-inputs (@ (my-packages) my-coreutils))
  181. (read-package-field (@ (my-packages) my-coreutils) 'inputs 3))))
  182. (test-equal "input labels, replace"
  183. (list '() ;there's no "gmp" input to replace
  184. "\
  185. (modify-inputs (package-propagated-inputs coreutils)
  186. (replace \"gmp\" gmp)))\n")
  187. (with-test-package '((inputs `(("gmp" ,gmp)
  188. ,@(alist-delete "gmp"
  189. (package-propagated-inputs coreutils)))))
  190. (list (package-inputs (@ (my-packages) my-coreutils))
  191. (read-package-field (@ (my-packages) my-coreutils) 'inputs 2))))
  192. (test-equal "input labels, 'safe' policy"
  193. (list `(("gmp" ,gmp) ("acl" ,acl))
  194. "\
  195. (inputs (list gmp acl))\n")
  196. (call-with-test-package '((inputs `(("GMP" ,gmp) ("ACL" ,acl)))
  197. (arguments '())) ;no build system arguments
  198. (lambda (directory)
  199. (define file
  200. (string-append directory "/my-packages.scm"))
  201. (system* "guix" "style" "-L" directory "my-coreutils"
  202. "--input-simplification=safe")
  203. (load file)
  204. (list (package-inputs (@ (my-packages) my-coreutils))
  205. (read-package-field (@ (my-packages) my-coreutils) 'inputs)))))
  206. (test-equal "input labels, 'safe' policy, nothing changed"
  207. (list `(("GMP" ,gmp) ("ACL" ,acl))
  208. "\
  209. (inputs `((\"GMP\" ,gmp) (\"ACL\" ,acl)))\n")
  210. (call-with-test-package '((inputs `(("GMP" ,gmp) ("ACL" ,acl)))
  211. ;; Non-empty argument list, so potentially unsafe
  212. ;; input simplification.
  213. (arguments
  214. '(#:configure-flags
  215. (assoc-ref %build-inputs "GMP"))))
  216. (lambda (directory)
  217. (define file
  218. (string-append directory "/my-packages.scm"))
  219. (system* "guix" "style" "-L" directory "my-coreutils"
  220. "--input-simplification=safe")
  221. (load file)
  222. (list (package-inputs (@ (my-packages) my-coreutils))
  223. (read-package-field (@ (my-packages) my-coreutils) 'inputs)))))
  224. (test-equal "input labels, margin comment"
  225. (list `(("gmp" ,gmp))
  226. `(("acl" ,acl))
  227. " (inputs (list gmp)) ;margin comment\n"
  228. " (native-inputs (list acl)) ;another one\n")
  229. (call-with-test-package '((inputs `(("gmp" ,gmp)))
  230. (native-inputs `(("acl" ,acl))))
  231. (lambda (directory)
  232. (define file
  233. (string-append directory "/my-packages.scm"))
  234. (substitute* file
  235. (("\"gmp\"(.*)$" _ rest)
  236. (string-append "\"gmp\"" (string-trim-right rest)
  237. " ;margin comment\n"))
  238. (("\"acl\"(.*)$" _ rest)
  239. (string-append "\"acl\"" (string-trim-right rest)
  240. " ;another one\n")))
  241. (system* "cat" file)
  242. (system* "guix" "style" "-L" directory "my-coreutils")
  243. (load file)
  244. (list (package-inputs (@ (my-packages) my-coreutils))
  245. (package-native-inputs (@ (my-packages) my-coreutils))
  246. (read-package-field (@ (my-packages) my-coreutils) 'inputs)
  247. (read-package-field (@ (my-packages) my-coreutils) 'native-inputs)))))
  248. (test-equal "input labels, margin comment on long list"
  249. (list (concatenate (make-list 4 `(("gmp" ,gmp) ("acl" ,acl))))
  250. "\
  251. (list gmp ;margin comment
  252. acl
  253. gmp ;margin comment
  254. acl
  255. gmp ;margin comment
  256. acl
  257. gmp ;margin comment
  258. acl))\n")
  259. (call-with-test-package '((inputs `(("gmp" ,gmp) ("acl" ,acl)
  260. ("gmp" ,gmp) ("acl" ,acl)
  261. ("gmp" ,gmp) ("acl" ,acl)
  262. ("gmp" ,gmp) ("acl" ,acl))))
  263. (lambda (directory)
  264. (define file
  265. (string-append directory "/my-packages.scm"))
  266. (substitute* file
  267. (("\"gmp\"(.*)$" _ rest)
  268. (string-append "\"gmp\"" (string-trim-right rest)
  269. " ;margin comment\n")))
  270. (system* "cat" file)
  271. (system* "guix" "style" "-L" directory "my-coreutils")
  272. (load file)
  273. (list (package-inputs (@ (my-packages) my-coreutils))
  274. (read-package-field (@ (my-packages) my-coreutils) 'inputs 8)))))
  275. (test-equal "input labels, line comment"
  276. (list `(("gmp" ,gmp) ("acl" ,acl))
  277. "\
  278. (inputs (list gmp
  279. ;; line comment!
  280. acl))\n")
  281. (call-with-test-package '((inputs `(("gmp" ,gmp) ("acl" ,acl))))
  282. (lambda (directory)
  283. (define file
  284. (string-append directory "/my-packages.scm"))
  285. (substitute* file
  286. ((",gmp\\)(.*)$" _ rest)
  287. (string-append ",gmp)\n ;; line comment!\n" rest)))
  288. (system* "guix" "style" "-L" directory "my-coreutils")
  289. (load file)
  290. (list (package-inputs (@ (my-packages) my-coreutils))
  291. (read-package-field (@ (my-packages) my-coreutils) 'inputs 3)))))
  292. (test-equal "input labels, modify-inputs and margin comment"
  293. (list `(("gmp" ,gmp) ("acl" ,acl) ("mpfr" ,mpfr))
  294. "\
  295. (modify-inputs (package-propagated-inputs coreutils)
  296. (prepend gmp ;margin comment
  297. acl ;another one
  298. mpfr)))\n")
  299. (call-with-test-package '((inputs
  300. `(("gmp" ,gmp) ("acl" ,acl) ("mpfr" ,mpfr)
  301. ,@(package-propagated-inputs coreutils))))
  302. (lambda (directory)
  303. (define file
  304. (string-append directory "/my-packages.scm"))
  305. (substitute* file
  306. ((",gmp\\)(.*)$" _ rest)
  307. (string-append ",gmp) ;margin comment\n" rest))
  308. ((",acl\\)(.*)$" _ rest)
  309. (string-append ",acl) ;another one\n" rest)))
  310. (system* "guix" "style" "-L" directory "my-coreutils")
  311. (load file)
  312. (list (package-inputs (@ (my-packages) my-coreutils))
  313. (read-package-field (@ (my-packages) my-coreutils) 'inputs 4)))))
  314. (test-end)
  315. ;; Local Variables:
  316. ;; eval: (put 'with-test-package 'scheme-indent-function 1)
  317. ;; eval: (put 'call-with-test-package 'scheme-indent-function 1)
  318. ;; End: