diff options
-rw-r--r-- | guix/import/crate.scm | 91 | ||||
-rw-r--r-- | guix/import/utils.scm | 21 | ||||
-rw-r--r-- | guix/scripts/import/crate.scm | 11 | ||||
-rw-r--r-- | tests/crate.scm | 500 |
4 files changed, 391 insertions, 232 deletions
diff --git a/guix/import/crate.scm b/guix/import/crate.scm index 47bfc16105..5498d1f0ff 100644 --- a/guix/import/crate.scm +++ b/guix/import/crate.scm @@ -1,7 +1,7 @@ ;;; GNU Guix --- Functional package management for GNU ;;; Copyright © 2016 David Craven <david@craven.ch> ;;; Copyright © 2019, 2020 Ludovic Courtès <ludo@gnu.org> -;;; Copyright © 2019 Martin Becze <mjbecze@riseup.net> +;;; Copyright © 2019, 2020 Martin Becze <mjbecze@riseup.net> ;;; ;;; This file is part of GNU Guix. ;;; @@ -37,6 +37,7 @@ #:use-module (srfi srfi-1) #:use-module (srfi srfi-2) #:use-module (srfi srfi-26) + #:use-module (srfi srfi-71) #:export (crate->guix-package guix-package->crate-name string->license @@ -85,10 +86,15 @@ crate-dependency? json->crate-dependency (id crate-dependency-id "crate_id") ;string - (kind crate-dependency-kind "kind" ;'normal | 'dev + (kind crate-dependency-kind "kind" ;'normal | 'dev | 'build string->symbol) (requirement crate-dependency-requirement "req")) ;string +(module-autoload! (current-module) + '(semver) '(string->semver semver<?)) +(module-autoload! (current-module) + '(semver ranges) '(string->semver-range semver-range-contains?)) + (define (lookup-crate name) "Look up NAME on https://crates.io and return the corresopnding <crate> record or #f if it was not found." @@ -142,16 +148,21 @@ record or #f if it was not found." `((arguments (,'quasiquote ,args)))))) (define* (make-crate-sexp #:key name version cargo-inputs cargo-development-inputs - home-page synopsis description license - #:allow-other-keys) + home-page synopsis description license) "Return the `package' s-expression for a rust package with the given NAME, VERSION, CARGO-INPUTS, CARGO-DEVELOPMENT-INPUTS, HOME-PAGE, SYNOPSIS, DESCRIPTION, and LICENSE." + (define (format-inputs inputs) + (map + (match-lambda + ((name version) + (list (crate-name->package-name name) version))) + inputs)) + (let* ((port (http-fetch (crate-uri name version))) (guix-name (crate-name->package-name name)) - (cargo-inputs (map crate-name->package-name cargo-inputs)) - (cargo-development-inputs (map crate-name->package-name - cargo-development-inputs)) + (cargo-inputs (format-inputs cargo-inputs)) + (cargo-development-inputs (format-inputs cargo-development-inputs)) (pkg `(package (name ,guix-name) (version ,version) @@ -163,7 +174,8 @@ and LICENSE." (base32 ,(bytevector->nix-base32-string (port-sha256 port)))))) (build-system cargo-build-system) - ,@(maybe-arguments (append (maybe-cargo-inputs cargo-inputs) + ,@(maybe-arguments (append '(#:skip-build? #t) + (maybe-cargo-inputs cargo-inputs) (maybe-cargo-development-inputs cargo-development-inputs))) (home-page ,(match home-page @@ -176,7 +188,7 @@ and LICENSE." ((license) license) (_ `(list ,@license))))))) (close-port port) - pkg)) + (package->definition pkg #t))) (define (string->license string) (filter-map (lambda (license) @@ -190,11 +202,17 @@ and LICENSE." (define* (crate->guix-package crate-name #:key version repo) "Fetch the metadata for CRATE-NAME from crates.io, and return the `package' s-expression corresponding to that package, or #f on failure. -When VERSION is specified, attempt to fetch that version; otherwise fetch the -latest version of CRATE-NAME." +When VERSION is specified, convert it into a semver range and attempt to fetch +the latest version matching this semver range; otherwise fetch the latest +version of CRATE-NAME." + + (define (semver-range-contains-string? range version) + (semver-range-contains? (string->semver-range range) + (string->semver version))) (define (normal-dependency? dependency) - (eq? (crate-dependency-kind dependency) 'normal)) + (or (eq? (crate-dependency-kind dependency) 'build) + (eq? (crate-dependency-kind dependency) 'normal))) (define crate (lookup-crate crate-name)) @@ -204,22 +222,45 @@ latest version of CRATE-NAME." (or version (crate-latest-version crate)))) + ;; find the highest version of a crate that fulfills the semver <range> + (define (find-crate-version crate range) + (let* ((semver-range (string->semver-range range)) + (versions + (sort + (filter (lambda (entry) + (semver-range-contains? semver-range (first entry))) + (map (lambda (ver) + (list (string->semver (crate-version-number ver)) + ver)) + (crate-versions crate))) + (match-lambda* (((semver _) ...) + (apply semver<? semver)))))) + (and (not (null-list? versions)) + (second (last versions))))) + (define version* (and crate - (find (lambda (version) - (string=? (crate-version-number version) - version-number)) - (crate-versions crate)))) + (find-crate-version crate version-number))) + + ;; sort and map the dependencies to a list containing + ;; pairs of (name version) + (define (sort-map-dependencies deps) + (sort (map (lambda (dep) + (let* ((name (crate-dependency-id dep)) + (crate (lookup-crate name)) + (req (crate-dependency-requirement dep)) + (ver (find-crate-version crate req))) + (list name + (crate-version-number ver)))) + deps) + (match-lambda* (((name _) ...) + (apply string-ci<? name))))) (and crate version* - (let* ((dependencies (crate-version-dependencies version*)) - (dep-crates (filter normal-dependency? dependencies)) - (dev-dep-crates (remove normal-dependency? dependencies)) - (cargo-inputs (sort (map crate-dependency-id dep-crates) - string-ci<?)) - (cargo-development-inputs - (sort (map crate-dependency-id dev-dep-crates) - string-ci<?))) + (let* ((dependencies (crate-version-dependencies version*)) + (dep-crates dev-dep-crates (partition normal-dependency? dependencies)) + (cargo-inputs (sort-map-dependencies dep-crates)) + (cargo-development-inputs '())) (values (make-crate-sexp #:name crate-name #:version (crate-version-number version*) @@ -251,7 +292,7 @@ latest version of CRATE-NAME." ((name _ ...) name)))) (define (crate-name->package-name name) - (string-append "rust-" (string-join (string-split name #\_) "-"))) + (guix-name "rust-" name)) ;;; diff --git a/guix/import/utils.scm b/guix/import/utils.scm index 895fbb11a8..10eb030188 100644 --- a/guix/import/utils.scm +++ b/guix/import/utils.scm @@ -229,13 +229,20 @@ into a proper sentence and by using two spaces between sentences." cleaned 'pre ". " 'post))) (define* (package-names->package-inputs names #:optional (output #f)) - "Given a list of PACKAGE-NAMES, and an optional OUTPUT, tries to generate a -quoted list of inputs, as suitable to use in an 'inputs' field of a package -definition." - (map (lambda (input) - (cons* input (list 'unquote (string->symbol input)) - (or (and output (list output)) - '()))) + "Given a list of PACKAGE-NAMES or (PACKAGE-NAME VERSION) pairs, and an +optional OUTPUT, tries to generate a quoted list of inputs, as suitable to +use in an 'inputs' field of a package definition." + (define (make-input input version) + (cons* input (list 'unquote (string->symbol + (if version + (string-append input "-" version) + input))) + (or (and output (list output)) + '()))) + + (map (match-lambda + ((input version) (make-input input version)) + (input (make-input input #f))) names)) (define* (maybe-inputs package-names #:optional (output #f)) diff --git a/guix/scripts/import/crate.scm b/guix/scripts/import/crate.scm index 9c4286f8bd..33dae56561 100644 --- a/guix/scripts/import/crate.scm +++ b/guix/scripts/import/crate.scm @@ -2,7 +2,7 @@ ;;; GNU Guix --- Functional package management for GNU ;;; Copyright © 2014 David Thompson <davet@gnu.org> ;;; Copyright © 2016 David Craven <david@craven.ch> -;;; Copyright © 2019 Martin Becze <mjbecze@riseup.net> +;;; Copyright © 2019, 2020 Martin Becze <mjbecze@riseup.net> ;;; ;;; This file is part of GNU Guix. ;;; @@ -95,19 +95,14 @@ Import and convert the crate.io package for PACKAGE-NAME.\n")) (package-name->name+version spec)) (if (assoc-ref opts 'recursive) - (map (match-lambda - ((and ('package ('name name) . rest) pkg) - `(define-public ,(string->symbol name) - ,pkg)) - (_ #f)) - (crate-recursive-import name #:version version)) + (crate-recursive-import name #:version version) (let ((sexp (crate->guix-package name #:version version))) (unless sexp (leave (G_ "failed to download meta-data for package '~a'~%") (if version (string-append name "@" version) name))) - sexp))) + (list sexp)))) (() (leave (G_ "too few arguments~%"))) ((many ...) diff --git a/tests/crate.scm b/tests/crate.scm index 61a04f986b..4465e12767 100644 --- a/tests/crate.scm +++ b/tests/crate.scm @@ -2,6 +2,7 @@ ;;; Copyright © 2014 David Thompson <davet@gnu.org> ;;; Copyright © 2016 David Craven <david@craven.ch> ;;; Copyright © 2019, 2020 Ludovic Courtès <ludo@gnu.org> +;;; Copyright © 2020 Martin Becze <mjbecze@riseup.net> ;;; ;;; This file is part of GNU Guix. ;;; @@ -28,23 +29,67 @@ #:use-module (ice-9 match) #:use-module (srfi srfi-64)) + +;; crate versions and dependencies used here +;; foo-0.8.1 +;; foo-1.0.0 +;; foo-1.0.3 +;; leaf-alice 0.7.5 +;; +;; root-1.0.0 +;; root-1.0.4 +;; intermediate-a 1.0.42 +;; intermeidate-b ^1.0.0 +;; leaf-alice ^0.7 +;; leaf-bob ^3 +;; +;; intermediate-a-1.0.40 +;; intermediate-a-1.0.42 +;; intermediate-a-1.1.0-alpha.1 +;; intermediate-a 1.2.3 +;; leaf-alice 0.7.5 +;; leaf-bob ^3 +;; +;; intermediate-b-1.2.3 +;; leaf-bob 3.0.1 +;; +;; leaf-alice-0.7.3 +;; leaf-alice-0.7.5 +;; +;; leaf-bob-3.0.1 + + (define test-foo-crate "{ \"crate\": { - \"max_version\": \"1.0.0\", + \"max_version\": \"1.0.3\", \"name\": \"foo\", \"description\": \"summary\", \"homepage\": \"http://example.com\", \"repository\": \"http://example.com\", - \"keywords\": [\"dummy\" \"test\"], - \"categories\": [\"test\"] + \"keywords\": [\"dummy\", \"test\"], + \"categories\": [\"test\"], \"actual_versions\": [ - { \"id\": \"foo\", + { \"id\": 234210, + \"num\": \"0.8.1\", + \"license\": \"MIT OR Apache-2.0\", + \"links\": { + \"dependencies\": \"/api/v1/crates/foo/0.8.1/dependencies\" + } + }, + { \"id\": 234212, \"num\": \"1.0.0\", \"license\": \"MIT OR Apache-2.0\", \"links\": { \"dependencies\": \"/api/v1/crates/foo/1.0.0/dependencies\" } + }, + { \"id\": 234214, + \"num\": \"1.0.3\", + \"license\": \"MIT OR Apache-2.0\", + \"links\": { + \"dependencies\": \"/api/v1/crates/foo/1.0.3/dependencies\" + } } ] } @@ -54,8 +99,9 @@ "{ \"dependencies\": [ { - \"crate_id\": \"bar\", - \"kind\": \"normal\" + \"crate_id\": \"leaf-alice\", + \"kind\": \"normal\", + \"req\": \"0.7.5\" } ] }") @@ -63,20 +109,27 @@ (define test-root-crate "{ \"crate\": { - \"max_version\": \"1.0.0\", + \"max_version\": \"1.0.4\", \"name\": \"root\", \"description\": \"summary\", \"homepage\": \"http://example.com\", \"repository\": \"http://example.com\", - \"keywords\": [\"dummy\" \"test\"], - \"categories\": [\"test\"] + \"keywords\": [\"dummy\", \"test\"], + \"categories\": [\"test\"], \"actual_versions\": [ - { \"id\": \"foo\", + { \"id\": 234240, \"num\": \"1.0.0\", \"license\": \"MIT OR Apache-2.0\", \"links\": { \"dependencies\": \"/api/v1/crates/root/1.0.0/dependencies\" } + }, + { \"id\": 234242, + \"num\": \"1.0.4\", + \"license\": \"MIT OR Apache-2.0\", + \"links\": { + \"dependencies\": \"/api/v1/crates/root/1.0.4/dependencies\" + } } ] } @@ -86,92 +139,114 @@ "{ \"dependencies\": [ { - \"crate_id\": \"intermediate-1\", - \"kind\": \"normal\" + \"crate_id\": \"intermediate-a\", + \"kind\": \"normal\", + \"req\": \"1.0.42\" }, { - \"crate_id\": \"intermediate-2\", - \"kind\": \"normal\" + \"crate_id\": \"intermediate-b\", + \"kind\": \"normal\", + \"req\": \"^1.0.0\" } { \"crate_id\": \"leaf-alice\", - \"kind\": \"normal\" + \"kind\": \"normal\", + \"req\": \"^0.7\" }, { \"crate_id\": \"leaf-bob\", - \"kind\": \"normal\" + \"kind\": \"normal\", + \"req\": \"^3\" } ] }") -(define test-intermediate-1-crate +(define test-intermediate-a-crate "{ \"crate\": { - \"max_version\": \"1.0.0\", - \"name\": \"intermediate-1\", + \"max_version\": \"1.1.0-alpha.1\", + \"name\": \"intermediate-a\", \"description\": \"summary\", \"homepage\": \"http://example.com\", \"repository\": \"http://example.com\", - \"keywords\": [\"dummy\" \"test\"], - \"categories\": [\"test\"] + \"keywords\": [\"dummy\", \"test\"], + \"categories\": [\"test\"], \"actual_versions\": [ - { \"id\": \"intermediate-1\", - \"num\": \"1.0.0\", + { \"id\": 234251, + \"num\": \"1.0.40\", + \"license\": \"MIT OR Apache-2.0\", + \"links\": { + \"dependencies\": \"/api/v1/crates/intermediate-a/1.0.40/dependencies\" + } + }, + { \"id\": 234250, + \"num\": \"1.0.42\", + \"license\": \"MIT OR Apache-2.0\", + \"links\": { + \"dependencies\": \"/api/v1/crates/intermediate-a/1.0.42/dependencies\" + } + }, + { \"id\": 234252, + \"num\": \"1.1.0-alpha.1\", \"license\": \"MIT OR Apache-2.0\", \"links\": { - \"dependencies\": \"/api/v1/crates/intermediate-1/1.0.0/dependencies\" + \"dependencies\": \"/api/v1/crates/intermediate-a/1.1.0-alpha.1/dependencies\" } } ] } }") -(define test-intermediate-1-dependencies +(define test-intermediate-a-dependencies "{ \"dependencies\": [ { - \"crate_id\": \"intermediate-2\", - \"kind\": \"normal\" + \"crate_id\": \"intermediate-b\", + \"kind\": \"normal\", + \"req\": \"1.2.3\" }, { \"crate_id\": \"leaf-alice\", - \"kind\": \"normal\" + \"kind\": \"normal\", + \"req\": \"0.7.5\" }, { \"crate_id\": \"leaf-bob\", - \"kind\": \"normal\" + \"kind\": \"normal\", + \"req\": \"^3\" } ] }") -(define test-intermediate-2-crate +(define test-intermediate-b-crate "{ \"crate\": { - \"max_version\": \"1.0.0\", - \"name\": \"intermediate-2\", + \"max_version\": \"1.2.3\", + \"name\": \"intermediate-b\", \"description\": \"summary\", \"homepage\": \"http://example.com\", \"repository\": \"http://example.com\", - \"keywords\": [\"dummy\" \"test\"], - \"categories\": [\"test\"] + \"keywords\": [\"dummy\", \"test\"], + \"categories\": [\"test\"], \"actual_versions\": [ - { \"id\": \"intermediate-2\", - \"num\": \"1.0.0\", + { \"id\": 234260, + \"num\": \"1.2.3\", \"license\": \"MIT OR Apache-2.0\", \"links\": { - \"dependencies\": \"/api/v1/crates/intermediate-2/1.0.0/dependencies\" + \"dependencies\": \"/api/v1/crates/intermediate-b/1.2.3/dependencies\" } } ] } }") -(define test-intermediate-2-dependencies +(define test-intermediate-b-dependencies "{ \"dependencies\": [ { \"crate_id\": \"leaf-bob\", - \"kind\": \"normal\" + \"kind\": \"normal\", + \"req\": \"3.0.1\" } ] }") @@ -179,19 +254,26 @@ (define test-leaf-alice-crate "{ \"crate\": { - \"max_version\": \"1.0.0\", + \"max_version\": \"0.7.5\", \"name\": \"leaf-alice\", \"description\": \"summary\", \"homepage\": \"http://example.com\", \"repository\": \"http://example.com\", - \"keywords\": [\"dummy\" \"test\"], - \"categories\": [\"test\"] + \"keywords\": [\"dummy\", \"test\"], + \"categories\": [\"test\"], \"actual_versions\": [ - { \"id\": \"leaf-alice\", - \"num\": \"1.0.0\", + { \"id\": 234270, + \"num\": \"0.7.3\", \"license\": \"MIT OR Apache-2.0\", \"links\": { - \"dependencies\": \"/api/v1/crates/leaf-alice/1.0.0/dependencies\" + \"dependencies\": \"/api/v1/crates/leaf-alice/0.7.3/dependencies\" + } + }, + { \"id\": 234272, + \"num\": \"0.7.5\", + \"license\": \"MIT OR Apache-2.0\", + \"links\": { + \"dependencies\": \"/api/v1/crates/leaf-alice/0.7.5/dependencies\" } } ] @@ -206,19 +288,19 @@ (define test-leaf-bob-crate "{ \"crate\": { - \"max_version\": \"1.0.0\", + \"max_version\": \"3.0.1\", \"name\": \"leaf-bob\", \"description\": \"summary\", \"homepage\": \"http://example.com\", \"repository\": \"http://example.com\", - \"keywords\": [\"dummy\" \"test\"], + \"keywords\": [\"dummy\", \"test\"], \"categories\": [\"test\"] \"actual_versions\": [ - { \"id\": \"leaf-bob\", - \"num\": \"1.0.0\", + { \"id\": 234280, + \"num\": \"3.0.1\", \"license\": \"MIT OR Apache-2.0\", \"links\": { - \"dependencies\": \"/api/v1/crates/leaf-bob/1.0.0/dependencies\" + \"dependencies\": \"/api/v1/crates/leaf-bob/3.0.1/dependencies\" } } ] @@ -251,36 +333,51 @@ (match url ("https://crates.io/api/v1/crates/foo" (open-input-string test-foo-crate)) - ("https://crates.io/api/v1/crates/foo/1.0.0/download" + ("https://crates.io/api/v1/crates/foo/1.0.3/download" (set! test-source-hash - (bytevector->nix-base32-string - (sha256 (string->bytevector "empty file\n" "utf-8")))) + (bytevector->nix-base32-string + (sha256 (string->bytevector "empty file\n" "utf-8")))) (open-input-string "empty file\n")) - ("https://crates.io/api/v1/crates/foo/1.0.0/dependencies" + ("https://crates.io/api/v1/crates/foo/1.0.3/dependencies" (open-input-string test-foo-dependencies)) + ("https://crates.io/api/v1/crates/leaf-alice" + (open-input-string test-leaf-alice-crate)) + ("https://crates.io/api/v1/crates/leaf-alice/0.7.5/download" + (set! test-source-hash + (bytevector->nix-base32-string + (sha256 (string->bytevector "empty file\n" "utf-8")))) + (open-input-string "empty file\n")) + ("https://crates.io/api/v1/crates/leaf-alice/0.7.5/dependencies" + (open-input-string test-leaf-alice-dependencies)) (_ (error "Unexpected URL: " url))))) - (match (crate->guix-package "foo") - (('package - ('name "rust-foo") - ('version "1.0.0") - ('source ('origin - ('method 'url-fetch) - ('uri ('crate-uri "foo" 'version)) - ('file-name ('string-append 'name "-" 'version ".tar.gz")) - ('sha256 - ('base32 - (? string? hash))))) - ('build-system 'cargo-build-system) - ('arguments - ('quasiquote - ('#:cargo-inputs (("rust-bar" ('unquote rust-bar)))))) - ('home-page "http://example.com") - ('synopsis "summary") - ('description "summary") - ('license ('list 'license:expat 'license:asl2.0))) - (string=? test-source-hash hash)) - (x - (pk 'fail x #f))))) + + (match (crate->guix-package "foo") + ((define-public 'rust-foo-1.0.3 + (package (name "rust-foo") + (version "1.0.3") + (source + (origin + (method url-fetch) + (uri (crate-uri "foo" 'version)) + (file-name (string-append name "-" version ".tar.gz")) + (sha256 + (base32 + (? string? hash))))) + (build-system 'cargo-build-system) + (arguments + ('quasiquote + (#:skip-build? #t + #:cargo-inputs + (("rust-leaf-alice" + ('unquote 'rust-leaf-alice-0.7.5)))))) + (home-page "http://example.com") + (synopsis "summary") + (description "summary") + (license (list license:expat license:asl2.0)))) + + (string=? test-source-hash hash)) + (x + (pk 'fail x #f))))) (test-assert "cargo-recursive-import" ;; Replace network resources with sample data. @@ -289,151 +386,170 @@ (match url ("https://crates.io/api/v1/crates/root" (open-input-string test-root-crate)) - ("https://crates.io/api/v1/crates/root/1.0.0/download" + ("https://crates.io/api/v1/crates/root/1.0.4/download" (set! test-source-hash (bytevector->nix-base32-string (sha256 (string->bytevector "empty file\n" "utf-8")))) (open-input-string "empty file\n")) - ("https://crates.io/api/v1/crates/root/1.0.0/dependencies" + ("https://crates.io/api/v1/crates/root/1.0.4/dependencies" (open-input-string test-root-dependencies)) - ("https://crates.io/api/v1/crates/intermediate-1" - (open-input-string test-intermediate-1-crate)) - ("https://crates.io/api/v1/crates/intermediate-1/1.0.0/download" + ("https://crates.io/api/v1/crates/intermediate-a" + (open-input-string test-intermediate-a-crate)) + ("https://crates.io/api/v1/crates/intermediate-a/1.0.42/download" (set! test-source-hash (bytevector->nix-base32-string (sha256 (string->bytevector "empty file\n" "utf-8")))) (open-input-string "empty file\n")) - ("https://crates.io/api/v1/crates/intermediate-1/1.0.0/dependencies" - (open-input-string test-intermediate-1-dependencies)) - ("https://crates.io/api/v1/crates/intermediate-2" - (open-input-string test-intermediate-2-crate)) - ("https://crates.io/api/v1/crates/intermediate-2/1.0.0/download" + ("https://crates.io/api/v1/crates/intermediate-a/1.0.42/dependencies" + (open-input-string test-intermediate-a-dependencies)) + ("https://crates.io/api/v1/crates/intermediate-b" + (open-input-string test-intermediate-b-crate)) + ("https://crates.io/api/v1/crates/intermediate-b/1.2.3/download" (set! test-source-hash (bytevector->nix-base32-string (sha256 (string->bytevector "empty file\n" "utf-8")))) (open-input-string "empty file\n")) - ("https://crates.io/api/v1/crates/intermediate-2/1.0.0/dependencies" - (open-input-string test-intermediate-2-dependencies)) + ("https://crates.io/api/v1/crates/intermediate-b/1.2.3/dependencies" + (open-input-string test-intermediate-b-dependencies)) ("https://crates.io/api/v1/crates/leaf-alice" (open-input-string test-leaf-alice-crate)) - ("https://crates.io/api/v1/crates/leaf-alice/1.0.0/download" + ("https://crates.io/api/v1/crates/leaf-alice/0.7.5/download" (set! test-source-hash (bytevector->nix-base32-string (sha256 (string->bytevector "empty file\n" "utf-8")))) (open-input-string "empty file\n")) - ("https://crates.io/api/v1/crates/leaf-alice/1.0.0/dependencies" + ("https://crates.io/api/v1/crates/leaf-alice/0.7.5/dependencies" (open-input-string test-leaf-alice-dependencies)) ("https://crates.io/api/v1/crates/leaf-bob" (open-input-string test-leaf-bob-crate)) - ("https://crates.io/api/v1/crates/leaf-bob/1.0.0/download" + ("https://crates.io/api/v1/crates/leaf-bob/3.0.1/download" (set! test-source-hash (bytevector->nix-base32-string (sha256 (string->bytevector "empty file\n" "utf-8")))) (open-input-string "empty file\n")) - ("https://crates.io/api/v1/crates/leaf-bob/1.0.0/dependencies" + ("https://crates.io/api/v1/crates/leaf-bob/3.0.1/dependencies" (open-input-string test-leaf-bob-dependencies)) (_ (error "Unexpected URL: " url))))) (match (crate-recursive-import "root") - ;; rust-intermediate-2 has no dependency on the rust-leaf-alice package, so this is a valid ordering - ((('package - ('name "rust-leaf-alice") - ('version (? string? ver)) - ('source - ('origin - ('method 'url-fetch) - ('uri ('crate-uri "leaf-alice" 'version)) - ('file-name - ('string-append 'name "-" 'version ".tar.gz")) - ('sha256 - ('base32 - (? string? hash))))) - ('build-system 'cargo-build-system) - ('home-page "http://example.com") - ('synopsis "summary") - ('description "summary") - ('license ('list 'license:expat 'license:asl2.0))) - ('package - ('name "rust-leaf-bob") - ('version (? string? ver)) - ('source - ('origin - ('method 'url-fetch) - ('uri ('crate-uri "leaf-bob" 'version)) - ('file-name - ('string-append 'name "-" 'version ".tar.gz")) - ('sha256 - ('base32 - (? string? hash))))) - ('build-system 'cargo-build-system) - ('home-page "http://example.com") - ('synopsis "summary") - ('description "summary") - ('license ('list 'license:expat 'license:asl2.0))) - ('package - ('name "rust-intermediate-2") - ('version (? string? ver)) - ('source - ('origin - ('method 'url-fetch) - ('uri ('crate-uri "intermediate-2" 'version)) - ('file-name - ('string-append 'name "-" 'version ".tar.gz")) - ('sha256 - ('base32 - (? string? hash))))) - ('build-system 'cargo-build-system) - ('arguments - ('quasiquote - ('#:cargo-inputs (("rust-leaf-bob" ('unquote rust-leaf-bob)))))) - ('home-page "http://example.com") - ('synopsis "summary") - ('description "summary") - ('license ('list 'license:expat 'license:asl2.0))) - ('package - ('name "rust-intermediate-1") - ('version (? string? ver)) - ('source - ('origin - ('method 'url-fetch) - ('uri ('crate-uri "intermediate-1" 'version)) - ('file-name - ('string-append 'name "-" 'version ".tar.gz")) - ('sha256 - ('base32 - (? string? hash))))) - ('build-system 'cargo-build-system) - ('arguments - ('quasiquote - ('#:cargo-inputs (("rust-intermediate-2" ('unquote rust-intermediate-2)) - ("rust-leaf-alice" ('unquote rust-leaf-alice)) - ("rust-leaf-bob" ('unquote rust-leaf-bob)))))) - ('home-page "http://example.com") - ('synopsis "summary") - ('description "summary") - ('license ('list 'license:expat 'license:asl2.0))) - ('package - ('name "rust-root") - ('version (? string? ver)) - ('source - ('origin - ('method 'url-fetch) - ('uri ('crate-uri "root" 'version)) - ('file-name - ('string-append 'name "-" 'version ".tar.gz")) - ('sha256 - ('base32 - (? string? hash))))) - ('build-system 'cargo-build-system) - ('arguments - ('quasiquote - ('#:cargo-inputs (("rust-intermediate-1" ('unquote rust-intermediate-1)) - ("rust-intermediate-2" ('unquote rust-intermediate-2)) - ("rust-leaf-alice" ('unquote rust-leaf-alice)) - ("rust-leaf-bob" ('unquote rust-leaf-bob)))))) - ('home-page "http://example.com") - ('synopsis "summary") - ('description "summary") - ('license ('list 'license:expat 'license:asl2.0)))) + ;; rust-intermediate-b has no dependency on the rust-leaf-alice + ;; package, so this is a valid ordering + (((define-public 'rust-leaf-alice-0.7.5 + (package + (name "rust-leaf-alice") + (version "0.7.5") + (source + (origin + (method url-fetch) + (uri (crate-uri "leaf-alice" version)) + (file-name + (string-append name "-" version ".tar.gz")) + (sha256 + (base32 + (? string? hash))))) + (build-system cargo-build-system) + (arguments ('quasiquote (#:skip-build? #t))) + (home-page "http://example.com") + (synopsis "summary") + (description "summary") + (license (list license:expat license:asl2.0)))) + (define-public 'rust-leaf-bob-3.0.1 + (package + (name "rust-leaf-bob") + (version "3.0.1") + (source + (origin + (method url-fetch) + (uri (crate-uri "leaf-bob" version)) + (file-name + (string-append name "-" version ".tar.gz")) + (sha256 + (base32 + (? string? hash))))) + (build-system cargo-build-system) + (arguments ('quasiquote (#:skip-build? #t))) + (home-page "http://example.com") + (synopsis "summary") + (description "summary") + (license (list license:expat license:asl2.0)))) + (define-public 'rust-intermediate-b-1.2.3 + (package + (name "rust-intermediate-b") + (version "1.2.3") + (source + (origin + (method url-fetch) + (uri (crate-uri "intermediate-b" version)) + (file-name + (string-append name "-" version ".tar.gz")) + (sha256 + (base32 + (? string? hash))))) + (build-system cargo-build-system) + (arguments + ('quasiquote (#:skip-build? #t + #:cargo-inputs + (("rust-leaf-bob" + ('unquote 'rust-leaf-bob-3.0.1)))))) + (home-page "http://example.com") + (synopsis "summary") + (description "summary") + (license (list license:expat license:asl2.0)))) + (define-public 'rust-intermediate-a-1.0.42 + (package + (name "rust-intermediate-a") + (version "1.0.42") + (source + (origin + (method url-fetch) + (uri (crate-uri "intermediate-a" version)) + (file-name + (string-append name "-" version ".tar.gz")) + (sha256 + (base32 + (? string? hash))))) + (build-system cargo-build-system) + (arguments + ('quasiquote (#:skip-build? #t + #:cargo-inputs + (("rust-intermediate-b" + ('unquote 'rust-intermediate-b-1.2.3)) + ("rust-leaf-alice" + ('unquote 'rust-leaf-alice-0.7.5)) + ("rust-leaf-bob" + ('unquote 'rust-leaf-bob-3.0.1)))))) + (home-page "http://example.com") + (synopsis "summary") + (description "summary") + (license (list license:expat license:asl2.0)))) + (define-public 'rust-root-1.0.4 + (package + (name "rust-root") + (version "1.0.4") + (source + (origin + (method url-fetch) + (uri (crate-uri "root" version)) + (file-name + (string-append name "-" version ".tar.gz")) + (sha256 + (base32 + (? string? hash))))) + (build-system cargo-build-system) + (arguments + ('quasiquote (#:skip-build? #t + #:cargo-inputs + (("rust-intermediate-a" + ('unquote 'rust-intermediate-a-1.0.42)) + ("rust-intermediate-b" + ('unquote 'rust-intermediate-b-1.2.3)) + ("rust-leaf-alice" + ('unquote 'rust-leaf-alice-0.7.5)) + ("rust-leaf-bob" + ('unquote 'rust-leaf-bob-3.0.1)))))) + (home-page "http://example.com") + (synopsis "summary") + (description "summary") + (license (list license:expat license:asl2.0))))) #t) (x (pk 'fail x #f))))) |