import: crate: Optionally import dev-dependencies recursively.

If --recursive-dev-dependencies is specified, development dependencies
are also included for all recursively imported packages.

* doc/guix.texi (Invoking guix import): Mention --recursive-dev-dependencies.
* guix/import/crate.scm (crate-recursive-import): Add
recursive-dev-dependencies? argument.
* guix/scripts/import/crate.scm (show-help, guix-import-crate): Add
"--recursive-dev-dependencies".
* tests/crate.scm: Test both #f and #t for #:recursive-dev-dependencies?
in the 'cargo-recursive-import' test.
(test-root-dependencies): Add intermediate-c as dev-dependency.
(test-intermediate-c-crate, test-intermediate-c-dependencies): New
variables.

Signed-off-by: Efraim Flashner <efraim@flashner.co.il>
Change-Id: Iae89794681155d77f128733120e60f03bc297717
This commit is contained in:
David Elsing 2023-12-21 22:01:50 +00:00 committed by Efraim Flashner
parent 4b0aa65c0a
commit 9f44ff2bb4
No known key found for this signature in database
GPG key ID: 41AAE7DCCA3D8351
4 changed files with 244 additions and 7 deletions

View file

@ -14585,6 +14585,10 @@ Additional options include:
Traverse the dependency graph of the given upstream package recursively Traverse the dependency graph of the given upstream package recursively
and generate package expressions for all those packages that are not yet and generate package expressions for all those packages that are not yet
in Guix. in Guix.
@item --recursive-dev-dependencies
If @option{--recursive-dev-dependencies} is specified, also the recursively
imported packages contain their development dependencies, which are recursively
imported as well.
@end table @end table
@item elm @item elm

View file

@ -328,14 +328,17 @@ (define (sort-map-dependencies deps)
(append cargo-inputs cargo-development-inputs))) (append cargo-inputs cargo-development-inputs)))
(values #f '()))) (values #f '())))
(define* (crate-recursive-import crate-name #:key version) (define* (crate-recursive-import
crate-name #:key version recursive-dev-dependencies?)
(recursive-import (recursive-import
crate-name crate-name
#:repo->guix-package #:repo->guix-package
(let ((crate->guix-package* (memoize crate->guix-package))) (let ((crate->guix-package* (memoize crate->guix-package)))
(lambda* params (lambda* params
;; download development dependencies only for the top level package ;; download development dependencies only for the top level package
(let ((include-dev-deps? (equal? (car params) crate-name))) (let ((include-dev-deps?
(or (equal? (car params) crate-name)
recursive-dev-dependencies?)))
(apply crate->guix-package* (apply crate->guix-package*
(append params `(#:include-dev-deps? ,include-dev-deps?)))))) (append params `(#:include-dev-deps? ,include-dev-deps?))))))
#:version version #:version version

View file

@ -5,6 +5,7 @@
;;; Copyright © 2019, 2020 Martin Becze <mjbecze@riseup.net> ;;; Copyright © 2019, 2020 Martin Becze <mjbecze@riseup.net>
;;; Copyright © 2021 Sarah Morgensen <iskarian@mgsn.dev> ;;; Copyright © 2021 Sarah Morgensen <iskarian@mgsn.dev>
;;; Copyright © 2023 Simon Tournier <zimon.toutoune@gmail.com> ;;; Copyright © 2023 Simon Tournier <zimon.toutoune@gmail.com>
;;; Copyright © 2023 David Elsing <david.elsing@posteo.net>
;;; ;;;
;;; This file is part of GNU Guix. ;;; This file is part of GNU Guix.
;;; ;;;
@ -47,6 +48,9 @@ (define (show-help)
Import and convert the crates.io package for PACKAGE-NAME.\n")) Import and convert the crates.io package for PACKAGE-NAME.\n"))
(display (G_ " (display (G_ "
-r, --recursive import packages recursively")) -r, --recursive import packages recursively"))
(display (G_ "
--recursive-dev-dependencies
include dev-dependencies recursively"))
(newline) (newline)
(display (G_ " (display (G_ "
-h, --help display this help and exit")) -h, --help display this help and exit"))
@ -67,6 +71,9 @@ (define %options
(option '(#\r "recursive") #f #f (option '(#\r "recursive") #f #f
(lambda (opt name arg result) (lambda (opt name arg result)
(alist-cons 'recursive #t result))) (alist-cons 'recursive #t result)))
(option '("recursive-dev-dependencies") #f #f
(lambda (opt name arg result)
(alist-cons 'recursive-dev-dependencies #t result)))
%standard-import-options)) %standard-import-options))
@ -92,7 +99,10 @@ (define-values (name version)
(package-name->name+version spec)) (package-name->name+version spec))
(match (if (assoc-ref opts 'recursive) (match (if (assoc-ref opts 'recursive)
(crate-recursive-import name #:version version) (crate-recursive-import
name #:version version
#:recursive-dev-dependencies?
(assoc-ref opts 'recursive-dev-dependencies))
(crate->guix-package name #:version version #:include-dev-deps? #t)) (crate->guix-package name #:version version #:include-dev-deps? #t))
((or #f '()) ((or #f '())
(leave (G_ "failed to download meta-data for package '~a'~%") (leave (G_ "failed to download meta-data for package '~a'~%")

View file

@ -4,6 +4,7 @@
;;; Copyright © 2019, 2020, 2022 Ludovic Courtès <ludo@gnu.org> ;;; Copyright © 2019, 2020, 2022 Ludovic Courtès <ludo@gnu.org>
;;; Copyright © 2020 Martin Becze <mjbecze@riseup.net> ;;; Copyright © 2020 Martin Becze <mjbecze@riseup.net>
;;; Copyright © 2023 Efraim Flashner <efraim@flashner.co.il> ;;; Copyright © 2023 Efraim Flashner <efraim@flashner.co.il>
;;; Copyright © 2023 David Elsing <david.elsing@posteo.net>
;;; ;;;
;;; This file is part of GNU Guix. ;;; This file is part of GNU Guix.
;;; ;;;
@ -40,10 +41,11 @@ (define-module (test-crate)
;; ;;
;; root-1.0.0 ;; root-1.0.0
;; root-1.0.4 ;; root-1.0.4
;; intermediate-a 1.0.42 ;; intermediate-a 1.0.42
;; intermeidate-b ^1.0.0 ;; intermediate-b ^1.0.0
;; leaf-alice ^0.7 ;; leaf-alice ^0.7
;; leaf-bob ^3 ;; leaf-bob ^3
;; intermediate-c 1 (dev-dependency)
;; ;;
;; intermediate-a-1.0.40 ;; intermediate-a-1.0.40
;; intermediate-a-1.0.42 ;; intermediate-a-1.0.42
@ -55,6 +57,9 @@ (define-module (test-crate)
;; intermediate-b-1.2.3 ;; intermediate-b-1.2.3
;; leaf-bob 3.0.1 ;; leaf-bob 3.0.1
;; ;;
;; intermediate-c-1.0.1
;; leaf-alice 0.7.5 (dev-dependency)
;;
;; leaf-alice-0.7.3 ;; leaf-alice-0.7.3
;; leaf-alice-0.7.5 ;; leaf-alice-0.7.5
;; ;;
@ -164,6 +169,11 @@ (define test-root-dependencies
\"crate_id\": \"leaf-bob\", \"crate_id\": \"leaf-bob\",
\"kind\": \"normal\", \"kind\": \"normal\",
\"req\": \"^3\" \"req\": \"^3\"
},
{
\"crate_id\": \"intermediate-c\",
\"kind\": \"dev\",
\"req\": \"1\"
} }
] ]
}") }")
@ -262,6 +272,40 @@ (define test-intermediate-b-dependencies
] ]
}") }")
(define test-intermediate-c-crate
"{
\"crate\": {
\"max_version\": \"1.0.1\",
\"name\": \"intermediate-c\",
\"description\": \"summary\",
\"homepage\": \"http://example.com\",
\"repository\": \"http://example.com\",
\"keywords\": [\"dummy\", \"test\"],
\"categories\": [\"test\"],
\"actual_versions\": [
{ \"id\": 234290,
\"num\": \"1.0.1\",
\"license\": \"MIT OR Apache-2.0\",
\"links\": {
\"dependencies\": \"/api/v1/crates/intermediate-c/1.0.1/dependencies\"
},
\"yanked\": false
}
]
}
}")
(define test-intermediate-c-dependencies
"{
\"dependencies\": [
{
\"crate_id\": \"leaf-alice\",
\"kind\": \"dev\",
\"req\": \"0.7.5\"
}
]
}")
(define test-leaf-alice-crate (define test-leaf-alice-crate
"{ "{
\"crate\": { \"crate\": {
@ -430,6 +474,15 @@ (define have-guile-semver?
(open-input-string "empty file\n")) (open-input-string "empty file\n"))
("https://crates.io/api/v1/crates/intermediate-b/1.2.3/dependencies" ("https://crates.io/api/v1/crates/intermediate-b/1.2.3/dependencies"
(open-input-string test-intermediate-b-dependencies)) (open-input-string test-intermediate-b-dependencies))
("https://crates.io/api/v1/crates/intermediate-c"
(open-input-string test-intermediate-c-crate))
("https://crates.io/api/v1/crates/intermediate-c/1.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/intermediate-c/1.0.1/dependencies"
(open-input-string test-intermediate-c-dependencies))
("https://crates.io/api/v1/crates/leaf-alice" ("https://crates.io/api/v1/crates/leaf-alice"
(open-input-string test-leaf-alice-crate)) (open-input-string test-leaf-alice-crate))
("https://crates.io/api/v1/crates/leaf-alice/0.7.5/download" ("https://crates.io/api/v1/crates/leaf-alice/0.7.5/download"
@ -452,7 +505,27 @@ (define have-guile-semver?
(match (crate-recursive-import "root") (match (crate-recursive-import "root")
;; rust-intermediate-b has no dependency on the rust-leaf-alice ;; rust-intermediate-b has no dependency on the rust-leaf-alice
;; package, so this is a valid ordering ;; package, so this is a valid ordering
(((define-public 'rust-leaf-alice-0.7 (((define-public 'rust-intermediate-c-1
(package
(name "rust-intermediate-c")
(version "1.0.1")
(source
(origin
(method url-fetch)
(uri (crate-uri "intermediate-c" 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-alice-0.7
(package (package
(name "rust-leaf-alice") (name "rust-leaf-alice")
(version "0.7.5") (version "0.7.5")
@ -563,10 +636,157 @@ (define-public 'rust-root-1
("rust-leaf-alice" ("rust-leaf-alice"
('unquote 'rust-leaf-alice-0.7)) ('unquote 'rust-leaf-alice-0.7))
("rust-leaf-bob" ("rust-leaf-bob"
('unquote rust-leaf-bob-3)))
#:cargo-development-inputs
(("rust-intermediate-c"
('unquote rust-intermediate-c-1))))))
(home-page "http://example.com")
(synopsis "summary")
(description "summary")
(license (list license:expat license:asl2.0)))))
#t)
(x
(pk 'fail x #f)))
(match (crate-recursive-import "root"
#:recursive-dev-dependencies? #t)
;; rust-intermediate-b has no dependency on the rust-leaf-alice
;; package, so this is a valid ordering
(((define-public 'rust-intermediate-c-1
(package
(name "rust-intermediate-c")
(version "1.0.1")
(source
(origin
(method url-fetch)
(uri (crate-uri "intermediate-c" version))
(file-name
(string-append name "-" version ".tar.gz"))
(sha256
(base32
(? string? hash)))))
(build-system cargo-build-system)
(arguments
('quasiquote (#:cargo-development-inputs
(("rust-leaf-alice"
('unquote rust-leaf-alice-0.7))))))
(home-page "http://example.com")
(synopsis "summary")
(description "summary")
(license (list license:expat license:asl2.0))))
(define-public 'rust-leaf-alice-0.7
(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)
(home-page "http://example.com")
(synopsis "summary")
(description "summary")
(license (list license:expat license:asl2.0))))
(define-public 'rust-leaf-bob-3
(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)
(home-page "http://example.com")
(synopsis "summary")
(description "summary")
(license (list license:expat license:asl2.0))))
(define-public 'rust-intermediate-b-1
(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 (#:cargo-inputs
(("rust-leaf-bob"
('unquote rust-leaf-bob-3)))))) ('unquote rust-leaf-bob-3))))))
(home-page "http://example.com") (home-page "http://example.com")
(synopsis "summary") (synopsis "summary")
(description "summary") (description "summary")
(license (list license:expat license:asl2.0))))
(define-public 'rust-intermediate-a-1
(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 (#:cargo-inputs
(("rust-intermediate-b"
('unquote rust-intermediate-b-1))
("rust-leaf-alice"
('unquote 'rust-leaf-alice-0.7))
("rust-leaf-bob"
('unquote rust-leaf-bob-3))))))
(home-page "http://example.com")
(synopsis "summary")
(description "summary")
(license (list license:expat license:asl2.0))))
(define-public 'rust-root-1
(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 (#:cargo-inputs
(("rust-intermediate-a"
('unquote rust-intermediate-a-1))
("rust-intermediate-b"
('unquote rust-intermediate-b-1))
("rust-leaf-alice"
('unquote 'rust-leaf-alice-0.7))
("rust-leaf-bob"
('unquote rust-leaf-bob-3)))
#:cargo-development-inputs
(("rust-intermediate-c"
('unquote rust-intermediate-c-1))))))
(home-page "http://example.com")
(synopsis "summary")
(description "summary")
(license (list license:expat license:asl2.0))))) (license (list license:expat license:asl2.0)))))
#t) #t)
(x (x