1 ;;; GNU Guix --- Functional package management for GNU
2 ;;; Copyright © 2014 David Thompson <davet@gnu.org>
3 ;;; Copyright © 2016 David Craven <david@craven.ch>
4 ;;; Copyright © 2019, 2020, 2022 Ludovic Courtès <ludo@gnu.org>
5 ;;; Copyright © 2020 Martin Becze <mjbecze@riseup.net>
7 ;;; This file is part of GNU Guix.
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.
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.
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/>.
22 (define-module (test-crate)
23 #:use-module (guix import crate)
24 #:use-module (guix base32)
25 #:use-module (guix build-system cargo)
26 #:use-module (gcrypt hash)
27 #:use-module (guix tests)
28 #:use-module (gnu packages)
29 #:use-module (ice-9 iconv)
30 #:use-module (ice-9 match)
31 #:use-module (srfi srfi-64))
34 ;; crate versions and dependencies used here
42 ;; intermediate-a 1.0.42
43 ;; intermeidate-b ^1.0.0
47 ;; intermediate-a-1.0.40
48 ;; intermediate-a-1.0.42
49 ;; intermediate-a-1.1.0-alpha.1
50 ;; intermediate-a 1.2.3
54 ;; intermediate-b-1.2.3
63 (define test-foo-crate
66 \"max_version\": \"1.0.3\",
68 \"description\": \"summary\",
69 \"homepage\": \"http://example.com\",
70 \"repository\": \"http://example.com\",
71 \"keywords\": [\"dummy\", \"test\"],
72 \"categories\": [\"test\"],
73 \"actual_versions\": [
76 \"license\": \"MIT OR Apache-2.0\",
78 \"dependencies\": \"/api/v1/crates/foo/0.8.1/dependencies\"
83 \"license\": \"MIT OR Apache-2.0\",
85 \"dependencies\": \"/api/v1/crates/foo/1.0.0/dependencies\"
90 \"license\": \"MIT OR Apache-2.0\",
92 \"dependencies\": \"/api/v1/crates/foo/1.0.3/dependencies\"
99 (define test-foo-dependencies
103 \"crate_id\": \"leaf-alice\",
104 \"kind\": \"normal\",
110 (define test-root-crate
113 \"max_version\": \"1.0.4\",
115 \"description\": \"summary\",
116 \"homepage\": \"http://example.com\",
117 \"repository\": \"http://example.com\",
118 \"keywords\": [\"dummy\", \"test\"],
119 \"categories\": [\"test\"],
120 \"actual_versions\": [
123 \"license\": \"MIT OR Apache-2.0\",
125 \"dependencies\": \"/api/v1/crates/root/1.0.0/dependencies\"
130 \"license\": \"MIT OR Apache-2.0\",
132 \"dependencies\": \"/api/v1/crates/root/1.0.4/dependencies\"
139 (define test-root-dependencies
143 \"crate_id\": \"intermediate-a\",
144 \"kind\": \"normal\",
148 \"crate_id\": \"intermediate-b\",
149 \"kind\": \"normal\",
153 \"crate_id\": \"leaf-alice\",
154 \"kind\": \"normal\",
158 \"crate_id\": \"leaf-bob\",
159 \"kind\": \"normal\",
165 (define test-intermediate-a-crate
168 \"max_version\": \"1.1.0-alpha.1\",
169 \"name\": \"intermediate-a\",
170 \"description\": \"summary\",
171 \"homepage\": \"http://example.com\",
172 \"repository\": \"http://example.com\",
173 \"keywords\": [\"dummy\", \"test\"],
174 \"categories\": [\"test\"],
175 \"actual_versions\": [
178 \"license\": \"MIT OR Apache-2.0\",
180 \"dependencies\": \"/api/v1/crates/intermediate-a/1.0.40/dependencies\"
185 \"license\": \"MIT OR Apache-2.0\",
187 \"dependencies\": \"/api/v1/crates/intermediate-a/1.0.42/dependencies\"
191 \"num\": \"1.1.0-alpha.1\",
192 \"license\": \"MIT OR Apache-2.0\",
194 \"dependencies\": \"/api/v1/crates/intermediate-a/1.1.0-alpha.1/dependencies\"
201 (define test-intermediate-a-dependencies
205 \"crate_id\": \"intermediate-b\",
206 \"kind\": \"normal\",
210 \"crate_id\": \"leaf-alice\",
211 \"kind\": \"normal\",
215 \"crate_id\": \"leaf-bob\",
216 \"kind\": \"normal\",
222 (define test-intermediate-b-crate
225 \"max_version\": \"1.2.3\",
226 \"name\": \"intermediate-b\",
227 \"description\": \"summary\",
228 \"homepage\": \"http://example.com\",
229 \"repository\": \"http://example.com\",
230 \"keywords\": [\"dummy\", \"test\"],
231 \"categories\": [\"test\"],
232 \"actual_versions\": [
235 \"license\": \"MIT OR Apache-2.0\",
237 \"dependencies\": \"/api/v1/crates/intermediate-b/1.2.3/dependencies\"
244 (define test-intermediate-b-dependencies
248 \"crate_id\": \"leaf-bob\",
249 \"kind\": \"normal\",
255 (define test-leaf-alice-crate
258 \"max_version\": \"0.7.5\",
259 \"name\": \"leaf-alice\",
260 \"description\": \"summary\",
261 \"homepage\": \"http://example.com\",
262 \"repository\": \"http://example.com\",
263 \"keywords\": [\"dummy\", \"test\"],
264 \"categories\": [\"test\"],
265 \"actual_versions\": [
268 \"license\": \"MIT OR Apache-2.0\",
270 \"dependencies\": \"/api/v1/crates/leaf-alice/0.7.3/dependencies\"
275 \"license\": \"MIT OR Apache-2.0\",
277 \"dependencies\": \"/api/v1/crates/leaf-alice/0.7.5/dependencies\"
284 (define test-leaf-alice-dependencies
289 (define test-leaf-bob-crate
292 \"max_version\": \"3.0.1\",
293 \"name\": \"leaf-bob\",
294 \"description\": \"summary\",
295 \"homepage\": \"http://example.com\",
296 \"repository\": \"http://example.com\",
297 \"keywords\": [\"dummy\", \"test\"],
298 \"categories\": [\"test\"]
299 \"actual_versions\": [
302 \"license\": \"MIT OR Apache-2.0\",
304 \"dependencies\": \"/api/v1/crates/leaf-bob/3.0.1/dependencies\"
311 (define test-leaf-bob-dependencies
317 (define test-source-hash
320 (define have-guile-semver?
321 (false-if-exception (resolve-interface '(semver))))
326 (test-equal "guix-package->crate-name"
328 (guix-package->crate-name
330 "rust-rustc-serialize"
331 (source (dummy-origin
332 (uri (crate-uri "rustc-serialize" "1.0")))))))
334 (unless have-guile-semver? (test-skip 1))
335 (test-assert "crate->guix-package"
336 ;; Replace network resources with sample data.
337 (mock ((guix http-client) http-fetch
340 ("https://crates.io/api/v1/crates/foo"
341 (open-input-string test-foo-crate))
342 ("https://crates.io/api/v1/crates/foo/1.0.3/download"
343 (set! test-source-hash
344 (bytevector->nix-base32-string
345 (sha256 (string->bytevector "empty file\n" "utf-8"))))
346 (open-input-string "empty file\n"))
347 ("https://crates.io/api/v1/crates/foo/1.0.3/dependencies"
348 (open-input-string test-foo-dependencies))
349 ("https://crates.io/api/v1/crates/leaf-alice"
350 (open-input-string test-leaf-alice-crate))
351 ("https://crates.io/api/v1/crates/leaf-alice/0.7.5/download"
352 (set! test-source-hash
353 (bytevector->nix-base32-string
354 (sha256 (string->bytevector "empty file\n" "utf-8"))))
355 (open-input-string "empty file\n"))
356 ("https://crates.io/api/v1/crates/leaf-alice/0.7.5/dependencies"
357 (open-input-string test-leaf-alice-dependencies))
358 (_ (error "Unexpected URL: " url)))))
360 (match (crate->guix-package "foo")
361 ((define-public 'rust-foo-1
362 (package (name "rust-foo")
367 (uri (crate-uri "foo" 'version))
368 (file-name (string-append name "-" version ".tar.gz"))
372 (build-system 'cargo-build-system)
377 (("rust-leaf-alice" ('unquote 'rust-leaf-alice-0.7))))))
378 (home-page "http://example.com")
380 (description "summary")
381 (license (list license:expat license:asl2.0))))
383 (string=? test-source-hash hash))
387 (unless have-guile-semver? (test-skip 1))
388 (test-assert "cargo-recursive-import"
389 ;; Replace network resources with sample data.
390 (mock ((guix http-client) http-fetch
393 ("https://crates.io/api/v1/crates/root"
394 (open-input-string test-root-crate))
395 ("https://crates.io/api/v1/crates/root/1.0.4/download"
396 (set! test-source-hash
397 (bytevector->nix-base32-string
398 (sha256 (string->bytevector "empty file\n" "utf-8"))))
399 (open-input-string "empty file\n"))
400 ("https://crates.io/api/v1/crates/root/1.0.4/dependencies"
401 (open-input-string test-root-dependencies))
402 ("https://crates.io/api/v1/crates/intermediate-a"
403 (open-input-string test-intermediate-a-crate))
404 ("https://crates.io/api/v1/crates/intermediate-a/1.0.42/download"
405 (set! test-source-hash
406 (bytevector->nix-base32-string
407 (sha256 (string->bytevector "empty file\n" "utf-8"))))
408 (open-input-string "empty file\n"))
409 ("https://crates.io/api/v1/crates/intermediate-a/1.0.42/dependencies"
410 (open-input-string test-intermediate-a-dependencies))
411 ("https://crates.io/api/v1/crates/intermediate-b"
412 (open-input-string test-intermediate-b-crate))
413 ("https://crates.io/api/v1/crates/intermediate-b/1.2.3/download"
414 (set! test-source-hash
415 (bytevector->nix-base32-string
416 (sha256 (string->bytevector "empty file\n" "utf-8"))))
417 (open-input-string "empty file\n"))
418 ("https://crates.io/api/v1/crates/intermediate-b/1.2.3/dependencies"
419 (open-input-string test-intermediate-b-dependencies))
420 ("https://crates.io/api/v1/crates/leaf-alice"
421 (open-input-string test-leaf-alice-crate))
422 ("https://crates.io/api/v1/crates/leaf-alice/0.7.5/download"
423 (set! test-source-hash
424 (bytevector->nix-base32-string
425 (sha256 (string->bytevector "empty file\n" "utf-8"))))
426 (open-input-string "empty file\n"))
427 ("https://crates.io/api/v1/crates/leaf-alice/0.7.5/dependencies"
428 (open-input-string test-leaf-alice-dependencies))
429 ("https://crates.io/api/v1/crates/leaf-bob"
430 (open-input-string test-leaf-bob-crate))
431 ("https://crates.io/api/v1/crates/leaf-bob/3.0.1/download"
432 (set! test-source-hash
433 (bytevector->nix-base32-string
434 (sha256 (string->bytevector "empty file\n" "utf-8"))))
435 (open-input-string "empty file\n"))
436 ("https://crates.io/api/v1/crates/leaf-bob/3.0.1/dependencies"
437 (open-input-string test-leaf-bob-dependencies))
438 (_ (error "Unexpected URL: " url)))))
439 (match (crate-recursive-import "root")
440 ;; rust-intermediate-b has no dependency on the rust-leaf-alice
441 ;; package, so this is a valid ordering
442 (((define-public 'rust-leaf-alice-0.7
444 (name "rust-leaf-alice")
449 (uri (crate-uri "leaf-alice" version))
451 (string-append name "-" version ".tar.gz"))
455 (build-system cargo-build-system)
456 (arguments ('quasiquote (#:skip-build? #t)))
457 (home-page "http://example.com")
459 (description "summary")
460 (license (list license:expat license:asl2.0))))
461 (define-public 'rust-leaf-bob-3
463 (name "rust-leaf-bob")
468 (uri (crate-uri "leaf-bob" version))
470 (string-append name "-" version ".tar.gz"))
474 (build-system cargo-build-system)
475 (arguments ('quasiquote (#:skip-build? #t)))
476 (home-page "http://example.com")
478 (description "summary")
479 (license (list license:expat license:asl2.0))))
480 (define-public 'rust-intermediate-b-1
482 (name "rust-intermediate-b")
487 (uri (crate-uri "intermediate-b" version))
489 (string-append name "-" version ".tar.gz"))
493 (build-system cargo-build-system)
495 ('quasiquote (#:skip-build? #t
498 ('unquote rust-leaf-bob-3))))))
499 (home-page "http://example.com")
501 (description "summary")
502 (license (list license:expat license:asl2.0))))
503 (define-public 'rust-intermediate-a-1
505 (name "rust-intermediate-a")
510 (uri (crate-uri "intermediate-a" version))
512 (string-append name "-" version ".tar.gz"))
516 (build-system cargo-build-system)
518 ('quasiquote (#:skip-build? #t
520 (("rust-intermediate-b"
521 ('unquote rust-intermediate-b-1))
523 ('unquote 'rust-leaf-alice-0.7))
525 ('unquote rust-leaf-bob-3))))))
526 (home-page "http://example.com")
528 (description "summary")
529 (license (list license:expat license:asl2.0))))
530 (define-public 'rust-root-1
537 (uri (crate-uri "root" version))
539 (string-append name "-" version ".tar.gz"))
543 (build-system cargo-build-system)
545 ('quasiquote (#:cargo-inputs
546 (("rust-intermediate-a"
547 ('unquote rust-intermediate-a-1))
548 ("rust-intermediate-b"
549 ('unquote rust-intermediate-b-1))
551 ('unquote 'rust-leaf-alice-0.7))
553 ('unquote rust-leaf-bob-3))))))
554 (home-page "http://example.com")
556 (description "summary")
557 (license (list license:expat license:asl2.0)))))
562 (test-equal "licenses: MIT OR Apache-2.0"
563 '(license:expat license:asl2.0)
564 (string->license "MIT OR Apache-2.0"))
566 (test-equal "licenses: Apache-2.0 / MIT"
567 '(license:asl2.0 license:expat)
568 (string->license "Apache-2.0 / MIT"))
570 (test-equal "licenses: Apache-2.0 WITH LLVM-exception"
571 '(license:asl2.0 unknown-license!)
572 (string->license "Apache-2.0 WITH LLVM-exception"))
574 (test-equal "licenses: MIT/Apache-2.0 AND BSD-2-Clause"
575 '(license:expat license:asl2.0 license:bsd-2)
576 (string->license "MIT/Apache-2.0 AND BSD-2-Clause"))
578 (test-equal "licenses: MIT/Apache-2.0"
579 '(license:expat license:asl2.0)
580 (string->license "MIT/Apache-2.0"))
584 (define test-doctool-crate
587 \"max_version\": \"2.2.2\",
588 \"name\": \"leaf-bob\",
589 \"description\": \"summary\",
590 \"homepage\": \"http://example.com\",
591 \"repository\": \"http://example.com\",
592 \"keywords\": [\"dummy\", \"test\"],
593 \"categories\": [\"test\"]
594 \"actual_versions\": [
597 \"license\": \"MIT OR Apache-2.0\",
599 \"dependencies\": \"/api/v1/crates/doctool/2.2.2/dependencies\"
606 ;; FIXME: This test depends on some existing packages
607 (define test-doctool-dependencies
611 \"crate_id\": \"docopt\",
612 \"kind\": \"normal\",
619 (test-assert "self-test: rust-docopt 0.8.x is gone, please adjust the test case"
620 (not (null? (find-packages-by-name "rust-docopt" "0.8"))))
622 (unless have-guile-semver? (test-skip 1))
623 (test-assert "cargo-recursive-import-hoors-existing-packages"
624 (mock ((guix http-client) http-fetch
627 ("https://crates.io/api/v1/crates/doctool"
628 (open-input-string test-doctool-crate))
629 ("https://crates.io/api/v1/crates/doctool/2.2.2/download"
630 (set! test-source-hash
631 (bytevector->nix-base32-string
632 (sha256 (string->bytevector "empty file\n" "utf-8"))))
633 (open-input-string "empty file\n"))
634 ("https://crates.io/api/v1/crates/doctool/2.2.2/dependencies"
635 (open-input-string test-doctool-dependencies))
636 (_ (error "Unexpected URL: " url)))))
637 (match (crate-recursive-import "doctool")
638 (((define-public 'rust-doctool-2
640 (name "rust-doctool")
645 (uri (crate-uri "doctool" version))
647 (string-append name "-" version ".tar.gz"))
651 (build-system cargo-build-system)
653 ('quasiquote (#:cargo-inputs
655 ('unquote 'rust-docopt-0.8))))))
656 (home-page "http://example.com")
658 (description "summary")
659 (license (list license:expat license:asl2.0)))))