[bug#77093,rust-team,v3,16/17] import: crate: Add ‘--lockfile’ option.
Commit Message
* guix/scripts/import/crate.scm (%options): Add ‘--lockfile’ option.
* guix/scripts/import/crate.scm (show-help): Add it.
(guix-import-crate): Use it.
* doc/guix.texi (Invoking guix import): Document it.
* tests/crate.scm (temp-file): New variable.
("crate-lockfile-import"): New test.
Change-Id: I291478e04adf9f2df0bf216425a5e8aeba0bedd9
---
doc/guix.texi | 14 ++++++
guix/scripts/import/crate.scm | 58 +++++++++++++++++++----
tests/crate.scm | 88 +++++++++++++++++++++++++++++++++++
3 files changed, 150 insertions(+), 10 deletions(-)
@@ -14703,6 +14703,20 @@ Invoking guix import
If a crate dependency is not (yet) packaged, make the corresponding
input in @code{#:cargo-inputs} or @code{#:cargo-development-inputs} into
a comment.
+@item --lockfile=@var{file}
+@itemx -f @var{file}
+When @option{--lockfile} is specified, the importer will ignore other options
+and won't output package definitions, instead generating source definitions for
+all dependencies in @var{file}, a @file{Cargo.lock} file. For example:
+
+@example
+guix import crate --lockfile=/path/to/Cargo.lock my-package
+@end example
+
+generates sources from @file{/path/to/Cargo.lock} and a list
+@code{my-package-cargo-inputs} referencing these sources. The generated list is
+intended for the package's @code{inputs}, replacing @code{#:cargo-inputs} and
+@code{#:cargo-development-inputs}.
@end table
@item elm
@@ -25,11 +25,13 @@
(define-module (guix scripts import crate)
#:use-module (guix ui)
#:use-module (guix utils)
+ #:use-module (guix read-print)
#:use-module (guix scripts)
#:use-module (guix import crate)
#:use-module (guix scripts import)
#:use-module (srfi srfi-1)
#:use-module (srfi srfi-11)
+ #:use-module (srfi srfi-26)
#:use-module (srfi srfi-37)
#:use-module (ice-9 match)
#:use-module (ice-9 format)
@@ -60,6 +62,9 @@ (define (show-help)
sufficient package exists for it"))
(newline)
(display (G_ "
+ -f, --lockfile=FILE import dependencies from FILE, a 'Cargo.lock' file"))
+ (newline)
+ (display (G_ "
-h, --help display this help and exit"))
(display (G_ "
-V, --version display version information and exit"))
@@ -87,6 +92,9 @@ (define %options
(option '("mark-missing") #f #f
(lambda (opt name arg result)
(alist-cons 'mark-missing #t result)))
+ (option '(#\f "lockfile") #f #t
+ (lambda (opt name arg result)
+ (alist-cons 'lockfile arg result)))
%standard-import-options))
@@ -101,6 +109,8 @@ (define (guix-import-crate . args)
#:build-options? #f))
(let* ((opts (parse-options))
+ (lockfile (assoc-ref opts 'lockfile))
+ (file-to-insert (assoc-ref opts 'file-to-insert))
(args (filter-map (match-lambda
(('argument . value)
value)
@@ -111,16 +121,44 @@ (define (guix-import-crate . args)
(define-values (name version)
(package-name->name+version spec))
- (match (if (assoc-ref opts 'recursive)
- (crate-recursive-import
- name #:version version
- #:recursive-dev-dependencies?
- (assoc-ref opts 'recursive-dev-dependencies)
- #:allow-yanked? (assoc-ref opts 'allow-yanked))
- (crate->guix-package
- name #:version version #:include-dev-deps? #t
- #:allow-yanked? (assoc-ref opts 'allow-yanked)
- #:mark-missing? (assoc-ref opts 'mark-missing)))
+ (match (cond
+ ((and=> lockfile
+ (lambda (file)
+ (or (file-exists? file)
+ (leave (G_ "file '~a' does not exist~%") file))))
+ (let-values (((crate-definitions input-list)
+ (cargo-lock->definitions lockfile name)))
+ (if file-to-insert
+ ;; Adjusted from ‘--insert’ option of guix-import.
+ (let ((term (second input-list)))
+ (begin
+ ;; Remove existing input list definition.
+ (and=> (find-definition-location file-to-insert term)
+ delete-expression)
+ ;; Insert input list alphabetically.
+ (or (and=> (find-definition-insertion-location
+ file-to-insert term)
+ (cut insert-expression <> input-list))
+ (let ((port (open-file file-to-insert "a")))
+ (newline port)
+ (pretty-print-with-comments port input-list)
+ (newline port)
+ (newline port)
+ (close-port port))))
+ crate-definitions)
+ `(,@crate-definitions
+ ,input-list))))
+ ((assoc-ref opts 'recursive)
+ (crate-recursive-import
+ name #:version version
+ #:recursive-dev-dependencies?
+ (assoc-ref opts 'recursive-dev-dependencies)
+ #:allow-yanked? (assoc-ref opts 'allow-yanked)))
+ (else
+ (crate->guix-package
+ name #:version version #:include-dev-deps? #t
+ #:allow-yanked? (assoc-ref opts 'allow-yanked)
+ #:mark-missing? (assoc-ref opts 'mark-missing))))
((or #f '())
(leave (G_ "failed to download meta-data for package '~a'~%")
(if version
@@ -34,6 +34,7 @@ (define-module (test-crate)
#:use-module (gnu packages)
#:use-module (ice-9 iconv)
#:use-module (ice-9 match)
+ #:use-module (srfi srfi-11)
#:use-module (srfi srfi-64))
@@ -476,6 +477,9 @@ (define rust-leaf-bob-3.0.2-yanked
(description #f)
(license #f)))
+(define temp-file
+ (string-append "t-crate-" (number->string (getpid))))
+
(test-begin "crate")
@@ -1178,4 +1182,88 @@ (define rust-leaf-bob-3.0.2-yanked
(x
(pk 'fail (pretty-print-with-comments (current-output-port) x) #f)))))
+
+(test-assert "crate-lockfile-import"
+ (begin
+ (call-with-output-file temp-file
+ (lambda (port)
+ (display "\
+# This file is automatically @generated by Cargo.
+# It is not intended for manual editing.
+version = 3
+
+[[package]]
+name = \"adler2\"
+version = \"2.0.0\"
+source = \"registry+https://github.com/rust-lang/crates.io-index\"
+checksum = \"512761e0bb2578dd7380c6baaa0f4ce03e84f95e960231d1dec8bf4d7d6e2627\"
+
+[[package]]
+name = \"aho-corasick\"
+version = \"1.1.3\"
+source = \"registry+https://github.com/rust-lang/crates.io-index\"
+checksum = \"8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916\"
+dependencies = [
+ \"memchr\",
+]
+
+[[package]]
+name = \"smithay\"
+version = \"0.4.0\"
+source = \"git+https://github.com/Smithay/smithay.git?rev=\
+0cd3345c59f7cb139521f267956a1a4e33248393#\
+0cd3345c59f7cb139521f267956a1a4e33248393\"
+dependencies = [
+ \"appendlist\",
+]
+
+[[package]]
+name = \"test\"
+version = \"25.2.0\"\n" port)))
+ (mock
+ ((guix scripts download) guix-download
+ (lambda _
+ (format #t "~a~%~a~%"
+ "/gnu/store/in056fyrz6nvy3jpxrxglgj30g0lwniv-smithay-0cd3345"
+ "191h87bpzg0l1ihfb4hmx00b86pfb5mwwc6s8i49al0vigc14l37")))
+ (let-values
+ (((crates-definitions input-list)
+ (cargo-lock->definitions temp-file "test")))
+ (and
+ (match crates-definitions
+ (((define 'rust-adler2-2.0.0
+ (crate-source
+ "adler2" "2.0.0"
+ "09r6drylvgy8vv8k20lnbvwq8gp09h7smfn6h1rxsy15pgh629si"))
+ (define 'rust-aho-corasick-1.1.3
+ (crate-source
+ "aho-corasick" "1.1.3"
+ "05mrpkvdgp5d20y2p989f187ry9diliijgwrs254fs9s1m1x6q4f"))
+ (define 'rust-smithay-0.4.0.0cd3345
+ ($ <comment>
+ ";; TODO: Define standalone package if this is a workspace.\n"
+ #f)
+ (origin
+ (method git-fetch)
+ (uri (git-reference
+ (url "https://github.com/Smithay/smithay.git")
+ (commit "0cd3345c59f7cb139521f267956a1a4e33248393")))
+ (file-name (git-file-name "rust-smithay" "0.4.0.0cd3345"))
+ (sha256
+ (base32
+ "191h87bpzg0l1ihfb4hmx00b86pfb5mwwc6s8i49al0vigc14l37")))))
+ #t)
+ (x
+ (pk 'fail (pretty-print-with-comments (current-output-port) x) #f)))
+ (match input-list
+ ((define-public 'test-cargo-inputs
+ (list rust-adler2-2.0.0
+ rust-aho-corasick-1.1.3
+ rust-smithay-0.4.0.0cd3345))
+ #t)
+ (x
+ (pk 'fail x #f))))))))
+
(test-end "crate")
+
+(false-if-exception (delete-file temp-file))