[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(-)
Comments
Hilton Chain <hako@ultrarare.space> writes:
> * 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
[...]
> + (match crates-definitions
> + (((define 'rust-adler2-2.0.0
> + (crate-source
> + "adler2" "2.0.0"
> + "09r6drylvgy8vv8k20lnbvwq8gp09h7smfn6h1rxsy15pgh629si"))
Note that this doesn’t actually testwhat you’d like. For instance, it
would match:
((whatever rust-adler2-2.0.0
(nonsense "adler2" "2.0.0"
"09r6drylvgy8vv8k20lnbvwq8gp09h7smfn6h1rxsy15pgh629si"))
…)
But the bug is already here in ‘master’, uh.
So you need to quote every symbol that is meant to be matched literally,
or wrap the pattern in quasiquote, as is done in ‘tests/gem.scm’:
(match …
((`(define rust-adler2-2.0.0 (crate-source …))) #t))
Ludo’.
On Wed, 23 Apr 2025 05:28:17 +0800,
Ludovic Courtès wrote:
>
> Hilton Chain <hako@ultrarare.space> writes:
>
> > * 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
>
> [...]
>
> > + (match crates-definitions
> > + (((define 'rust-adler2-2.0.0
> > + (crate-source
> > + "adler2" "2.0.0"
> > + "09r6drylvgy8vv8k20lnbvwq8gp09h7smfn6h1rxsy15pgh629si"))
>
> Note that this doesn’t actually testwhat you’d like. For instance, it
> would match:
>
> ((whatever rust-adler2-2.0.0
> (nonsense "adler2" "2.0.0"
> "09r6drylvgy8vv8k20lnbvwq8gp09h7smfn6h1rxsy15pgh629si"))
> …)
>
> But the bug is already here in ‘master’, uh.
>
> So you need to quote every symbol that is meant to be matched literally,
> or wrap the pattern in quasiquote, as is done in ‘tests/gem.scm’:
>
> (match …
> ((`(define rust-adler2-2.0.0 (crate-source …))) #t))
Thanks! Changes here are not applied to master yet, they are currently
available in rust-team only.
@@ -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))