lint.scm 32 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920
  1. ;;; GNU Guix --- Functional package management for GNU
  2. ;;; Copyright © 2012, 2013 Cyril Roelandt <tipecaml@gmail.com>
  3. ;;; Copyright © 2014, 2015, 2016 Eric Bavier <bavier@member.fsf.org>
  4. ;;; Copyright © 2014, 2015, 2016, 2017, 2018 Ludovic Courtès <ludo@gnu.org>
  5. ;;; Copyright © 2015, 2016 Mathieu Lirzin <mthl@gnu.org>
  6. ;;; Copyright © 2016 Hartmut Goebel <h.goebel@crazy-compilers.com>
  7. ;;; Copyright © 2017 Alex Kost <alezost@gmail.com>
  8. ;;; Copyright © 2017 Efraim Flashner <efraim@flashner.co.il>
  9. ;;; Copyright © 2018, 2019 Arun Isaac <arunisaac@systemreboot.net>
  10. ;;;
  11. ;;; This file is part of GNU Guix.
  12. ;;;
  13. ;;; GNU Guix is free software; you can redistribute it and/or modify it
  14. ;;; under the terms of the GNU General Public License as published by
  15. ;;; the Free Software Foundation; either version 3 of the License, or (at
  16. ;;; your option) any later version.
  17. ;;;
  18. ;;; GNU Guix is distributed in the hope that it will be useful, but
  19. ;;; WITHOUT ANY WARRANTY; without even the implied warranty of
  20. ;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  21. ;;; GNU General Public License for more details.
  22. ;;;
  23. ;;; You should have received a copy of the GNU General Public License
  24. ;;; along with GNU Guix. If not, see <http://www.gnu.org/licenses/>.
  25. ;; Avoid interference.
  26. (unsetenv "http_proxy")
  27. (define-module (test-lint)
  28. #:use-module (guix tests)
  29. #:use-module (guix tests http)
  30. #:use-module (guix download)
  31. #:use-module (guix git-download)
  32. #:use-module (guix build-system gnu)
  33. #:use-module (guix packages)
  34. #:use-module (guix scripts lint)
  35. #:use-module (guix ui)
  36. #:use-module (gnu packages)
  37. #:use-module (gnu packages glib)
  38. #:use-module (gnu packages pkg-config)
  39. #:use-module (gnu packages python-xyz)
  40. #:use-module (web uri)
  41. #:use-module (web server)
  42. #:use-module (web server http)
  43. #:use-module (web response)
  44. #:use-module (ice-9 match)
  45. #:use-module (srfi srfi-9 gnu)
  46. #:use-module (srfi srfi-64))
  47. ;; Test the linter.
  48. ;; Avoid collisions with other tests.
  49. (%http-server-port 9999)
  50. (define %null-sha256
  51. ;; SHA256 of the empty string.
  52. (base32
  53. "0mdqa9w1p6cmli6976v4wi0sw9r4p5prkj7lzfd1877wk11c9c73"))
  54. (define %long-string
  55. (make-string 2000 #\a))
  56. (test-begin "lint")
  57. (define (call-with-warnings thunk)
  58. (let ((port (open-output-string)))
  59. (parameterize ((guix-warning-port port))
  60. (thunk))
  61. (get-output-string port)))
  62. (define-syntax-rule (with-warnings body ...)
  63. (call-with-warnings (lambda () body ...)))
  64. (test-assert "description: not a string"
  65. (->bool
  66. (string-contains (with-warnings
  67. (let ((pkg (dummy-package "x"
  68. (description 'foobar))))
  69. (check-description-style pkg)))
  70. "invalid description")))
  71. (test-assert "description: not empty"
  72. (->bool
  73. (string-contains (with-warnings
  74. (let ((pkg (dummy-package "x"
  75. (description ""))))
  76. (check-description-style pkg)))
  77. "description should not be empty")))
  78. (test-assert "description: valid Texinfo markup"
  79. (->bool
  80. (string-contains
  81. (with-warnings
  82. (check-description-style (dummy-package "x" (description "f{oo}b@r"))))
  83. "Texinfo markup in description is invalid")))
  84. (test-assert "description: does not start with an upper-case letter"
  85. (->bool
  86. (string-contains (with-warnings
  87. (let ((pkg (dummy-package "x"
  88. (description "bad description."))))
  89. (check-description-style pkg)))
  90. "description should start with an upper-case letter")))
  91. (test-assert "description: may start with a digit"
  92. (string-null?
  93. (with-warnings
  94. (let ((pkg (dummy-package "x"
  95. (description "2-component library."))))
  96. (check-description-style pkg)))))
  97. (test-assert "description: may start with lower-case package name"
  98. (string-null?
  99. (with-warnings
  100. (let ((pkg (dummy-package "x"
  101. (description "x is a dummy package."))))
  102. (check-description-style pkg)))))
  103. (test-assert "description: two spaces after end of sentence"
  104. (->bool
  105. (string-contains (with-warnings
  106. (let ((pkg (dummy-package "x"
  107. (description "Bad. Quite bad."))))
  108. (check-description-style pkg)))
  109. "sentences in description should be followed by two spaces")))
  110. (test-assert "description: end-of-sentence detection with abbreviations"
  111. (string-null?
  112. (with-warnings
  113. (let ((pkg (dummy-package "x"
  114. (description
  115. "E.g. Foo, i.e. Bar resp. Baz (a.k.a. DVD)."))))
  116. (check-description-style pkg)))))
  117. (test-assert "description: may not contain trademark signs"
  118. (and (->bool
  119. (string-contains (with-warnings
  120. (let ((pkg (dummy-package "x"
  121. (description "Does The Right Thing™"))))
  122. (check-description-style pkg)))
  123. "should not contain trademark sign"))
  124. (->bool
  125. (string-contains (with-warnings
  126. (let ((pkg (dummy-package "x"
  127. (description "Works with Format®"))))
  128. (check-description-style pkg)))
  129. "should not contain trademark sign"))))
  130. (test-assert "description: suggest ornament instead of quotes"
  131. (->bool
  132. (string-contains (with-warnings
  133. (let ((pkg (dummy-package "x"
  134. (description "This is a 'quoted' thing."))))
  135. (check-description-style pkg)))
  136. "use @code")))
  137. (test-assert "synopsis: not a string"
  138. (->bool
  139. (string-contains (with-warnings
  140. (let ((pkg (dummy-package "x"
  141. (synopsis #f))))
  142. (check-synopsis-style pkg)))
  143. "invalid synopsis")))
  144. (test-assert "synopsis: not empty"
  145. (->bool
  146. (string-contains (with-warnings
  147. (let ((pkg (dummy-package "x"
  148. (synopsis ""))))
  149. (check-synopsis-style pkg)))
  150. "synopsis should not be empty")))
  151. (test-assert "synopsis: valid Texinfo markup"
  152. (->bool
  153. (string-contains
  154. (with-warnings
  155. (check-synopsis-style (dummy-package "x" (synopsis "Bad $@ texinfo"))))
  156. "Texinfo markup in synopsis is invalid")))
  157. (test-assert "synopsis: does not start with an upper-case letter"
  158. (->bool
  159. (string-contains (with-warnings
  160. (let ((pkg (dummy-package "x"
  161. (synopsis "bad synopsis."))))
  162. (check-synopsis-style pkg)))
  163. "synopsis should start with an upper-case letter")))
  164. (test-assert "synopsis: may start with a digit"
  165. (string-null?
  166. (with-warnings
  167. (let ((pkg (dummy-package "x"
  168. (synopsis "5-dimensional frobnicator"))))
  169. (check-synopsis-style pkg)))))
  170. (test-assert "synopsis: ends with a period"
  171. (->bool
  172. (string-contains (with-warnings
  173. (let ((pkg (dummy-package "x"
  174. (synopsis "Bad synopsis."))))
  175. (check-synopsis-style pkg)))
  176. "no period allowed at the end of the synopsis")))
  177. (test-assert "synopsis: ends with 'etc.'"
  178. (string-null? (with-warnings
  179. (let ((pkg (dummy-package "x"
  180. (synopsis "Foo, bar, etc."))))
  181. (check-synopsis-style pkg)))))
  182. (test-assert "synopsis: starts with 'A'"
  183. (->bool
  184. (string-contains (with-warnings
  185. (let ((pkg (dummy-package "x"
  186. (synopsis "A bad synopŝis"))))
  187. (check-synopsis-style pkg)))
  188. "no article allowed at the beginning of the synopsis")))
  189. (test-assert "synopsis: starts with 'An'"
  190. (->bool
  191. (string-contains (with-warnings
  192. (let ((pkg (dummy-package "x"
  193. (synopsis "An awful synopsis"))))
  194. (check-synopsis-style pkg)))
  195. "no article allowed at the beginning of the synopsis")))
  196. (test-assert "synopsis: starts with 'a'"
  197. (->bool
  198. (string-contains (with-warnings
  199. (let ((pkg (dummy-package "x"
  200. (synopsis "a bad synopsis"))))
  201. (check-synopsis-style pkg)))
  202. "no article allowed at the beginning of the synopsis")))
  203. (test-assert "synopsis: starts with 'an'"
  204. (->bool
  205. (string-contains (with-warnings
  206. (let ((pkg (dummy-package "x"
  207. (synopsis "an awful synopsis"))))
  208. (check-synopsis-style pkg)))
  209. "no article allowed at the beginning of the synopsis")))
  210. (test-assert "synopsis: too long"
  211. (->bool
  212. (string-contains (with-warnings
  213. (let ((pkg (dummy-package "x"
  214. (synopsis (make-string 80 #\x)))))
  215. (check-synopsis-style pkg)))
  216. "synopsis should be less than 80 characters long")))
  217. (test-assert "synopsis: start with package name"
  218. (->bool
  219. (string-contains (with-warnings
  220. (let ((pkg (dummy-package "x"
  221. (name "foo")
  222. (synopsis "foo, a nice package"))))
  223. (check-synopsis-style pkg)))
  224. "synopsis should not start with the package name")))
  225. (test-assert "synopsis: start with package name prefix"
  226. (string-null?
  227. (with-warnings
  228. (let ((pkg (dummy-package "arb"
  229. (synopsis "Arbitrary precision"))))
  230. (check-synopsis-style pkg)))))
  231. (test-assert "synopsis: start with abbreviation"
  232. (string-null?
  233. (with-warnings
  234. (let ((pkg (dummy-package "uucp"
  235. ;; Same problem with "APL interpreter", etc.
  236. (synopsis "UUCP implementation")
  237. (description "Imagine this is Taylor UUCP."))))
  238. (check-synopsis-style pkg)))))
  239. (test-assert "inputs: pkg-config is probably a native input"
  240. (->bool
  241. (string-contains
  242. (with-warnings
  243. (let ((pkg (dummy-package "x"
  244. (inputs `(("pkg-config" ,pkg-config))))))
  245. (check-inputs-should-be-native pkg)))
  246. "'pkg-config' should probably be a native input")))
  247. (test-assert "inputs: glib:bin is probably a native input"
  248. (->bool
  249. (string-contains
  250. (with-warnings
  251. (let ((pkg (dummy-package "x"
  252. (inputs `(("glib" ,glib "bin"))))))
  253. (check-inputs-should-be-native pkg)))
  254. "'glib:bin' should probably be a native input")))
  255. (test-assert
  256. "inputs: python-setuptools should not be an input at all (input)"
  257. (->bool
  258. (string-contains
  259. (with-warnings
  260. (let ((pkg (dummy-package "x"
  261. (inputs `(("python-setuptools" ,python-setuptools))))))
  262. (check-inputs-should-not-be-an-input-at-all pkg)))
  263. "'python-setuptools' should probably not be an input at all")))
  264. (test-assert
  265. "inputs: python-setuptools should not be an input at all (native-input)"
  266. (->bool
  267. (string-contains
  268. (with-warnings
  269. (let ((pkg (dummy-package "x"
  270. (native-inputs
  271. `(("python-setuptools" ,python-setuptools))))))
  272. (check-inputs-should-not-be-an-input-at-all pkg)))
  273. "'python-setuptools' should probably not be an input at all")))
  274. (test-assert
  275. "inputs: python-setuptools should not be an input at all (propagated-input)"
  276. (->bool
  277. (string-contains
  278. (with-warnings
  279. (let ((pkg (dummy-package "x"
  280. (propagated-inputs
  281. `(("python-setuptools" ,python-setuptools))))))
  282. (check-inputs-should-not-be-an-input-at-all pkg)))
  283. "'python-setuptools' should probably not be an input at all")))
  284. (test-assert "patches: file names"
  285. (->bool
  286. (string-contains
  287. (with-warnings
  288. (let ((pkg (dummy-package "x"
  289. (source
  290. (dummy-origin
  291. (patches (list "/path/to/y.patch")))))))
  292. (check-patch-file-names pkg)))
  293. "file names of patches should start with the package name")))
  294. (test-assert "patches: file name too long"
  295. (->bool
  296. (string-contains
  297. (with-warnings
  298. (let ((pkg (dummy-package "x"
  299. (source
  300. (dummy-origin
  301. (patches (list (string-append "x-"
  302. (make-string 100 #\a)
  303. ".patch"))))))))
  304. (check-patch-file-names pkg)))
  305. "file name is too long")))
  306. (test-assert "patches: not found"
  307. (->bool
  308. (string-contains
  309. (with-warnings
  310. (let ((pkg (dummy-package "x"
  311. (source
  312. (dummy-origin
  313. (patches
  314. (list (search-patch "this-patch-does-not-exist!"))))))))
  315. (check-patch-file-names pkg)))
  316. "patch not found")))
  317. (test-assert "derivation: invalid arguments"
  318. (->bool
  319. (string-contains
  320. (with-warnings
  321. (let ((pkg (dummy-package "x"
  322. (arguments
  323. '(#:imported-modules (invalid-module))))))
  324. (check-derivation pkg)))
  325. "failed to create")))
  326. (test-assert "license: invalid license"
  327. (string-contains
  328. (with-warnings
  329. (check-license (dummy-package "x" (license #f))))
  330. "invalid license"))
  331. (test-assert "home-page: wrong home-page"
  332. (->bool
  333. (string-contains
  334. (with-warnings
  335. (let ((pkg (package
  336. (inherit (dummy-package "x"))
  337. (home-page #f))))
  338. (check-home-page pkg)))
  339. "invalid")))
  340. (test-assert "home-page: invalid URI"
  341. (->bool
  342. (string-contains
  343. (with-warnings
  344. (let ((pkg (package
  345. (inherit (dummy-package "x"))
  346. (home-page "foobar"))))
  347. (check-home-page pkg)))
  348. "invalid home page URL")))
  349. (test-assert "home-page: host not found"
  350. (->bool
  351. (string-contains
  352. (with-warnings
  353. (let ((pkg (package
  354. (inherit (dummy-package "x"))
  355. (home-page "http://does-not-exist"))))
  356. (check-home-page pkg)))
  357. "domain not found")))
  358. (test-skip (if (http-server-can-listen?) 0 1))
  359. (test-assert "home-page: Connection refused"
  360. (->bool
  361. (string-contains
  362. (with-warnings
  363. (let ((pkg (package
  364. (inherit (dummy-package "x"))
  365. (home-page (%local-url)))))
  366. (check-home-page pkg)))
  367. "Connection refused")))
  368. (test-skip (if (http-server-can-listen?) 0 1))
  369. (test-equal "home-page: 200"
  370. ""
  371. (with-warnings
  372. (with-http-server 200 %long-string
  373. (let ((pkg (package
  374. (inherit (dummy-package "x"))
  375. (home-page (%local-url)))))
  376. (check-home-page pkg)))))
  377. (test-skip (if (http-server-can-listen?) 0 1))
  378. (test-assert "home-page: 200 but short length"
  379. (->bool
  380. (string-contains
  381. (with-warnings
  382. (with-http-server 200 "This is too small."
  383. (let ((pkg (package
  384. (inherit (dummy-package "x"))
  385. (home-page (%local-url)))))
  386. (check-home-page pkg))))
  387. "suspiciously small")))
  388. (test-skip (if (http-server-can-listen?) 0 1))
  389. (test-assert "home-page: 404"
  390. (->bool
  391. (string-contains
  392. (with-warnings
  393. (with-http-server 404 %long-string
  394. (let ((pkg (package
  395. (inherit (dummy-package "x"))
  396. (home-page (%local-url)))))
  397. (check-home-page pkg))))
  398. "not reachable: 404")))
  399. (test-skip (if (http-server-can-listen?) 0 1))
  400. (test-assert "home-page: 301, invalid"
  401. (->bool
  402. (string-contains
  403. (with-warnings
  404. (with-http-server 301 %long-string
  405. (let ((pkg (package
  406. (inherit (dummy-package "x"))
  407. (home-page (%local-url)))))
  408. (check-home-page pkg))))
  409. "invalid permanent redirect")))
  410. (test-skip (if (http-server-can-listen?) 0 1))
  411. (test-assert "home-page: 301 -> 200"
  412. (->bool
  413. (string-contains
  414. (with-warnings
  415. (with-http-server 200 %long-string
  416. (let ((initial-url (%local-url)))
  417. (parameterize ((%http-server-port (+ 1 (%http-server-port))))
  418. (with-http-server (301 `((location
  419. . ,(string->uri initial-url))))
  420. ""
  421. (let ((pkg (package
  422. (inherit (dummy-package "x"))
  423. (home-page (%local-url)))))
  424. (check-home-page pkg)))))))
  425. "permanent redirect")))
  426. (test-skip (if (http-server-can-listen?) 0 1))
  427. (test-assert "home-page: 301 -> 404"
  428. (->bool
  429. (string-contains
  430. (with-warnings
  431. (with-http-server 404 "booh!"
  432. (let ((initial-url (%local-url)))
  433. (parameterize ((%http-server-port (+ 1 (%http-server-port))))
  434. (with-http-server (301 `((location
  435. . ,(string->uri initial-url))))
  436. ""
  437. (let ((pkg (package
  438. (inherit (dummy-package "x"))
  439. (home-page (%local-url)))))
  440. (check-home-page pkg)))))))
  441. "not reachable: 404")))
  442. (test-assert "source-file-name"
  443. (->bool
  444. (string-contains
  445. (with-warnings
  446. (let ((pkg (dummy-package "x"
  447. (version "3.2.1")
  448. (source
  449. (origin
  450. (method url-fetch)
  451. (uri "http://www.example.com/3.2.1.tar.gz")
  452. (sha256 %null-sha256))))))
  453. (check-source-file-name pkg)))
  454. "file name should contain the package name")))
  455. (test-assert "source-file-name: v prefix"
  456. (->bool
  457. (string-contains
  458. (with-warnings
  459. (let ((pkg (dummy-package "x"
  460. (version "3.2.1")
  461. (source
  462. (origin
  463. (method url-fetch)
  464. (uri "http://www.example.com/v3.2.1.tar.gz")
  465. (sha256 %null-sha256))))))
  466. (check-source-file-name pkg)))
  467. "file name should contain the package name")))
  468. (test-assert "source-file-name: bad checkout"
  469. (->bool
  470. (string-contains
  471. (with-warnings
  472. (let ((pkg (dummy-package "x"
  473. (version "3.2.1")
  474. (source
  475. (origin
  476. (method git-fetch)
  477. (uri (git-reference
  478. (url "http://www.example.com/x.git")
  479. (commit "0")))
  480. (sha256 %null-sha256))))))
  481. (check-source-file-name pkg)))
  482. "file name should contain the package name")))
  483. (test-assert "source-file-name: good checkout"
  484. (not
  485. (->bool
  486. (string-contains
  487. (with-warnings
  488. (let ((pkg (dummy-package "x"
  489. (version "3.2.1")
  490. (source
  491. (origin
  492. (method git-fetch)
  493. (uri (git-reference
  494. (url "http://git.example.com/x.git")
  495. (commit "0")))
  496. (file-name (string-append "x-" version))
  497. (sha256 %null-sha256))))))
  498. (check-source-file-name pkg)))
  499. "file name should contain the package name"))))
  500. (test-assert "source-file-name: valid"
  501. (not
  502. (->bool
  503. (string-contains
  504. (with-warnings
  505. (let ((pkg (dummy-package "x"
  506. (version "3.2.1")
  507. (source
  508. (origin
  509. (method url-fetch)
  510. (uri "http://www.example.com/x-3.2.1.tar.gz")
  511. (sha256 %null-sha256))))))
  512. (check-source-file-name pkg)))
  513. "file name should contain the package name"))))
  514. (test-assert "source-unstable-tarball"
  515. (string-contains
  516. (with-warnings
  517. (let ((pkg (dummy-package "x"
  518. (source
  519. (origin
  520. (method url-fetch)
  521. (uri "https://github.com/example/example/archive/v0.0.tar.gz")
  522. (sha256 %null-sha256))))))
  523. (check-source-unstable-tarball pkg)))
  524. "source URI should not be an autogenerated tarball"))
  525. (test-assert "source-unstable-tarball: source #f"
  526. (not
  527. (->bool
  528. (string-contains
  529. (with-warnings
  530. (let ((pkg (dummy-package "x"
  531. (source #f))))
  532. (check-source-unstable-tarball pkg)))
  533. "source URI should not be an autogenerated tarball"))))
  534. (test-assert "source-unstable-tarball: valid"
  535. (not
  536. (->bool
  537. (string-contains
  538. (with-warnings
  539. (let ((pkg (dummy-package "x"
  540. (source
  541. (origin
  542. (method url-fetch)
  543. (uri "https://github.com/example/example/releases/download/x-0.0/x-0.0.tar.gz")
  544. (sha256 %null-sha256))))))
  545. (check-source-unstable-tarball pkg)))
  546. "source URI should not be an autogenerated tarball"))))
  547. (test-assert "source-unstable-tarball: package named archive"
  548. (not
  549. (->bool
  550. (string-contains
  551. (with-warnings
  552. (let ((pkg (dummy-package "x"
  553. (source
  554. (origin
  555. (method url-fetch)
  556. (uri "https://github.com/example/archive/releases/download/x-0.0/x-0.0.tar.gz")
  557. (sha256 %null-sha256))))))
  558. (check-source-unstable-tarball pkg)))
  559. "source URI should not be an autogenerated tarball"))))
  560. (test-assert "source-unstable-tarball: not-github"
  561. (not
  562. (->bool
  563. (string-contains
  564. (with-warnings
  565. (let ((pkg (dummy-package "x"
  566. (source
  567. (origin
  568. (method url-fetch)
  569. (uri "https://bitbucket.org/archive/example/download/x-0.0.tar.gz")
  570. (sha256 %null-sha256))))))
  571. (check-source-unstable-tarball pkg)))
  572. "source URI should not be an autogenerated tarball"))))
  573. (test-assert "source-unstable-tarball: git-fetch"
  574. (not
  575. (->bool
  576. (string-contains
  577. (with-warnings
  578. (let ((pkg (dummy-package "x"
  579. (source
  580. (origin
  581. (method git-fetch)
  582. (uri (git-reference
  583. (url "https://github.com/archive/example.git")
  584. (commit "0")))
  585. (sha256 %null-sha256))))))
  586. (check-source-unstable-tarball pkg)))
  587. "source URI should not be an autogenerated tarball"))))
  588. (test-skip (if (http-server-can-listen?) 0 1))
  589. (test-equal "source: 200"
  590. ""
  591. (with-warnings
  592. (with-http-server 200 %long-string
  593. (let ((pkg (package
  594. (inherit (dummy-package "x"))
  595. (source (origin
  596. (method url-fetch)
  597. (uri (%local-url))
  598. (sha256 %null-sha256))))))
  599. (check-source pkg)))))
  600. (test-skip (if (http-server-can-listen?) 0 1))
  601. (test-assert "source: 200 but short length"
  602. (->bool
  603. (string-contains
  604. (with-warnings
  605. (with-http-server 200 "This is too small."
  606. (let ((pkg (package
  607. (inherit (dummy-package "x"))
  608. (source (origin
  609. (method url-fetch)
  610. (uri (%local-url))
  611. (sha256 %null-sha256))))))
  612. (check-source pkg))))
  613. "suspiciously small")))
  614. (test-skip (if (http-server-can-listen?) 0 1))
  615. (test-assert "source: 404"
  616. (->bool
  617. (string-contains
  618. (with-warnings
  619. (with-http-server 404 %long-string
  620. (let ((pkg (package
  621. (inherit (dummy-package "x"))
  622. (source (origin
  623. (method url-fetch)
  624. (uri (%local-url))
  625. (sha256 %null-sha256))))))
  626. (check-source pkg))))
  627. "not reachable: 404")))
  628. (test-skip (if (http-server-can-listen?) 0 1))
  629. (test-equal "source: 301 -> 200"
  630. ""
  631. (with-warnings
  632. (with-http-server 200 %long-string
  633. (let ((initial-url (%local-url)))
  634. (parameterize ((%http-server-port (+ 1 (%http-server-port))))
  635. (with-http-server (301 `((location . ,(string->uri initial-url))))
  636. ""
  637. (let ((pkg (package
  638. (inherit (dummy-package "x"))
  639. (source (origin
  640. (method url-fetch)
  641. (uri (%local-url))
  642. (sha256 %null-sha256))))))
  643. (check-source pkg))))))))
  644. (test-skip (if (http-server-can-listen?) 0 1))
  645. (test-assert "source: 301 -> 404"
  646. (->bool
  647. (string-contains
  648. (with-warnings
  649. (with-http-server 404 "booh!"
  650. (let ((initial-url (%local-url)))
  651. (parameterize ((%http-server-port (+ 1 (%http-server-port))))
  652. (with-http-server (301 `((location . ,(string->uri initial-url))))
  653. ""
  654. (let ((pkg (package
  655. (inherit (dummy-package "x"))
  656. (source (origin
  657. (method url-fetch)
  658. (uri (%local-url))
  659. (sha256 %null-sha256))))))
  660. (check-source pkg)))))))
  661. "not reachable: 404")))
  662. (test-assert "mirror-url"
  663. (string-null?
  664. (with-warnings
  665. (let ((source (origin
  666. (method url-fetch)
  667. (uri "http://example.org/foo/bar.tar.gz")
  668. (sha256 %null-sha256))))
  669. (check-mirror-url (dummy-package "x" (source source)))))))
  670. (test-assert "mirror-url: one suggestion"
  671. (string-contains
  672. (with-warnings
  673. (let ((source (origin
  674. (method url-fetch)
  675. (uri "http://ftp.gnu.org/pub/gnu/foo/foo.tar.gz")
  676. (sha256 %null-sha256))))
  677. (check-mirror-url (dummy-package "x" (source source)))))
  678. "mirror://gnu/foo/foo.tar.gz"))
  679. (test-assert "github-url"
  680. (string-null?
  681. (with-warnings
  682. (with-http-server 200 %long-string
  683. (check-github-url
  684. (dummy-package "x" (source
  685. (origin
  686. (method url-fetch)
  687. (uri (%local-url))
  688. (sha256 %null-sha256)))))))))
  689. (let ((github-url "https://github.com/foo/bar/bar-1.0.tar.gz"))
  690. (test-assert "github-url: one suggestion"
  691. (string-contains
  692. (with-warnings
  693. (with-http-server (301 `((location . ,(string->uri github-url)))) ""
  694. (let ((initial-uri (%local-url)))
  695. (parameterize ((%http-server-port (+ 1 (%http-server-port))))
  696. (with-http-server (302 `((location . ,(string->uri initial-uri)))) ""
  697. (check-github-url
  698. (dummy-package "x" (source
  699. (origin
  700. (method url-fetch)
  701. (uri (%local-url))
  702. (sha256 %null-sha256))))))))))
  703. github-url))
  704. (test-assert "github-url: already the correct github url"
  705. (string-null?
  706. (with-warnings
  707. (check-github-url
  708. (dummy-package "x" (source
  709. (origin
  710. (method url-fetch)
  711. (uri github-url)
  712. (sha256 %null-sha256)))))))))
  713. (test-assert "cve"
  714. (mock ((guix scripts lint) package-vulnerabilities (const '()))
  715. (string-null?
  716. (with-warnings (check-vulnerabilities (dummy-package "x"))))))
  717. (test-assert "cve: one vulnerability"
  718. (mock ((guix scripts lint) package-vulnerabilities
  719. (lambda (package)
  720. (list (make-struct (@@ (guix cve) <vulnerability>) 0
  721. "CVE-2015-1234"
  722. (list (cons (package-name package)
  723. (package-version package)))))))
  724. (string-contains
  725. (with-warnings
  726. (check-vulnerabilities (dummy-package "pi" (version "3.14"))))
  727. "vulnerable to CVE-2015-1234")))
  728. (test-assert "cve: one patched vulnerability"
  729. (mock ((guix scripts lint) package-vulnerabilities
  730. (lambda (package)
  731. (list (make-struct (@@ (guix cve) <vulnerability>) 0
  732. "CVE-2015-1234"
  733. (list (cons (package-name package)
  734. (package-version package)))))))
  735. (string-null?
  736. (with-warnings
  737. (check-vulnerabilities
  738. (dummy-package "pi"
  739. (version "3.14")
  740. (source
  741. (dummy-origin
  742. (patches
  743. (list "/a/b/pi-CVE-2015-1234.patch"))))))))))
  744. (test-assert "cve: known safe from vulnerability"
  745. (mock ((guix scripts lint) package-vulnerabilities
  746. (lambda (package)
  747. (list (make-struct (@@ (guix cve) <vulnerability>) 0
  748. "CVE-2015-1234"
  749. (list (cons (package-name package)
  750. (package-version package)))))))
  751. (string-null?
  752. (with-warnings
  753. (check-vulnerabilities
  754. (dummy-package "pi"
  755. (version "3.14")
  756. (properties `((lint-hidden-cve . ("CVE-2015-1234"))))))))))
  757. (test-assert "cve: vulnerability fixed in replacement version"
  758. (mock ((guix scripts lint) package-vulnerabilities
  759. (lambda (package)
  760. (match (package-version package)
  761. ("0"
  762. (list (make-struct (@@ (guix cve) <vulnerability>) 0
  763. "CVE-2015-1234"
  764. (list (cons (package-name package)
  765. (package-version package))))))
  766. ("1"
  767. '()))))
  768. (and (not (string-null?
  769. (with-warnings
  770. (check-vulnerabilities
  771. (dummy-package "foo" (version "0"))))))
  772. (string-null?
  773. (with-warnings
  774. (check-vulnerabilities
  775. (dummy-package
  776. "foo" (version "0")
  777. (replacement (dummy-package "foo" (version "1"))))))))))
  778. (test-assert "cve: patched vulnerability in replacement"
  779. (mock ((guix scripts lint) package-vulnerabilities
  780. (lambda (package)
  781. (list (make-struct (@@ (guix cve) <vulnerability>) 0
  782. "CVE-2015-1234"
  783. (list (cons (package-name package)
  784. (package-version package)))))))
  785. (string-null?
  786. (with-warnings
  787. (check-vulnerabilities
  788. (dummy-package
  789. "pi" (version "3.14") (source (dummy-origin))
  790. (replacement (dummy-package
  791. "pi" (version "3.14")
  792. (source
  793. (dummy-origin
  794. (patches
  795. (list "/a/b/pi-CVE-2015-1234.patch"))))))))))))
  796. (test-assert "formatting: lonely parentheses"
  797. (string-contains
  798. (with-warnings
  799. (check-formatting
  800. (
  801. dummy-package "ugly as hell!"
  802. )
  803. ))
  804. "lonely"))
  805. (test-assert "formatting: tabulation"
  806. (string-contains
  807. (with-warnings
  808. (check-formatting (dummy-package "leave the tab here: ")))
  809. "tabulation"))
  810. (test-assert "formatting: trailing white space"
  811. (string-contains
  812. (with-warnings
  813. ;; Leave the trailing white space on the next line!
  814. (check-formatting (dummy-package "x")))
  815. "trailing white space"))
  816. (test-assert "formatting: long line"
  817. (string-contains
  818. (with-warnings
  819. (check-formatting
  820. (dummy-package "x" ;here is a stupid comment just to make a long line
  821. )))
  822. "too long"))
  823. (test-assert "formatting: alright"
  824. (string-null?
  825. (with-warnings
  826. (check-formatting (dummy-package "x")))))
  827. (test-end "lint")
  828. ;; Local Variables:
  829. ;; eval: (put 'with-http-server 'scheme-indent-function 2)
  830. ;; eval: (put 'with-warnings 'scheme-indent-function 0)
  831. ;; End: