diff options
author | Hilton Chain <hako@ultrarare.space> | 2025-06-09 18:35:27 +0800 |
---|---|---|
committer | Hilton Chain <hako@ultrarare.space> | 2025-08-21 19:09:04 +0800 |
commit | 92d130e03594bd2b8e6688c83fc35a3f2c2954da (patch) | |
tree | c2dcc0d09edd789a9b4308c34a82eb0ab3e61642 | |
parent | efaa3e681ef14ac5e0900319557a21fb421b2053 (diff) | |
download | guix-92d130e03594bd2b8e6688c83fc35a3f2c2954da.tar guix-92d130e03594bd2b8e6688c83fc35a3f2c2954da.tar.gz |
import: crate: Stop importing dependencies from crates.io.
* guix/scripts/import/crate.scm (show-help, %options, guix-import-crate)
[--recursive, --recursive-dev-dependencies, --mark-missing]: Remove options.
* doc/guix.texi (Invoking guix import)[crate]: Adjust accordingly.
Mention packaging workflow.
* guix/import/crate.scm (make-crate-sexp): Don't use "rust-" prefix and semver
suffix for package name.
[#:cargo-inputs, #:cargo-development-inputs, #:build?]: Remove arguments.
(crate->guix-package)[#:include-dev-deps?, #:mark-missing?]: Remove arguments.
(<crate-dependency>): Remove data type.
(make-crate-dependency, crate-dependency?, json->crate-dependency)
(crate-version-dependencies, package-names->package-inputs)
(maybe-cargo-inputs, maybe-cargo-development-inputs, maybe-arguments)
(version->semver-prefix, find-package-version, crate-recursive-import): Remove
procedures.
* tests/crate.scm (test-foo-crate, test-bar-crate): Adjust for modified tests.
(test-foo-dependencies, test-bar-dependencies, test-root-crate)
(test-root-dependencies, test-intermediate-a-crate)
(test-intermediate-a-dependencies, test-intermediate-b-crate)
(test-intermediate-b-dependencies, test-intermediate-c-crate)
(test-intermediate-c-dependencies, test-leaf-alice-crate)
(test-leaf-alice-dependencies, test-leaf-bob-crate)
(test-leaf-bob-dependencies, rust-leaf-bob-3, rust-leaf-bob-3.0.2-yanked):
Remove variables.
("crate->guix-package yanked", "crate->guix-package only yanked available"): New
tests.
("crate->guix-package"): Adjust accordingly.
("crate->guix-package-marks-missing-packages", "crate-recursive-import")
("crate-recursive-import-honors-existing-packages")
("crate-import-only-yanked-available"): Remove tests.
Change-Id: Ib1d24511ed0ea1a2373f53de12e06afa7950a7d7
-rw-r--r-- | doc/guix.texi | 16 | ||||
-rw-r--r-- | guix/import/crate.scm | 267 | ||||
-rw-r--r-- | guix/scripts/import/crate.scm | 85 | ||||
-rw-r--r-- | tests/crate.scm | 1116 |
4 files changed, 152 insertions, 1332 deletions
diff --git a/doc/guix.texi b/doc/guix.texi index bde3724dcd..9147cd61ca 100644 --- a/doc/guix.texi +++ b/doc/guix.texi @@ -14939,27 +14939,17 @@ guix import crate constant-time-eq@@0.1.0 Additional options include: @table @code -@item --recursive -@itemx -r -Traverse the dependency graph of the given upstream package recursively -and generate package expressions for all those packages that are not yet -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. @item --allow-yanked If no non-yanked version of a crate is available, use the latest yanked version instead instead of aborting. -@item --mark-missing -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 expressions, instead importing source expressions from @var{file}, a @file{Cargo.lock} file. + +@xref{Packaging Rust Crates,,, guix-cookbook, GNU Guix Cookbook}, for packaging +workflow utilizing it. @end table @item elm diff --git a/guix/import/crate.scm b/guix/import/crate.scm index b7a3250c13..3973be1e13 100644 --- a/guix/import/crate.scm +++ b/guix/import/crate.scm @@ -104,20 +104,9 @@ (yanked? crate-version-yanked? "yanked") ;boolean (links crate-version-links)) ;alist -;; Crate dependency. Each dependency (each edge in the graph) is annotated as -;; being a "normal" dependency or a development dependency. There also -;; information about the minimum required version, such as "^0.0.41". -(define-json-mapping <crate-dependency> make-crate-dependency - crate-dependency? - json->crate-dependency - (id crate-dependency-id "crate_id") ;string - (kind crate-dependency-kind "kind" ;'normal | 'dev | 'build - string->symbol) - (requirement crate-dependency-requirement "req")) ;string - ;; Autoload Guile-Semver so we only have a soft dependency. (module-autoload! (current-module) - '(semver) '(string->semver semver->string semver<? semver=? semver>?)) + '(semver) '(string->semver semver->string semver>?)) (module-autoload! (current-module) '(semver ranges) '(string->semver-range semver-range-contains?)) @@ -138,91 +127,17 @@ record or #f if it was not found." (define lookup-crate* (memoize lookup-crate)) -(define (crate-version-dependencies version) - "Return the list of <crate-dependency> records of VERSION, a -<crate-version>." - (let* ((path (assoc-ref (crate-version-links version) "dependencies")) - (url (string-append (%crate-base-url) path))) - (match (assoc-ref (or (json-fetch url) '()) "dependencies") - ((? vector? vector) - (delete-duplicates (map json->crate-dependency (vector->list vector)))) - (_ - '())))) - ;;; ;;; Converting crates to Guix packages. ;;; -(define* (package-names->package-inputs names #:optional (output #f)) - "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)) - ((? blank? comment) comment) - (input (make-input input #f))) - names)) - -(define (maybe-cargo-inputs package-names) - (match (package-names->package-inputs package-names) - (() - '()) - ((package-inputs ...) - `(#:cargo-inputs ,package-inputs)))) - -(define (maybe-cargo-development-inputs package-names) - (match (package-names->package-inputs package-names) - (() - '()) - ((package-inputs ...) - `(#:cargo-development-inputs ,package-inputs)))) - -(define (maybe-arguments arguments) - (match arguments - (() - '()) - ((args ...) - `((arguments (,'quasiquote ,args)))))) - -(define (version->semver-prefix version) - "Return the version up to and including the first non-zero part" - (first - (map match:substring - (list-matches "^(0+\\.){,2}[0-9]+" version)))) - -(define* (make-crate-sexp #:key name version cargo-inputs cargo-development-inputs - home-page synopsis description license build? yanked?) +(define* (make-crate-sexp #:key name version + home-page synopsis description license yanked?) "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 missing version yanked) - (let ((input (list (crate-name->package-name name) - (if yanked - (string-append version "-yanked") - (version->semver-prefix version))))) - (if missing - (comment - (string-append ";; " (string-join input "-") "\n") - #f) - input)))) - inputs)) - +VERSION, HOME-PAGE, SYNOPSIS, DESCRIPTION and LICENSE." (let* ((port (http-fetch (crate-uri name version))) - (guix-name (crate-name->package-name name)) - (cargo-inputs (format-inputs cargo-inputs)) - (cargo-development-inputs (format-inputs cargo-development-inputs)) + (guix-name (downstream-package-name "" name)) (description (beautify-description description)) (pkg `(package (name ,guix-name) @@ -234,9 +149,9 @@ and LICENSE." (method url-fetch) (uri (crate-uri ,name version)) (file-name - ,@(if yanked? - `((string-append name "-" version "-yanked.tar.gz")) - `((string-append name "-" version ".tar.gz")))) + ,@(if yanked? + `((string-append name "-" version "-yanked.tar.gz")) + `((string-append name "-" version ".tar.gz")))) (sha256 (base32 ,(bytevector->nix-base32-string (port-sha256 port)))))) @@ -244,12 +159,7 @@ and LICENSE." `((properties '((crate-version-yanked? . #t)))) '()) (build-system cargo-build-system) - ,@(maybe-arguments (append (if build? - '() - '(#:skip-build? #t)) - (maybe-cargo-inputs cargo-inputs) - (maybe-cargo-development-inputs - cargo-development-inputs))) + (inputs (cargo-inputs ',(string->symbol guix-name))) (home-page ,home-page) (synopsis ,(beautify-synopsis synopsis)) (description ,(if (string-prefix? "This" description) @@ -262,10 +172,7 @@ and LICENSE." ((license) license) (_ `(list ,@license))))))) (close-port port) - (package->definition pkg - (if yanked? - (string-append version "-yanked") - (version->semver-prefix version))))) + (package->definition pkg))) (define (string->license string) (filter-map (lambda (license) @@ -310,50 +217,13 @@ satisfies SEMVER-RANGE." (not (crate-version-yanked? entry))) (crate-versions crate))) -(define (find-package-version name range allow-yanked?) - "Find the latest existing package that fulfills the SemVer RANGE. If -ALLOW-YANKED? is #t, include packages marked as yanked at a lower -priority." - (set! range (string->semver-range range)) - (let loop ((packages (find-packages-by-name - (crate-name->package-name name))) - (semver #f) - (yanked? #f)) - (match packages - ((pkg packages ...) - (let ((pkg-yanked? (assoc-ref (package-properties pkg) - 'crate-version-yanked?))) - (if (or allow-yanked? (not pkg-yanked?)) - (let ((pkg-semver (string->semver (package-version pkg)))) - (if (and (or (not semver) - (and yanked? (not pkg-yanked?)) - (and (eq? yanked? pkg-yanked?) - (semver>? pkg-semver semver))) - (semver-range-contains? range pkg-semver)) - (loop packages pkg-semver pkg-yanked?) - (loop packages semver yanked?))) - (loop packages semver yanked?)))) - (() (and semver (list (semver->string semver) yanked?)))))) - (define* (crate->guix-package - crate-name - #:key version include-dev-deps? allow-yanked? mark-missing? - #:allow-other-keys) + crate-name #:key version allow-yanked? #:allow-other-keys) "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, 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. If INCLUDE-DEV-DEPS is true then this will also -look up the development dependencs for the given crate." - - (define (semver-range-contains-string? range version) - (semver-range-contains? (string->semver-range range) - (string->semver version))) - - (define (normal-dependency? dependency) - (or (eq? (crate-dependency-kind dependency) 'build) - (eq? (crate-dependency-kind dependency) 'normal))) - +version of CRATE-NAME." (define crate (lookup-crate* crate-name)) @@ -375,112 +245,29 @@ look up the development dependencs for the given crate." (max-crate-version-of-semver semver-range (crate-versions crate)))))) - ;; If no non-yanked existing package version was found, check the upstream - ;; versions. If a non-yanked upstream version exists, use it instead, - ;; otherwise use the existing package version, provided it exists. - (define (dependency-name+missing+version+yanked dep) - (let* ((name (crate-dependency-id dep)) - (req (crate-dependency-requirement dep)) - (existing-version - (find-package-version name req allow-yanked?))) - (if (and existing-version (not (second existing-version))) - (cons* name #f existing-version) - (let* ((crate (lookup-crate* name)) - (ver (find-crate-version crate req))) - (if existing-version - (if (and ver (not (crate-version-yanked? ver))) - (if (semver=? (string->semver (first existing-version)) - (string->semver (crate-version-number ver))) - (begin - (warning (G_ "~A: version ~a is no longer yanked~%") - name (first existing-version)) - (cons* name #f existing-version)) - (list name - #f - (crate-version-number ver) - (crate-version-yanked? ver))) - (begin - (warning (G_ "~A: using existing version ~a, which was yanked~%") - name (first existing-version)) - (cons* name #f existing-version))) - (begin - (unless ver - (leave (G_ "~A: no version found for requirement ~a~%") name req)) - (if (crate-version-yanked? ver) - (warning (G_ "~A: imported version ~a was yanked~%") - name (crate-version-number ver))) - (list name - mark-missing? - (crate-version-number ver) - (crate-version-yanked? ver)))))))) - (define version* (and crate (or (find-crate-version crate version-number) (leave (G_ "~A: version ~a not found~%") crate-name version-number)))) - ;; sort and map the dependencies to a list containing - ;; pairs of (name version) - (define (sort-map-dependencies deps) - (sort (map dependency-name+missing+version+yanked - deps) - (match-lambda* (((name _ _ _) ...) - (apply string-ci<? name))))) - - (define (remove-missing+yanked-info deps) - (map - (match-lambda ((name missing version yanked) - (list name version))) - deps)) - (if (and crate version*) - (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 (if include-dev-deps? - (sort-map-dependencies dev-dep-crates) - '()))) - (values - (make-crate-sexp #:build? include-dev-deps? - #:yanked? (crate-version-yanked? version*) - #:name crate-name - #:version (crate-version-number version*) - #:cargo-inputs cargo-inputs - #:cargo-development-inputs cargo-development-inputs - #:home-page - (let ((home-page (crate-home-page crate))) - (if (string? home-page) - home-page - (let ((repository (crate-repository crate))) - (if (string? repository) - repository - "")))) - #:synopsis (crate-description crate) - #:description (crate-description crate) - #:license (and=> (crate-version-license version*) - string->license)) - (append - (remove-missing+yanked-info cargo-inputs) - (remove-missing+yanked-info cargo-development-inputs)))) + (make-crate-sexp #:yanked? (crate-version-yanked? version*) + #:name crate-name + #:version (crate-version-number version*) + #:home-page + (let ((home-page (crate-home-page crate))) + (if (string? home-page) + home-page + (let ((repository (crate-repository crate))) + (if (string? repository) + repository + "")))) + #:synopsis (crate-description crate) + #:description (crate-description crate) + #:license (and=> (crate-version-license version*) + string->license)) (values #f '()))) -(define* (crate-recursive-import - crate-name #:key version recursive-dev-dependencies? allow-yanked?) - (recursive-import - crate-name - #:repo->guix-package - (let ((crate->guix-package* (memoize crate->guix-package))) - (lambda* params - ;; download development dependencies only for the top level package - (let ((include-dev-deps? - (or (equal? (car params) crate-name) - recursive-dev-dependencies?))) - (apply crate->guix-package* - (append params `(#:include-dev-deps? ,include-dev-deps? - #:allow-yanked? ,allow-yanked?)))))) - #:version version - #:guix-name crate-name->package-name)) - (define (guix-package->crate-name package) "Return the crate name of PACKAGE." (and-let* ((origin (package-source package)) diff --git a/guix/scripts/import/crate.scm b/guix/scripts/import/crate.scm index 8791d1092b..0218cced74 100644 --- a/guix/scripts/import/crate.scm +++ b/guix/scripts/import/crate.scm @@ -50,17 +50,8 @@ (display (G_ "Usage: guix import crate PACKAGE-NAME Import and convert the crates.io package for PACKAGE-NAME.\n")) (display (G_ " - -r, --recursive import packages recursively")) - (display (G_ " - --recursive-dev-dependencies - include dev-dependencies recursively")) - (newline) - (display (G_ " --allow-yanked allow importing yanked crates if no alternative satisfying the version requirement is found")) - (display (G_ " - --mark-missing comment out the desired dependency if no - sufficient package exists for it")) (newline) (display (G_ " -f, --lockfile=FILE import dependencies from FILE, a 'Cargo.lock' file")) @@ -81,18 +72,9 @@ Import and convert the crates.io package for PACKAGE-NAME.\n")) (option '(#\V "version") #f #f (lambda args (show-version-and-exit "guix import crate"))) - (option '(#\r "recursive") #f #f - (lambda (opt name arg result) - (alist-cons 'recursive #t result))) - (option '("recursive-dev-dependencies") #f #f - (lambda (opt name arg result) - (alist-cons 'recursive-dev-dependencies #t result))) (option '("allow-yanked") #f #f (lambda (opt name arg result) (alist-cons 'allow-yanked #t result))) - (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) (if (file-exists? arg) @@ -124,44 +106,35 @@ Import and convert the crates.io package for PACKAGE-NAME.\n")) (define-values (name version) (package-name->name+version spec)) - (match (cond - (lockfile - (let ((source-expressions - _ - (cargo-lock->expressions lockfile name))) - (when file-to-insert - (let* ((source-expressions - cargo-inputs-entry - (cargo-lock->expressions lockfile name)) - (term (first cargo-inputs-entry)) - (cargo-inputs - `(define-cargo-inputs lookup-cargo-inputs - ,@(sort - (cons cargo-inputs-entry - (extract-cargo-inputs - file-to-insert #:exclude term)) - (lambda (a b) - (string< (symbol->string (first a)) - (symbol->string (first b))))))) - (_ - (and=> (find-cargo-inputs-location file-to-insert) - delete-expression)) - (port (open-file file-to-insert "a"))) - (pretty-print-with-comments port cargo-inputs) - (newline port) - (close-port port))) - source-expressions)) - ((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)))) + (match (if lockfile + (let ((source-expressions + _ + (cargo-lock->expressions lockfile name))) + (when file-to-insert + (let* ((source-expressions + cargo-inputs-entry + (cargo-lock->expressions lockfile name)) + (term (first cargo-inputs-entry)) + (cargo-inputs + `(define-cargo-inputs lookup-cargo-inputs + ,@(sort + (cons cargo-inputs-entry + (extract-cargo-inputs + file-to-insert #:exclude term)) + (lambda (a b) + (string< (symbol->string (first a)) + (symbol->string (first b))))))) + (_ + (and=> (find-cargo-inputs-location file-to-insert) + delete-expression)) + (port (open-file file-to-insert "a"))) + (pretty-print-with-comments port cargo-inputs) + (newline port) + (close-port port))) + source-expressions) + (crate->guix-package + name #:version version + #:allow-yanked? (assoc-ref opts 'allow-yanked))) ((or #f '()) (leave (G_ "failed to download meta-data for package '~a'~%") (if version diff --git a/tests/crate.scm b/tests/crate.scm index 8c1f6e738d..b5599e5d48 100644 --- a/tests/crate.scm +++ b/tests/crate.scm @@ -37,51 +37,10 @@ #:use-module (srfi srfi-11) #: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 -;; bar-1.0.0 -;; leaf-bob 3.0.1 -;; leaf-bob 3.0.2 (dev-dependency) -;; leaf-bob 4.0.0 (dev-dependency) -;; -;; root-1.0.0 -;; root-1.0.4 -;; intermediate-a 1.0.42 -;; intermediate-b ^1.0.0 -;; leaf-alice ^0.7 -;; leaf-bob ^3 -;; leaf-bob 3 (build-dependency) -;; intermediate-c 1 (dev-dependency) -;; -;; 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 -;; -;; intermediate-c-1.0.1 -;; leaf-alice 0.7.5 (dev-dependency) -;; -;; leaf-alice-0.7.3 -;; leaf-alice-0.7.5 -;; -;; leaf-bob-3.0.1 -;; leaf-bob-3.0.2 (yanked) -;; leaf-bob-4.0.0 (yanked) - - (define test-foo-crate "{ \"crate\": { - \"max_version\": \"1.0.3\", + \"max_version\": \"1.0.0\", \"name\": \"foo\", \"description\": \"summary\", \"homepage\": \"http://example.com\", @@ -111,23 +70,12 @@ \"links\": { \"dependencies\": \"/api/v1/crates/foo/1.0.3/dependencies\" }, - \"yanked\": false + \"yanked\": true } ] } }") -(define test-foo-dependencies - "{ - \"dependencies\": [ - { - \"crate_id\": \"leaf-alice\", - \"kind\": \"normal\", - \"req\": \"0.7.5\" - } - ] -}") - (define test-bar-crate "{ \"crate\": { @@ -145,338 +93,18 @@ \"links\": { \"dependencies\": \"/api/v1/crates/bar/1.0.0/dependencies\" }, - \"yanked\": false - } - ] - } -}") - -(define test-bar-dependencies - "{ - \"dependencies\": [ - { - \"crate_id\": \"leaf-bob\", - \"kind\": \"normal\", - \"req\": \"3.0.1\" - }, - { - \"crate_id\": \"leaf-bob\", - \"kind\": \"dev\", - \"req\": \"^3.0.2\" - }, - { - \"crate_id\": \"leaf-bob\", - \"kind\": \"dev\", - \"req\": \"^4.0.0\" - } - ] -}") - -(define test-root-crate - "{ - \"crate\": { - \"max_version\": \"1.0.4\", - \"name\": \"root\", - \"description\": \"summary\", - \"homepage\": \"http://example.com\", - \"repository\": \"http://example.com\", - \"keywords\": [\"dummy\", \"test\"], - \"categories\": [\"test\"], - \"actual_versions\": [ - { \"id\": 234240, - \"num\": \"1.0.0\", - \"license\": \"MIT OR Apache-2.0\", - \"links\": { - \"dependencies\": \"/api/v1/crates/root/1.0.0/dependencies\" - }, - \"yanked\": false - }, - { \"id\": 234242, - \"num\": \"1.0.4\", - \"license\": \"MIT OR Apache-2.0\", - \"links\": { - \"dependencies\": \"/api/v1/crates/root/1.0.4/dependencies\" - }, - \"yanked\": false - } - ] - } -}") - -(define test-root-dependencies - "{ - \"dependencies\": [ - { - \"crate_id\": \"intermediate-a\", - \"kind\": \"normal\", - \"req\": \"1.0.42\" - }, - { - \"crate_id\": \"intermediate-b\", - \"kind\": \"normal\", - \"req\": \"^1.0.0\" - }, - { - \"crate_id\": \"leaf-alice\", - \"kind\": \"normal\", - \"req\": \"^0.7\" - }, - { - \"crate_id\": \"leaf-bob\", - \"kind\": \"normal\", - \"req\": \"^3\" - }, - { - \"crate_id\": \"leaf-bob\", - \"kind\": \"build\", - \"req\": \"3\" - }, - { - \"crate_id\": \"intermediate-c\", - \"kind\": \"dev\", - \"req\": \"1\" - } - ] -}") - -(define test-intermediate-a-crate - "{ - \"crate\": { - \"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\"], - \"actual_versions\": [ - { \"id\": 234251, - \"num\": \"1.0.40\", - \"license\": \"MIT OR Apache-2.0\", - \"links\": { - \"dependencies\": \"/api/v1/crates/intermediate-a/1.0.40/dependencies\" - }, - \"yanked\": false - }, - { \"id\": 234250, - \"num\": \"1.0.42\", - \"license\": \"MIT OR Apache-2.0\", - \"links\": { - \"dependencies\": \"/api/v1/crates/intermediate-a/1.0.42/dependencies\" - }, - \"yanked\": false - }, - { \"id\": 234252, - \"num\": \"1.1.0-alpha.1\", - \"license\": \"MIT OR Apache-2.0\", - \"links\": { - \"dependencies\": \"/api/v1/crates/intermediate-a/1.1.0-alpha.1/dependencies\" - }, - \"yanked\": false - } - ] - } -}") - -(define test-intermediate-a-dependencies - "{ - \"dependencies\": [ - { - \"crate_id\": \"intermediate-b\", - \"kind\": \"normal\", - \"req\": \"1.2.3\" - }, - { - \"crate_id\": \"leaf-alice\", - \"kind\": \"normal\", - \"req\": \"0.7.5\" - }, - { - \"crate_id\": \"leaf-bob\", - \"kind\": \"normal\", - \"req\": \"^3\" - } - ] -}") - -(define test-intermediate-b-crate - "{ - \"crate\": { - \"max_version\": \"1.2.3\", - \"name\": \"intermediate-b\", - \"description\": \"summary\", - \"homepage\": \"http://example.com\", - \"repository\": \"http://example.com\", - \"keywords\": [\"dummy\", \"test\"], - \"categories\": [\"test\"], - \"actual_versions\": [ - { \"id\": 234260, - \"num\": \"1.2.3\", - \"license\": \"MIT OR Apache-2.0\", - \"links\": { - \"dependencies\": \"/api/v1/crates/intermediate-b/1.2.3/dependencies\" - }, - \"yanked\": false - } - ] - } -}") - -(define test-intermediate-b-dependencies - "{ - \"dependencies\": [ - { - \"crate_id\": \"leaf-bob\", - \"kind\": \"normal\", - \"req\": \"3.0.1\" - } - ] -}") - -(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 - "{ - \"crate\": { - \"max_version\": \"0.7.5\", - \"name\": \"leaf-alice\", - \"description\": \"summary\", - \"homepage\": \"http://example.com\", - \"repository\": \"http://example.com\", - \"keywords\": [\"dummy\", \"test\"], - \"categories\": [\"test\"], - \"actual_versions\": [ - { \"id\": 234270, - \"num\": \"0.7.3\", - \"license\": \"MIT OR Apache-2.0\", - \"links\": { - \"dependencies\": \"/api/v1/crates/leaf-alice/0.7.3/dependencies\" - }, - \"yanked\": false - }, - { \"id\": 234272, - \"num\": \"0.7.5\", - \"license\": \"MIT OR Apache-2.0\", - \"links\": { - \"dependencies\": \"/api/v1/crates/leaf-alice/0.7.5/dependencies\" - }, - \"yanked\": false - } - ] - } -}") - -(define test-leaf-alice-dependencies - "{ - \"dependencies\": [] -}") - -(define test-leaf-bob-crate - "{ - \"crate\": { - \"max_version\": \"3.0.1\", - \"name\": \"leaf-bob\", - \"description\": \"summary\", - \"homepage\": \"http://example.com\", - \"repository\": \"http://example.com\", - \"keywords\": [\"dummy\", \"test\"], - \"categories\": [\"test\"] - \"actual_versions\": [ - { \"id\": 234280, - \"num\": \"3.0.1\", - \"license\": \"MIT OR Apache-2.0\", - \"links\": { - \"dependencies\": \"/api/v1/crates/leaf-bob/3.0.1/dependencies\" - }, - \"yanked\": false - }, - { \"id\": 234281, - \"num\": \"3.0.2\", - \"license\": \"MIT OR Apache-2.0\", - \"links\": { - \"dependencies\": \"/api/v1/crates/leaf-bob/3.0.2/dependencies\" - }, - \"yanked\": true - }, - { \"id\": 234282, - \"num\": \"4.0.0\", - \"license\": \"MIT OR Apache-2.0\", - \"links\": { - \"dependencies\": \"/api/v1/crates/leaf-bob/4.0.0/dependencies\" - }, \"yanked\": true } ] } }") -(define test-leaf-bob-dependencies - "{ - \"dependencies\": [] -}") - - (define test-source-hash "") (define have-guile-semver? (false-if-exception (resolve-interface '(semver)))) -(define rust-leaf-bob-3 - (package - (name "rust-leaf-bob") - (version "3.0.1") - (source #f) - (build-system #f) - (home-page #f) - (synopsis #f) - (description #f) - (license #f))) - -(define rust-leaf-bob-3.0.2-yanked - (package - (name "rust-leaf-bob") - (version "3.0.2") - (source #f) - (properties '((crate-version-yanked? . #t))) - (build-system #f) - (home-page #f) - (synopsis #f) - (description #f) - (license #f))) - (define temp-file (string-append "t-crate-" (number->string (getpid)))) @@ -491,7 +119,7 @@ (source (dummy-origin (uri (crate-uri "rustc-serialize" "1.0"))))))) -(unless have-guile-semver? (test-skip 1)) +(unless have-guile-semver? (test-skip 3)) (test-assert "crate->guix-package" ;; Replace network resources with sample data. (mock ((guix http-client) http-fetch @@ -499,463 +127,110 @@ (match url ("https://crates.io/api/v1/crates/foo" (open-input-string test-foo-crate)) - ("https://crates.io/api/v1/crates/foo/1.0.3/download" - (set! test-source-hash - (bytevector->nix-base32-string - (gcrypt-sha256 (string->bytevector "empty file\n" "utf-8")))) - (open-input-string "empty file\n")) - ("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" + ("https://crates.io/api/v1/crates/foo/1.0.0/download" (set! test-source-hash (bytevector->nix-base32-string (gcrypt-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") - ((define-public 'rust-foo-1 - (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)))))) - (home-page "http://example.com") - (synopsis "summary") - (description "This package provides summary.") - (license (list license:expat license:asl2.0)))) + (`(define-public foo + (package (name "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) + (inputs (cargo-inputs 'foo)) + (home-page "http://example.com") + (synopsis "summary") + (description "This package provides summary.") + (license (list license:expat license:asl2.0)))) (string=? test-source-hash hash)) (x (pk 'fail x #f))))) -(unless have-guile-semver? (test-skip 1)) -(test-assert "crate->guix-package-marks-missing-packages" +(test-assert "crate->guix-package yanked" (mock - ((gnu packages) find-packages-by-name - (lambda* (name #:optional version) - (match name - ("rust-leaf-bob" - (list rust-leaf-bob-3.0.2-yanked)) - (_ '())))) - (mock - ((guix http-client) http-fetch - (lambda (url . rest) - (match url - ("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 - (gcrypt-sha256 (string->bytevector "empty file\n" "utf-8")))) - (open-input-string "empty file\n")) - ("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-bob" - (open-input-string test-leaf-bob-crate)) - ("https://crates.io/api/v1/crates/leaf-bob/3.0.1/download" - (set! test-source-hash - (bytevector->nix-base32-string - (gcrypt-sha256 (string->bytevector "empty file\n" "utf-8")))) - (open-input-string "empty file\n")) - (_ (error "Unexpected URL: " url))))) - (match (crate->guix-package "intermediate-b" #:mark-missing? #t) - ((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 - (#:skip-build? #t - #:cargo-inputs - (($ <comment> ";; rust-leaf-bob-3\n" #f))))) - (home-page "http://example.com") - (synopsis "summary") - (description "This package provides summary.") - (license (list license:expat license:asl2.0)))) - #t) - (x - (pk 'fail - (pretty-print-with-comments (current-output-port) x) - #f)))))) + ((guix http-client) http-fetch + (lambda (url . rest) + (match url + ("https://crates.io/api/v1/crates/foo" + (open-input-string test-foo-crate)) + ("https://crates.io/api/v1/crates/foo/1.0.3/download" + (set! test-source-hash + (bytevector->nix-base32-string + (gcrypt-sha256 (string->bytevector "empty file\n" "utf-8")))) + (open-input-string "empty file\n")) + (_ (error "Unexpected URL: " url))))) -(unless have-guile-semver? (test-skip 1)) -(test-assert "crate-recursive-import" - ;; Replace network resources with sample data. - (mock ((guix http-client) http-fetch - (lambda (url . rest) - (match url - ("https://crates.io/api/v1/crates/root" - (open-input-string test-root-crate)) - ("https://crates.io/api/v1/crates/root/1.0.4/download" - (set! test-source-hash - (bytevector->nix-base32-string - (gcrypt-sha256 (string->bytevector "empty file\n" "utf-8")))) - (open-input-string "empty file\n")) - ("https://crates.io/api/v1/crates/root/1.0.4/dependencies" - (open-input-string test-root-dependencies)) - ("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 - (gcrypt-sha256 (string->bytevector "empty file\n" "utf-8")))) - (open-input-string "empty file\n")) - ("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 - (gcrypt-sha256 (string->bytevector "empty file\n" "utf-8")))) - (open-input-string "empty file\n")) - ("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/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 - (gcrypt-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" - (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 - (gcrypt-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)) - ("https://crates.io/api/v1/crates/leaf-bob" - (open-input-string test-leaf-bob-crate)) - ("https://crates.io/api/v1/crates/leaf-bob/3.0.1/download" - (set! test-source-hash - (bytevector->nix-base32-string - (gcrypt-sha256 (string->bytevector "empty file\n" "utf-8")))) - (open-input-string "empty file\n")) - ("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-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 (#:skip-build? #t))) - (home-page "http://example.com") - (synopsis "summary") - (description "This package provides 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) - (arguments ('quasiquote (#:skip-build? #t))) - (home-page "http://example.com") - (synopsis "summary") - (description "This package provides 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) - (arguments ('quasiquote (#:skip-build? #t))) - (home-page "http://example.com") - (synopsis "summary") - (description "This package provides 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 (#:skip-build? #t - #:cargo-inputs - (("rust-leaf-bob" - ('unquote rust-leaf-bob-3)))))) - (home-page "http://example.com") - (synopsis "summary") - (description "This package provides 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 (#:skip-build? #t - #: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 "This package provides 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 "This package provides 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 "This package provides 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 "This package provides 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 "This package provides 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)))))) - (home-page "http://example.com") - (synopsis "summary") - (description "This package provides 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 "This package provides 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)) - ("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 "This package provides summary.") - (license (list license:expat license:asl2.0))))) - #t) - (x - (pk 'fail x #f))))) + (match (crate->guix-package "foo" #:version "1.0.3" #:allow-yanked? #t) + (`(define-public foo + (package (name "foo") + (version "1.0.3") + ,(? comment?) + (source + (origin + (method url-fetch) + (uri (crate-uri "foo" version)) + (file-name (string-append name "-" version "-yanked.tar.gz")) + (sha256 + (base32 + ,(? string? hash))))) + (properties '((crate-version-yanked? . #t))) + (build-system cargo-build-system) + (inputs (cargo-inputs 'foo)) + (home-page "http://example.com") + (synopsis "summary") + (description "This package provides summary.") + (license (list license:expat license:asl2.0)))) + (string=? test-source-hash hash)) + (x + (pk 'fail x #f))))) + +(test-assert "crate->guix-package only yanked available" + (mock + ((guix http-client) http-fetch + (lambda (url . rest) + (match url + ("https://crates.io/api/v1/crates/bar" + (open-input-string test-foo-crate)) + ("https://crates.io/api/v1/crates/bar/1.0.0/download" + (set! test-source-hash + (bytevector->nix-base32-string + (gcrypt-sha256 (string->bytevector "empty file\n" "utf-8")))) + (open-input-string "empty file\n")) + (_ (error "Unexpected URL: " url))))) + + (match (crate->guix-package "bar") + (`(define-public bar + (package (name "bar") + (version "1.0.0") + (source + (origin + (method url-fetch) + (uri (crate-uri "bar" version)) + (file-name + (string-append name "-" version ".tar.gz")) + (sha256 + (base32 + ,(? string? hash))))) + (build-system cargo-build-system) + (inputs (cargo-inputs 'bar)) + (home-page "http://example.com") + (synopsis "summary") + (description "This package provides summary.") + (license (list license:expat license:asl2.0)))) + (string=? test-source-hash hash)) + (x + (pk 'fail x #f))))) (test-equal "licenses: MIT OR Apache-2.0" '(license:expat license:asl2.0) @@ -977,211 +252,6 @@ '(license:expat license:asl2.0) (string->license "MIT/Apache-2.0")) - - -(unless have-guile-semver? (test-skip 1)) -(test-assert "crate-recursive-import-honors-existing-packages" - (mock - ((gnu packages) find-packages-by-name - (lambda* (name #:optional version) - (match name - ("rust-leaf-bob" - (list rust-leaf-bob-3 rust-leaf-bob-3.0.2-yanked)) - (_ '())))) - (mock - ((guix http-client) http-fetch - (lambda (url . rest) - (match url - ("https://crates.io/api/v1/crates/bar" - (open-input-string test-bar-crate)) - ("https://crates.io/api/v1/crates/bar/1.0.0/download" - (set! test-source-hash - (bytevector->nix-base32-string - (gcrypt-sha256 (string->bytevector "empty file\n" "utf-8")))) - (open-input-string "empty file\n")) - ("https://crates.io/api/v1/crates/bar/1.0.0/dependencies" - (open-input-string test-bar-dependencies)) - ("https://crates.io/api/v1/crates/leaf-bob" - (open-input-string test-leaf-bob-crate)) - ("https://crates.io/api/v1/crates/leaf-bob/3.0.2/download" - (set! test-source-hash - (bytevector->nix-base32-string - (gcrypt-sha256 (string->bytevector "empty file\n" "utf-8")))) - (open-input-string "empty file\n")) - ("https://crates.io/api/v1/crates/leaf-bob/3.0.2/dependencies" - (open-input-string test-leaf-bob-dependencies)) - ("https://crates.io/api/v1/crates/leaf-bob/4.0.0/download" - (set! test-source-hash - (bytevector->nix-base32-string - (gcrypt-sha256 (string->bytevector "empty file\n" "utf-8")))) - (open-input-string "empty file\n")) - ("https://crates.io/api/v1/crates/leaf-bob/4.0.0/dependencies" - (open-input-string test-leaf-bob-dependencies)) - (_ (error "Unexpected URL: " url))))) - (match (crate-recursive-import "bar" - #:allow-yanked? #t) - (((define-public 'rust-bar-1 - (package - (name "rust-bar") - (version "1.0.0") - (source - (origin - (method url-fetch) - (uri (crate-uri "bar" 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))) - #:cargo-development-inputs - (("rust-leaf-bob" - ('unquote 'rust-leaf-bob-3.0.2-yanked)) - ("rust-leaf-bob" - ('unquote 'rust-leaf-bob-4.0.0-yanked)))))) - (home-page "http://example.com") - (synopsis "summary") - (description "This package provides summary.") - (license (list license:expat license:asl2.0))))) - #t) - (x - (pk 'fail x #f)))))) - -(unless have-guile-semver? (test-skip 1)) -(test-assert "crate-import-only-yanked-available" - (mock - ((guix http-client) http-fetch - (lambda (url . rest) - (match url - ("https://crates.io/api/v1/crates/bar" - (open-input-string test-bar-crate)) - ("https://crates.io/api/v1/crates/bar/1.0.0/download" - (set! test-source-hash - (bytevector->nix-base32-string - (gcrypt-sha256 (string->bytevector "empty file\n" "utf-8")))) - (open-input-string "empty file\n")) - ("https://crates.io/api/v1/crates/bar/1.0.0/dependencies" - (open-input-string test-bar-dependencies)) - ("https://crates.io/api/v1/crates/leaf-bob" - (open-input-string test-leaf-bob-crate)) - ("https://crates.io/api/v1/crates/leaf-bob/3.0.1/download" - (set! test-source-hash - (bytevector->nix-base32-string - (gcrypt-sha256 (string->bytevector "empty file\n" "utf-8")))) - (open-input-string "empty file\n")) - ("https://crates.io/api/v1/crates/leaf-bob/3.0.1/dependencies" - (open-input-string test-leaf-bob-dependencies)) - ("https://crates.io/api/v1/crates/leaf-bob/3.0.2/download" - (set! test-source-hash - (bytevector->nix-base32-string - (gcrypt-sha256 (string->bytevector "empty file\n" "utf-8")))) - (open-input-string "empty file\n")) - ("https://crates.io/api/v1/crates/leaf-bob/3.0.2/dependencies" - (open-input-string test-leaf-bob-dependencies)) - ("https://crates.io/api/v1/crates/leaf-bob/4.0.0/download" - (set! test-source-hash - (bytevector->nix-base32-string - (gcrypt-sha256 (string->bytevector "empty file\n" "utf-8")))) - (open-input-string "empty file\n")) - ("https://crates.io/api/v1/crates/leaf-bob/4.0.0/dependencies" - (open-input-string test-leaf-bob-dependencies)) - (_ (error "Unexpected URL: " url))))) - (match (crate-recursive-import "bar" - #:recursive-dev-dependencies? #t - #:allow-yanked? #t) - (((define-public 'rust-leaf-bob-4.0.0-yanked - (package - (name "rust-leaf-bob") - (version "4.0.0") - ($ <comment> "; This version was yanked!\n" #t) - (source - (origin - (method url-fetch) - (uri (crate-uri "leaf-bob" version)) - (file-name - (string-append name "-" version "-yanked.tar.gz")) - (sha256 - (base32 - (? string? hash))))) - (properties ('quote (('crate-version-yanked? . #t)))) - (build-system cargo-build-system) - (home-page "http://example.com") - (synopsis "summary") - (description "This package provides summary.") - (license (list license:expat license:asl2.0)))) - (define-public 'rust-leaf-bob-3.0.2-yanked - (package - (name "rust-leaf-bob") - (version "3.0.2") - ($ <comment> "; This version was yanked!\n" #t) - (source - (origin - (method url-fetch) - (uri (crate-uri "leaf-bob" version)) - (file-name - (string-append name "-" version "-yanked.tar.gz")) - (sha256 - (base32 - (? string? hash))))) - (properties ('quote (('crate-version-yanked? . #t)))) - (build-system cargo-build-system) - (home-page "http://example.com") - (synopsis "summary") - (description "This package provides 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 "This package provides summary.") - (license (list license:expat license:asl2.0)))) - (define-public 'rust-bar-1 - (package - (name "rust-bar") - (version "1.0.0") - (source - (origin - (method url-fetch) - (uri (crate-uri "bar" 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))) - #:cargo-development-inputs - (("rust-leaf-bob" - ('unquote 'rust-leaf-bob-3.0.2-yanked)) - ("rust-leaf-bob" - ('unquote 'rust-leaf-bob-4.0.0-yanked)))))) - (home-page "http://example.com") - (synopsis "summary") - (description "This package provides summary.") - (license (list license:expat license:asl2.0))))) - #t) - (x - (pk 'fail (pretty-print-with-comments (current-output-port) x) #f))))) - (test-assert "crate-lockfile-import" (begin |