@@ -32,6 +32,7 @@
#:use-module (guix packages)
#:use-module (guix upstream)
#:use-module (guix utils)
+ #:use-module (gnu packages)
#:use-module (ice-9 match)
#:use-module (ice-9 regex)
#:use-module (json)
@@ -92,7 +93,7 @@
(requirement crate-dependency-requirement "req")) ;string
(module-autoload! (current-module)
- '(semver) '(string->semver semver<?))
+ '(semver) '(string->semver semver->string semver<?))
(module-autoload! (current-module)
'(semver ranges) '(string->semver-range semver-range-contains?))
@@ -235,6 +236,21 @@ look up the development dependencs for the given crate."
(or version
(crate-latest-version crate))))
+ ;; find the highest existing package that fulfills the semver <range>
+ (define (find-package-version name range)
+ (let* ((semver-range (string->semver-range range))
+ (versions
+ (sort
+ (filter (lambda (version)
+ (semver-range-contains? semver-range version))
+ (map (lambda (pkg)
+ (string->semver (package-version pkg)))
+ (find-packages-by-name
+ (crate-name->package-name name))))
+ semver<?)))
+ (and (not (null-list? versions))
+ (semver->string (last versions)))))
+
;; 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))
@@ -251,6 +267,17 @@ look up the development dependencs for the given crate."
(and (not (null-list? versions))
(second (last versions)))))
+ (define (dependency-name+version dep)
+ (let* ((name (crate-dependency-id dep))
+ (req (crate-dependency-requirement dep))
+ (existing-version (find-package-version name req)))
+ (if existing-version
+ (list name existing-version)
+ (let* ((crate (lookup-crate* name))
+ (ver (find-crate-version crate req)))
+ (list name
+ (crate-version-number ver))))))
+
(define version*
(and crate
(find-crate-version crate version-number)))
@@ -258,13 +285,7 @@ look up the development dependencs for the given crate."
;; 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))))
+ (sort (map dependency-name+version
deps)
(match-lambda* (((name _) ...)
(apply string-ci<? name)))))
@@ -25,6 +25,7 @@
#:use-module (guix build-system cargo)
#:use-module (gcrypt hash)
#:use-module (guix tests)
+ #:use-module (gnu packages)
#:use-module (ice-9 iconv)
#:use-module (ice-9 match)
#:use-module (srfi srfi-64))
@@ -312,6 +313,7 @@
\"dependencies\": []
}")
+
(define test-source-hash
"")
@@ -572,4 +574,85 @@
'(license:expat license:asl2.0)
(string->license "MIT/Apache-2.0"))
+
+
+(define test-doctool-crate
+ "{
+ \"crate\": {
+ \"max_version\": \"2.2.2\",
+ \"name\": \"leaf-bob\",
+ \"description\": \"summary\",
+ \"homepage\": \"http://example.com\",
+ \"repository\": \"http://example.com\",
+ \"keywords\": [\"dummy\", \"test\"],
+ \"categories\": [\"test\"]
+ \"actual_versions\": [
+ { \"id\": 234280,
+ \"num\": \"2.2.2\",
+ \"license\": \"MIT OR Apache-2.0\",
+ \"links\": {
+ \"dependencies\": \"/api/v1/crates/doctool/2.2.2/dependencies\"
+ }
+ }
+ ]
+ }
+}")
+
+;; FIXME: This test depends on some existing packages
+(define test-doctool-dependencies
+ "{
+ \"dependencies\": [
+ {
+ \"crate_id\": \"docopt\",
+ \"kind\": \"normal\",
+ \"req\": \"^0.8.1\"
+ }
+ ]
+}")
+
+
+(test-assert "self-test: rust-docopt 0.8.x is gone, please adjust the test case"
+ (not (null? (find-packages-by-name "rust-docopt" "0.8"))))
+
+(test-assert "cargo-recursive-import-hoors-existing-packages"
+ (mock ((guix http-client) http-fetch
+ (lambda (url . rest)
+ (match url
+ ("https://crates.io/api/v1/crates/doctool"
+ (open-input-string test-doctool-crate))
+ ("https://crates.io/api/v1/crates/doctool/2.2.2/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/doctool/2.2.2/dependencies"
+ (open-input-string test-doctool-dependencies))
+ (_ (error "Unexpected URL: " url)))))
+ (match (crate-recursive-import "doctool")
+ (((define-public 'rust-doctool-2
+ (package
+ (name "rust-doctool")
+ (version "2.2.2")
+ (source
+ (origin
+ (method url-fetch)
+ (uri (crate-uri "doctool" version))
+ (file-name
+ (string-append name "-" version ".tar.gz"))
+ (sha256
+ (base32
+ (? string? hash)))))
+ (build-system cargo-build-system)
+ (arguments
+ ('quasiquote (#:cargo-inputs
+ (("rust-docopt"
+ ('unquote 'rust-docopt-0.8))))))
+ (home-page "http://example.com")
+ (synopsis "summary")
+ (description "summary")
+ (license (list license:expat license:asl2.0)))))
+ #t)
+ (x
+ (pk 'fail x #f)))))
+
(test-end "crate")