import: crate: Trim version for names after left-most non-zero part.
[jackhill/guix/guix.git] / tests / crate.scm
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 Ludovic Courtès <ludo@gnu.org>
5 ;;; Copyright © 2020 Martin Becze <mjbecze@riseup.net>
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
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 (ice-9 iconv)
29 #:use-module (ice-9 match)
30 #:use-module (srfi srfi-64))
31
32
33 ;; crate versions and dependencies used here
34 ;; foo-0.8.1
35 ;; foo-1.0.0
36 ;; foo-1.0.3
37 ;; leaf-alice 0.7.5
38 ;;
39 ;; root-1.0.0
40 ;; root-1.0.4
41 ;; intermediate-a 1.0.42
42 ;; intermeidate-b ^1.0.0
43 ;; leaf-alice ^0.7
44 ;; leaf-bob ^3
45 ;;
46 ;; intermediate-a-1.0.40
47 ;; intermediate-a-1.0.42
48 ;; intermediate-a-1.1.0-alpha.1
49 ;; intermediate-a 1.2.3
50 ;; leaf-alice 0.7.5
51 ;; leaf-bob ^3
52 ;;
53 ;; intermediate-b-1.2.3
54 ;; leaf-bob 3.0.1
55 ;;
56 ;; leaf-alice-0.7.3
57 ;; leaf-alice-0.7.5
58 ;;
59 ;; leaf-bob-3.0.1
60
61
62 (define test-foo-crate
63 "{
64 \"crate\": {
65 \"max_version\": \"1.0.3\",
66 \"name\": \"foo\",
67 \"description\": \"summary\",
68 \"homepage\": \"http://example.com\",
69 \"repository\": \"http://example.com\",
70 \"keywords\": [\"dummy\", \"test\"],
71 \"categories\": [\"test\"],
72 \"actual_versions\": [
73 { \"id\": 234210,
74 \"num\": \"0.8.1\",
75 \"license\": \"MIT OR Apache-2.0\",
76 \"links\": {
77 \"dependencies\": \"/api/v1/crates/foo/0.8.1/dependencies\"
78 }
79 },
80 { \"id\": 234212,
81 \"num\": \"1.0.0\",
82 \"license\": \"MIT OR Apache-2.0\",
83 \"links\": {
84 \"dependencies\": \"/api/v1/crates/foo/1.0.0/dependencies\"
85 }
86 },
87 { \"id\": 234214,
88 \"num\": \"1.0.3\",
89 \"license\": \"MIT OR Apache-2.0\",
90 \"links\": {
91 \"dependencies\": \"/api/v1/crates/foo/1.0.3/dependencies\"
92 }
93 }
94 ]
95 }
96 }")
97
98 (define test-foo-dependencies
99 "{
100 \"dependencies\": [
101 {
102 \"crate_id\": \"leaf-alice\",
103 \"kind\": \"normal\",
104 \"req\": \"0.7.5\"
105 }
106 ]
107 }")
108
109 (define test-root-crate
110 "{
111 \"crate\": {
112 \"max_version\": \"1.0.4\",
113 \"name\": \"root\",
114 \"description\": \"summary\",
115 \"homepage\": \"http://example.com\",
116 \"repository\": \"http://example.com\",
117 \"keywords\": [\"dummy\", \"test\"],
118 \"categories\": [\"test\"],
119 \"actual_versions\": [
120 { \"id\": 234240,
121 \"num\": \"1.0.0\",
122 \"license\": \"MIT OR Apache-2.0\",
123 \"links\": {
124 \"dependencies\": \"/api/v1/crates/root/1.0.0/dependencies\"
125 }
126 },
127 { \"id\": 234242,
128 \"num\": \"1.0.4\",
129 \"license\": \"MIT OR Apache-2.0\",
130 \"links\": {
131 \"dependencies\": \"/api/v1/crates/root/1.0.4/dependencies\"
132 }
133 }
134 ]
135 }
136 }")
137
138 (define test-root-dependencies
139 "{
140 \"dependencies\": [
141 {
142 \"crate_id\": \"intermediate-a\",
143 \"kind\": \"normal\",
144 \"req\": \"1.0.42\"
145 },
146 {
147 \"crate_id\": \"intermediate-b\",
148 \"kind\": \"normal\",
149 \"req\": \"^1.0.0\"
150 }
151 {
152 \"crate_id\": \"leaf-alice\",
153 \"kind\": \"normal\",
154 \"req\": \"^0.7\"
155 },
156 {
157 \"crate_id\": \"leaf-bob\",
158 \"kind\": \"normal\",
159 \"req\": \"^3\"
160 }
161 ]
162 }")
163
164 (define test-intermediate-a-crate
165 "{
166 \"crate\": {
167 \"max_version\": \"1.1.0-alpha.1\",
168 \"name\": \"intermediate-a\",
169 \"description\": \"summary\",
170 \"homepage\": \"http://example.com\",
171 \"repository\": \"http://example.com\",
172 \"keywords\": [\"dummy\", \"test\"],
173 \"categories\": [\"test\"],
174 \"actual_versions\": [
175 { \"id\": 234251,
176 \"num\": \"1.0.40\",
177 \"license\": \"MIT OR Apache-2.0\",
178 \"links\": {
179 \"dependencies\": \"/api/v1/crates/intermediate-a/1.0.40/dependencies\"
180 }
181 },
182 { \"id\": 234250,
183 \"num\": \"1.0.42\",
184 \"license\": \"MIT OR Apache-2.0\",
185 \"links\": {
186 \"dependencies\": \"/api/v1/crates/intermediate-a/1.0.42/dependencies\"
187 }
188 },
189 { \"id\": 234252,
190 \"num\": \"1.1.0-alpha.1\",
191 \"license\": \"MIT OR Apache-2.0\",
192 \"links\": {
193 \"dependencies\": \"/api/v1/crates/intermediate-a/1.1.0-alpha.1/dependencies\"
194 }
195 }
196 ]
197 }
198 }")
199
200 (define test-intermediate-a-dependencies
201 "{
202 \"dependencies\": [
203 {
204 \"crate_id\": \"intermediate-b\",
205 \"kind\": \"normal\",
206 \"req\": \"1.2.3\"
207 },
208 {
209 \"crate_id\": \"leaf-alice\",
210 \"kind\": \"normal\",
211 \"req\": \"0.7.5\"
212 },
213 {
214 \"crate_id\": \"leaf-bob\",
215 \"kind\": \"normal\",
216 \"req\": \"^3\"
217 }
218 ]
219 }")
220
221 (define test-intermediate-b-crate
222 "{
223 \"crate\": {
224 \"max_version\": \"1.2.3\",
225 \"name\": \"intermediate-b\",
226 \"description\": \"summary\",
227 \"homepage\": \"http://example.com\",
228 \"repository\": \"http://example.com\",
229 \"keywords\": [\"dummy\", \"test\"],
230 \"categories\": [\"test\"],
231 \"actual_versions\": [
232 { \"id\": 234260,
233 \"num\": \"1.2.3\",
234 \"license\": \"MIT OR Apache-2.0\",
235 \"links\": {
236 \"dependencies\": \"/api/v1/crates/intermediate-b/1.2.3/dependencies\"
237 }
238 }
239 ]
240 }
241 }")
242
243 (define test-intermediate-b-dependencies
244 "{
245 \"dependencies\": [
246 {
247 \"crate_id\": \"leaf-bob\",
248 \"kind\": \"normal\",
249 \"req\": \"3.0.1\"
250 }
251 ]
252 }")
253
254 (define test-leaf-alice-crate
255 "{
256 \"crate\": {
257 \"max_version\": \"0.7.5\",
258 \"name\": \"leaf-alice\",
259 \"description\": \"summary\",
260 \"homepage\": \"http://example.com\",
261 \"repository\": \"http://example.com\",
262 \"keywords\": [\"dummy\", \"test\"],
263 \"categories\": [\"test\"],
264 \"actual_versions\": [
265 { \"id\": 234270,
266 \"num\": \"0.7.3\",
267 \"license\": \"MIT OR Apache-2.0\",
268 \"links\": {
269 \"dependencies\": \"/api/v1/crates/leaf-alice/0.7.3/dependencies\"
270 }
271 },
272 { \"id\": 234272,
273 \"num\": \"0.7.5\",
274 \"license\": \"MIT OR Apache-2.0\",
275 \"links\": {
276 \"dependencies\": \"/api/v1/crates/leaf-alice/0.7.5/dependencies\"
277 }
278 }
279 ]
280 }
281 }")
282
283 (define test-leaf-alice-dependencies
284 "{
285 \"dependencies\": []
286 }")
287
288 (define test-leaf-bob-crate
289 "{
290 \"crate\": {
291 \"max_version\": \"3.0.1\",
292 \"name\": \"leaf-bob\",
293 \"description\": \"summary\",
294 \"homepage\": \"http://example.com\",
295 \"repository\": \"http://example.com\",
296 \"keywords\": [\"dummy\", \"test\"],
297 \"categories\": [\"test\"]
298 \"actual_versions\": [
299 { \"id\": 234280,
300 \"num\": \"3.0.1\",
301 \"license\": \"MIT OR Apache-2.0\",
302 \"links\": {
303 \"dependencies\": \"/api/v1/crates/leaf-bob/3.0.1/dependencies\"
304 }
305 }
306 ]
307 }
308 }")
309
310 (define test-leaf-bob-dependencies
311 "{
312 \"dependencies\": []
313 }")
314
315 (define test-source-hash
316 "")
317
318 \f
319 (test-begin "crate")
320
321 (test-equal "guix-package->crate-name"
322 "rustc-serialize"
323 (guix-package->crate-name
324 (dummy-package
325 "rust-rustc-serialize"
326 (source (dummy-origin
327 (uri (crate-uri "rustc-serialize" "1.0")))))))
328
329 (test-assert "crate->guix-package"
330 ;; Replace network resources with sample data.
331 (mock ((guix http-client) http-fetch
332 (lambda (url . rest)
333 (match url
334 ("https://crates.io/api/v1/crates/foo"
335 (open-input-string test-foo-crate))
336 ("https://crates.io/api/v1/crates/foo/1.0.3/download"
337 (set! test-source-hash
338 (bytevector->nix-base32-string
339 (sha256 (string->bytevector "empty file\n" "utf-8"))))
340 (open-input-string "empty file\n"))
341 ("https://crates.io/api/v1/crates/foo/1.0.3/dependencies"
342 (open-input-string test-foo-dependencies))
343 ("https://crates.io/api/v1/crates/leaf-alice"
344 (open-input-string test-leaf-alice-crate))
345 ("https://crates.io/api/v1/crates/leaf-alice/0.7.5/download"
346 (set! test-source-hash
347 (bytevector->nix-base32-string
348 (sha256 (string->bytevector "empty file\n" "utf-8"))))
349 (open-input-string "empty file\n"))
350 ("https://crates.io/api/v1/crates/leaf-alice/0.7.5/dependencies"
351 (open-input-string test-leaf-alice-dependencies))
352 (_ (error "Unexpected URL: " url)))))
353
354 (match (crate->guix-package "foo")
355 ((define-public 'rust-foo-1
356 (package (name "rust-foo")
357 (version "1.0.3")
358 (source
359 (origin
360 (method url-fetch)
361 (uri (crate-uri "foo" 'version))
362 (file-name (string-append name "-" version ".tar.gz"))
363 (sha256
364 (base32
365 (? string? hash)))))
366 (build-system 'cargo-build-system)
367 (arguments
368 ('quasiquote
369 (#:skip-build? #t
370 #:cargo-inputs
371 (("rust-leaf-alice" ('unquote 'rust-leaf-alice-0.7))))))
372 (home-page "http://example.com")
373 (synopsis "summary")
374 (description "summary")
375 (license (list license:expat license:asl2.0))))
376
377 (string=? test-source-hash hash))
378 (x
379 (pk 'fail x #f)))))
380
381 (test-assert "cargo-recursive-import"
382 ;; Replace network resources with sample data.
383 (mock ((guix http-client) http-fetch
384 (lambda (url . rest)
385 (match url
386 ("https://crates.io/api/v1/crates/root"
387 (open-input-string test-root-crate))
388 ("https://crates.io/api/v1/crates/root/1.0.4/download"
389 (set! test-source-hash
390 (bytevector->nix-base32-string
391 (sha256 (string->bytevector "empty file\n" "utf-8"))))
392 (open-input-string "empty file\n"))
393 ("https://crates.io/api/v1/crates/root/1.0.4/dependencies"
394 (open-input-string test-root-dependencies))
395 ("https://crates.io/api/v1/crates/intermediate-a"
396 (open-input-string test-intermediate-a-crate))
397 ("https://crates.io/api/v1/crates/intermediate-a/1.0.42/download"
398 (set! test-source-hash
399 (bytevector->nix-base32-string
400 (sha256 (string->bytevector "empty file\n" "utf-8"))))
401 (open-input-string "empty file\n"))
402 ("https://crates.io/api/v1/crates/intermediate-a/1.0.42/dependencies"
403 (open-input-string test-intermediate-a-dependencies))
404 ("https://crates.io/api/v1/crates/intermediate-b"
405 (open-input-string test-intermediate-b-crate))
406 ("https://crates.io/api/v1/crates/intermediate-b/1.2.3/download"
407 (set! test-source-hash
408 (bytevector->nix-base32-string
409 (sha256 (string->bytevector "empty file\n" "utf-8"))))
410 (open-input-string "empty file\n"))
411 ("https://crates.io/api/v1/crates/intermediate-b/1.2.3/dependencies"
412 (open-input-string test-intermediate-b-dependencies))
413 ("https://crates.io/api/v1/crates/leaf-alice"
414 (open-input-string test-leaf-alice-crate))
415 ("https://crates.io/api/v1/crates/leaf-alice/0.7.5/download"
416 (set! test-source-hash
417 (bytevector->nix-base32-string
418 (sha256 (string->bytevector "empty file\n" "utf-8"))))
419 (open-input-string "empty file\n"))
420 ("https://crates.io/api/v1/crates/leaf-alice/0.7.5/dependencies"
421 (open-input-string test-leaf-alice-dependencies))
422 ("https://crates.io/api/v1/crates/leaf-bob"
423 (open-input-string test-leaf-bob-crate))
424 ("https://crates.io/api/v1/crates/leaf-bob/3.0.1/download"
425 (set! test-source-hash
426 (bytevector->nix-base32-string
427 (sha256 (string->bytevector "empty file\n" "utf-8"))))
428 (open-input-string "empty file\n"))
429 ("https://crates.io/api/v1/crates/leaf-bob/3.0.1/dependencies"
430 (open-input-string test-leaf-bob-dependencies))
431 (_ (error "Unexpected URL: " url)))))
432 (match (crate-recursive-import "root")
433 ;; rust-intermediate-b has no dependency on the rust-leaf-alice
434 ;; package, so this is a valid ordering
435 (((define-public 'rust-leaf-alice-0.7
436 (package
437 (name "rust-leaf-alice")
438 (version "0.7.5")
439 (source
440 (origin
441 (method url-fetch)
442 (uri (crate-uri "leaf-alice" version))
443 (file-name
444 (string-append name "-" version ".tar.gz"))
445 (sha256
446 (base32
447 (? string? hash)))))
448 (build-system cargo-build-system)
449 (arguments ('quasiquote (#:skip-build? #t)))
450 (home-page "http://example.com")
451 (synopsis "summary")
452 (description "summary")
453 (license (list license:expat license:asl2.0))))
454 (define-public 'rust-leaf-bob-3
455 (package
456 (name "rust-leaf-bob")
457 (version "3.0.1")
458 (source
459 (origin
460 (method url-fetch)
461 (uri (crate-uri "leaf-bob" version))
462 (file-name
463 (string-append name "-" version ".tar.gz"))
464 (sha256
465 (base32
466 (? string? hash)))))
467 (build-system cargo-build-system)
468 (arguments ('quasiquote (#:skip-build? #t)))
469 (home-page "http://example.com")
470 (synopsis "summary")
471 (description "summary")
472 (license (list license:expat license:asl2.0))))
473 (define-public 'rust-intermediate-b-1
474 (package
475 (name "rust-intermediate-b")
476 (version "1.2.3")
477 (source
478 (origin
479 (method url-fetch)
480 (uri (crate-uri "intermediate-b" version))
481 (file-name
482 (string-append name "-" version ".tar.gz"))
483 (sha256
484 (base32
485 (? string? hash)))))
486 (build-system cargo-build-system)
487 (arguments
488 ('quasiquote (#:skip-build? #t
489 #:cargo-inputs
490 (("rust-leaf-bob"
491 ('unquote rust-leaf-bob-3))))))
492 (home-page "http://example.com")
493 (synopsis "summary")
494 (description "summary")
495 (license (list license:expat license:asl2.0))))
496 (define-public 'rust-intermediate-a-1
497 (package
498 (name "rust-intermediate-a")
499 (version "1.0.42")
500 (source
501 (origin
502 (method url-fetch)
503 (uri (crate-uri "intermediate-a" version))
504 (file-name
505 (string-append name "-" version ".tar.gz"))
506 (sha256
507 (base32
508 (? string? hash)))))
509 (build-system cargo-build-system)
510 (arguments
511 ('quasiquote (#:skip-build? #t
512 #:cargo-inputs
513 (("rust-intermediate-b"
514 ('unquote rust-intermediate-b-1))
515 ("rust-leaf-alice"
516 ('unquote 'rust-leaf-alice-0.7))
517 ("rust-leaf-bob"
518 ('unquote rust-leaf-bob-3))))))
519 (home-page "http://example.com")
520 (synopsis "summary")
521 (description "summary")
522 (license (list license:expat license:asl2.0))))
523 (define-public 'rust-root-1
524 (package
525 (name "rust-root")
526 (version "1.0.4")
527 (source
528 (origin
529 (method url-fetch)
530 (uri (crate-uri "root" version))
531 (file-name
532 (string-append name "-" version ".tar.gz"))
533 (sha256
534 (base32
535 (? string? hash)))))
536 (build-system cargo-build-system)
537 (arguments
538 ('quasiquote (#:cargo-inputs
539 (("rust-intermediate-a"
540 ('unquote rust-intermediate-a-1))
541 ("rust-intermediate-b"
542 ('unquote rust-intermediate-b-1))
543 ("rust-leaf-alice"
544 ('unquote 'rust-leaf-alice-0.7))
545 ("rust-leaf-bob"
546 ('unquote rust-leaf-bob-3))))))
547 (home-page "http://example.com")
548 (synopsis "summary")
549 (description "summary")
550 (license (list license:expat license:asl2.0)))))
551 #t)
552 (x
553 (pk 'fail x #f)))))
554
555 (test-equal "licenses: MIT OR Apache-2.0"
556 '(license:expat license:asl2.0)
557 (string->license "MIT OR Apache-2.0"))
558
559 (test-equal "licenses: Apache-2.0 / MIT"
560 '(license:asl2.0 license:expat)
561 (string->license "Apache-2.0 / MIT"))
562
563 (test-equal "licenses: Apache-2.0 WITH LLVM-exception"
564 '(license:asl2.0 unknown-license!)
565 (string->license "Apache-2.0 WITH LLVM-exception"))
566
567 (test-equal "licenses: MIT/Apache-2.0 AND BSD-2-Clause"
568 '(license:expat license:asl2.0 unknown-license!)
569 (string->license "MIT/Apache-2.0 AND BSD-2-Clause"))
570
571 (test-equal "licenses: MIT/Apache-2.0"
572 '(license:expat license:asl2.0)
573 (string->license "MIT/Apache-2.0"))
574
575 (test-end "crate")