From unknown Tue Jun 17 21:52:50 2025 X-Loop: help-debbugs@gnu.org Subject: [bug#36048] [PATCH] guix: import: hackage: handle hackage revisions Resent-From: Robert Vollmert Original-Sender: "Debbugs-submit" Resent-CC: guix-patches@gnu.org Resent-Date: Sat, 01 Jun 2019 22:37:02 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: report 36048 X-GNU-PR-Package: guix-patches X-GNU-PR-Keywords: patch To: 36048@debbugs.gnu.org Cc: Robert Vollmert X-Debbugs-Original-To: guix-patches@gnu.org Received: via spool by submit@debbugs.gnu.org id=B.155942862115382 (code B ref -1); Sat, 01 Jun 2019 22:37:02 +0000 Received: (at submit) by debbugs.gnu.org; 1 Jun 2019 22:37:01 +0000 Received: from localhost ([127.0.0.1]:38946 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1hXCcX-000401-5G for submit@debbugs.gnu.org; Sat, 01 Jun 2019 18:37:01 -0400 Received: from eggs.gnu.org ([209.51.188.92]:33566) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1hXCcU-0003zo-Do for submit@debbugs.gnu.org; Sat, 01 Jun 2019 18:36:59 -0400 Received: from lists.gnu.org ([209.51.188.17]:39389) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1hXCcP-0004VH-7I for submit@debbugs.gnu.org; Sat, 01 Jun 2019 18:36:53 -0400 Received: from eggs.gnu.org ([209.51.188.92]:47948) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1hXCcN-0006rq-C4 for guix-patches@gnu.org; Sat, 01 Jun 2019 18:36:53 -0400 X-Spam-Checker-Version: SpamAssassin 3.3.2 (2011-06-06) on eggs.gnu.org X-Spam-Level: X-Spam-Status: No, score=0.1 required=5.0 tests=BAYES_50,RCVD_IN_DNSWL_LOW, URIBL_BLOCKED autolearn=disabled version=3.3.2 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1hXCcL-0004Th-Kv for guix-patches@gnu.org; Sat, 01 Jun 2019 18:36:51 -0400 Received: from mx1.mailbox.org ([80.241.60.212]:27650) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1hXCcL-0004SJ-C6 for guix-patches@gnu.org; Sat, 01 Jun 2019 18:36:49 -0400 Received: from smtp1.mailbox.org (smtp1.mailbox.org [IPv6:2001:67c:2050:105:465:1:1:0]) (using TLSv1.2 with cipher ECDHE-RSA-CHACHA20-POLY1305 (256/256 bits)) (No client certificate requested) by mx1.mailbox.org (Postfix) with ESMTPS id 368E34E8DD; Sun, 2 Jun 2019 00:36:46 +0200 (CEST) X-Virus-Scanned: amavisd-new at heinlein-support.de Received: from smtp1.mailbox.org ([80.241.60.240]) by spamfilter01.heinlein-hosting.de (spamfilter01.heinlein-hosting.de [80.241.56.115]) (amavisd-new, port 10030) with ESMTP id c-kscZiOC9pD; Sun, 2 Jun 2019 00:36:37 +0200 (CEST) From: Robert Vollmert Date: Sun, 2 Jun 2019 00:36:36 +0200 Message-Id: <20190601223636.74362-1-rob@vllmrt.net> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 80.241.60.212 X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.6.x X-Spam-Score: -1.6 (-) X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -2.6 (--) Hackage packages can have metadata revision (cabal-file only) that aren't reflected in the source archive. haskell-build-system has support for this, but previously `guix import hackage` would create a definition based on the new cabal file but building using the old cabal file. Compare https://debbugs.gnu.org/cgi/bugreport.cgi?bug=3D35750. * guix/import/cabal.scm: Parse `x-revision:` property. * guix/import/hackage.scm: Compute hash of cabal file, and write cabal-revision build system arguments. * guix/tests/hackage.scm: Test import of cabal revision. --- guix/import/cabal.scm | 7 +++-- guix/import/hackage.scm | 61 ++++++++++++++++++++++++++++++----------- tests/hackage.scm | 46 +++++++++++++++++++++++++++++++ 3 files changed, 96 insertions(+), 18 deletions(-) diff --git a/guix/import/cabal.scm b/guix/import/cabal.scm index 1a87be0b00..7dfe771e41 100644 --- a/guix/import/cabal.scm +++ b/guix/import/cabal.scm @@ -40,6 +40,7 @@ cabal-package? cabal-package-name cabal-package-version + cabal-package-revision cabal-package-license cabal-package-home-page cabal-package-source-repository @@ -638,13 +639,14 @@ If #f use the function 'port-filename' to obtain it= ." ;; information of the Cabal file, but only the ones we currently are ;; interested in. (define-record-type - (make-cabal-package name version license home-page source-repository + (make-cabal-package name version revision license home-page source-rep= ository synopsis description executables lib test-suites flags eval-environment custom-setup) cabal-package? (name cabal-package-name) (version cabal-package-version) + (revision cabal-package-revision) (license cabal-package-license) (home-page cabal-package-home-page) (source-repository cabal-package-source-repository) @@ -838,6 +840,7 @@ See the manual for limitations."))))))) (define (cabal-evaluated-sexp->package evaluated-sexp) (let* ((name (lookup-join evaluated-sexp "name")) (version (lookup-join evaluated-sexp "version")) + (revision (lookup-join evaluated-sexp "x-revision")) (license (lookup-join evaluated-sexp "license")) (home-page (lookup-join evaluated-sexp "homepage")) (home-page-or-hackage @@ -856,7 +859,7 @@ See the manual for limitations."))))))) (custom-setup (match (make-cabal-section evaluated-sexp 'cust= om-setup) ((x) x) (_ #f)))) - (make-cabal-package name version license home-page-or-hackage + (make-cabal-package name version revision license home-page-or-hac= kage source-repository synopsis description executa= bles lib test-suites flags eval-environment custom-setu= p))) =20 diff --git a/guix/import/hackage.scm b/guix/import/hackage.scm index 366256b40d..cf8219143a 100644 --- a/guix/import/hackage.scm +++ b/guix/import/hackage.scm @@ -117,9 +117,15 @@ version is returned." (#f name) (m (match:substring m 1))))))) =20 -(define (hackage-fetch name-version) - "Return the Cabal file for the package NAME-VERSION, or #f on failure.= If -the version part is omitted from the package name, then return the lates= t +(define (read-cabal-and-hash port) + (let-values (((port get-hash) (open-sha256-input-port port))) + (cons + (read-cabal (canonical-newline-port port)) + (bytevector->nix-base32-string (get-hash))))) + +(define (hackage-fetch-and-hash name-version) + "Return the Cabal file and hash for the package NAME-VERSION, or #f on= failure. +If the version part is omitted from the package name, then return the la= test version." (guard (c ((and (http-get-error? c) (=3D 404 (http-get-error-code c))) @@ -127,10 +133,18 @@ version." (let-values (((name version) (package-name->name+version name-versio= n))) (let* ((url (hackage-cabal-url name version)) (port (http-fetch url)) - (result (read-cabal (canonical-newline-port port)))) + (result (read-cabal-and-hash port))) (close-port port) result)))) =20 +(define (hackage-fetch name-version) + "Return the Cabal file for the package NAME-VERSION, or #f on failure.= If +the version part is omitted from the package name, then return the lates= t +version." + (match (hackage-fetch-and-hash name-version) + ((cabal . hash) cabal) + (_ #f))) + (define string->license ;; List of valid values from ;; https://www.haskell.org @@ -198,15 +212,19 @@ package being processed and is used to filter refer= ences to itself." (cons own-name ghc-standard-libraries= )))) dependencies)) =20 -(define* (hackage-module->sexp cabal #:key (include-test-dependencies? #= t)) +(define* (hackage-module->sexp cabal cabal-hash #:key (include-test-depe= ndencies? #t)) "Return the `package' S-expression for a Cabal package. CABAL is the -representation of a Cabal file as produced by 'read-cabal'." +representation of a Cabal file as produced by 'read-cabal'. CABAL-HASH i= s +the hash of the Cabal file." =20 (define name (cabal-package-name cabal)) =20 (define version (cabal-package-version cabal)) + + (define revision + (cabal-package-revision cabal)) =20 (define source-url (hackage-source-url name version)) @@ -252,9 +270,17 @@ representation of a Cabal file as produced by 'read-= cabal'." (list 'quasiquote inputs)))))) =20 (define (maybe-arguments) - (if (not include-test-dependencies?) - '((arguments `(#:tests? #f))) - '())) + (define testargs (if (not include-test-dependencies?) + '(#:tests? #f) + '())) + (define revargs (if (not (string-null? revision)) + `(#:cabal-revision (,revision ,cabal-hash)) + '())) + (define args (append testargs revargs)) + (if (not (nil? args)) + (let ((qargs `(,'quasiquote ,args))) + `((arguments ,qargs))) + '())) =20 (let ((tarball (with-store store (download-to-store store source-url)))) @@ -294,13 +320,16 @@ symbol 'true' or 'false'. The value associated wit= h other keys has to conform to the Cabal file format definition. The default value associated with = the keys \"os\", \"arch\" and \"impl\" is \"linux\", \"x86_64\" and \"ghc\" respectively." - (let ((cabal-meta (if port - (read-cabal (canonical-newline-port port)) - (hackage-fetch package-name)))) - (and=3D> cabal-meta (compose (cut hackage-module->sexp <> - #:include-test-dependencies? - include-test-dependencies?) - (cut eval-cabal <> cabal-environment))))) + (match + (if port (read-cabal-and-hash port) + (hackage-fetch-and-hash package-name)) + ((cabal-meta . cabal-hash) + (and=3D> cabal-meta (compose (cut hackage-module->sexp <> + cabal-hash + #:include-test-dependencies? + include-test-dependencies?) + (cut eval-cabal <> cabal-environment)))) + (_ #f))) =20 (define hackage->guix-package/m ;memoized variant (memoize hackage->guix-package)) diff --git a/tests/hackage.scm b/tests/hackage.scm index 38a5825af7..fe4e0efb69 100644 --- a/tests/hackage.scm +++ b/tests/hackage.scm @@ -274,6 +274,52 @@ executable cabal (test-assert "hackage->guix-package test multiline desc (braced)" (eval-test-with-cabal test-cabal-multiline-braced match-ghc-foo)) =20 +;; test hackage cabal revisions +(define test-cabal-revision + "name: foo +version: 1.0.0 +x-revision: 2 +homepage: http://test.org +synopsis: synopsis +description: description +license: BSD3 +executable cabal + build-depends: + HTTP >=3D 4000.2.5 && < 4000.3, + mtl >=3D 2.0 && < 3 +") + +(define-package-matcher match-ghc-foo-revision + ('package + ('name "ghc-foo") + ('version "1.0.0") + ('source + ('origin + ('method 'url-fetch) + ('uri ('string-append + "https://hackage.haskell.org/package/foo/foo-" + 'version + ".tar.gz")) + ('sha256 + ('base32 + (? string? hash))))) + ('build-system 'haskell-build-system) + ('inputs + ('quasiquote + (("ghc-http" ('unquote 'ghc-http))))) + ('arguments + ('quasiquote + ('#:cabal-revision + ("2" "0xxd88fb659f0krljidbvvmkh9ppjnx83j0nqzx8whcg4n5qbyng")))) + ('home-page "http://test.org") + ('synopsis (? string?)) + ('description (? string?)) + ('license 'bsd-3))) + +(test-assert "hackage->guix-package test cabal revision" + (eval-test-with-cabal test-cabal-revision match-ghc-foo-revision)) + + (test-assert "read-cabal test 1" (match (call-with-input-string test-read-cabal-1 read-cabal) ((("name" ("test-me")) --=20 2.20.1 (Apple Git-117) From unknown Tue Jun 17 21:52:50 2025 X-Loop: help-debbugs@gnu.org Subject: [bug#36048] [PATCH] guix: import: hackage: handle hackage revisions Resent-From: Timothy Sample Original-Sender: "Debbugs-submit" Resent-CC: guix-patches@gnu.org Resent-Date: Thu, 13 Jun 2019 02:29:02 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 36048 X-GNU-PR-Package: guix-patches X-GNU-PR-Keywords: patch To: Robert Vollmert Cc: 36048@debbugs.gnu.org Received: via spool by 36048-submit@debbugs.gnu.org id=B36048.156039293111202 (code B ref 36048); Thu, 13 Jun 2019 02:29:02 +0000 Received: (at 36048) by debbugs.gnu.org; 13 Jun 2019 02:28:51 +0000 Received: from localhost ([127.0.0.1]:34315 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1hbFTq-0002uU-VE for submit@debbugs.gnu.org; Wed, 12 Jun 2019 22:28:51 -0400 Received: from wout3-smtp.messagingengine.com ([64.147.123.19]:48597) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1hbFTm-0002u2-Te for 36048@debbugs.gnu.org; Wed, 12 Jun 2019 22:28:45 -0400 Received: from compute4.internal (compute4.nyi.internal [10.202.2.44]) by mailout.west.internal (Postfix) with ESMTP id 1E336796; Wed, 12 Jun 2019 22:28:37 -0400 (EDT) Received: from mailfrontend2 ([10.202.2.163]) by compute4.internal (MEProxy); Wed, 12 Jun 2019 22:28:37 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d= messagingengine.com; h=cc:content-transfer-encoding:content-type :date:from:in-reply-to:message-id:mime-version:references :subject:to:x-me-proxy:x-me-proxy:x-me-sender:x-me-sender :x-sasl-enc; s=fm3; bh=e5dTt8vAT8dhh0E9yRUfuM/j4IaSan+lFx3QuGrNI C8=; b=c1a8y/EsWVcqVOClM+lQ7WEHfIOv7hNSwT1jh9Gfz1S61nP6uEOUygbsm 2NjYTEEaKBiZoox/+ihMbjclLM43IeXrULbIRe5eOdi2rLp0NDdcaySvZz1Ur/Jh Ar1XnIxvZmAlE2oVR4ltTDqWCu0qyEuSzAT6IIMWtij3FjuHcBDVtPvQhcqQ6u8h uu0+2dSXwdF1GPCiK+iucvVFioyGZcPZ93HTqgGgxM9VnbEi5rY3e3+yz9oN5/4P Z+lVU/maqpbvK9j/goyFtuh1oYAmOYVx7B74a4dCwMkz5dS6entwgQhbsxBt4rum UvSt0MmDowL6CLBIQvUlp4rvcF0Kg== X-ME-Sender: X-ME-Proxy-Cause: gggruggvucftvghtrhhoucdtuddrgeduuddrudehkedgheelucetufdoteggodetrfdotf fvucfrrhhofhhilhgvmecuhfgrshhtofgrihhlpdfqfgfvpdfurfetoffkrfgpnffqhgen uceurghilhhouhhtmecufedttdenucenucfjughrpefhvffufhffjgfkfgggtgfgsehtqh ertddtreejnecuhfhrohhmpefvihhmohhthhihucfurghmphhlvgcuoehsrghmphhlvght sehnghihrhhordgtohhmqeenucffohhmrghinhepthgvshhtrdhorhhgpdhhrghskhgvlh hlrdhorhhgpdhgnhhurdhorhhgnecukfhppeejgedrudduiedrudekiedrgeegnecurfgr rhgrmhepmhgrihhlfhhrohhmpehsrghmphhlvghtsehnghihrhhordgtohhmnecuvehluh hsthgvrhfuihiivgeptd X-ME-Proxy: Received: from mrblack (74-116-186-44.qc.dsl.ebox.net [74.116.186.44]) by mail.messagingengine.com (Postfix) with ESMTPA id A3DA9380087; Wed, 12 Jun 2019 22:28:35 -0400 (EDT) From: Timothy Sample References: <20190601223636.74362-1-rob@vllmrt.net> Date: Wed, 12 Jun 2019 22:28:35 -0400 In-Reply-To: <20190601223636.74362-1-rob@vllmrt.net> (Robert Vollmert's message of "Sun, 2 Jun 2019 00:36:36 +0200") Message-ID: <87sgse43sc.fsf@ngyro.com> User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/26.2 (gnu/linux) MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: quoted-printable X-Spam-Score: -0.7 (/) X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -1.7 (-) Hi Robert, Thanks for the patch, and thanks for the work you=E2=80=99ve been doing in general on the Haskell packages and tools in Guix! Robert Vollmert writes: > Hackage packages can have metadata revision (cabal-file only) > that aren't reflected in the source archive. haskell-build-system > has support for this, but previously `guix import hackage` would > create a definition based on the new cabal file but building using > the old cabal file. > > Compare https://debbugs.gnu.org/cgi/bugreport.cgi?bug=3D35750. > > > * guix/import/cabal.scm: Parse `x-revision:` property. > * guix/import/hackage.scm: Compute hash of cabal file, and write > cabal-revision build system arguments. > * guix/tests/hackage.scm: Test import of cabal revision. > --- > guix/import/cabal.scm | 7 +++-- > guix/import/hackage.scm | 61 ++++++++++++++++++++++++++++++----------- > tests/hackage.scm | 46 +++++++++++++++++++++++++++++++ > 3 files changed, 96 insertions(+), 18 deletions(-) > > diff --git a/guix/import/cabal.scm b/guix/import/cabal.scm > index 1a87be0b00..7dfe771e41 100644 > --- a/guix/import/cabal.scm > +++ b/guix/import/cabal.scm > @@ -40,6 +40,7 @@ > cabal-package? > cabal-package-name > cabal-package-version > + cabal-package-revision > cabal-package-license > cabal-package-home-page > cabal-package-source-repository > @@ -638,13 +639,14 @@ If #f use the function 'port-filename' to obtain it= ." > ;; information of the Cabal file, but only the ones we currently are > ;; interested in. > (define-record-type > - (make-cabal-package name version license home-page source-repository > + (make-cabal-package name version revision license home-page source-rep= ository > synopsis description > executables lib test-suites > flags eval-environment custom-setup) > cabal-package? > (name cabal-package-name) > (version cabal-package-version) > + (revision cabal-package-revision) > (license cabal-package-license) > (home-page cabal-package-home-page) > (source-repository cabal-package-source-repository) > @@ -838,6 +840,7 @@ See the manual for limitations."))))))) > (define (cabal-evaluated-sexp->package evaluated-sexp) > (let* ((name (lookup-join evaluated-sexp "name")) > (version (lookup-join evaluated-sexp "version")) > + (revision (lookup-join evaluated-sexp "x-revision")) > (license (lookup-join evaluated-sexp "license")) > (home-page (lookup-join evaluated-sexp "homepage")) > (home-page-or-hackage > @@ -856,7 +859,7 @@ See the manual for limitations."))))))) > (custom-setup (match (make-cabal-section evaluated-sexp 'cust= om-setup) > ((x) x) > (_ #f)))) > - (make-cabal-package name version license home-page-or-hackage > + (make-cabal-package name version revision license home-page-or-hac= kage > source-repository synopsis description executa= bles lib > test-suites flags eval-environment custom-setu= p))) >=20=20 > diff --git a/guix/import/hackage.scm b/guix/import/hackage.scm > index 366256b40d..cf8219143a 100644 > --- a/guix/import/hackage.scm > +++ b/guix/import/hackage.scm > @@ -117,9 +117,15 @@ version is returned." > (#f name) > (m (match:substring m 1))))))) >=20=20 > -(define (hackage-fetch name-version) > - "Return the Cabal file for the package NAME-VERSION, or #f on failure.= If > -the version part is omitted from the package name, then return the latest > +(define (read-cabal-and-hash port) This procedure should have a docstring. > + (let-values (((port get-hash) (open-sha256-input-port port))) > + (cons > + (read-cabal (canonical-newline-port port)) > + (bytevector->nix-base32-string (get-hash))))) The indentation here is wrong. In general, list elements all line up with each other, so everything would be under the =E2=80=98c=E2=80=99 of = =E2=80=9Ccons=E2=80=9D. There are exceptions to this, but they=E2=80=99re mostly for special block-like f= orms such as =E2=80=9Clet=E2=80=9D and =E2=80=9Cbegin=E2=80=9D. However, I thin= k Schemers tend to avoid putting a line break after the procedure when applying. That is, it would be more conventionally formatted as: (cons (read-cabal (canonical-newline-port port)) (bytevector->nix-base32-string (get-hash))) Also, I think returning multiple values would be more natural here (i.e., replace =E2=80=9Ccons=E2=80=9D with =E2=80=9Cvalues=E2=80=9D). > + > +(define (hackage-fetch-and-hash name-version) > + "Return the Cabal file and hash for the package NAME-VERSION, or #f on= failure. Here, it would be clearer to mention the shape of the return value as well. For the =E2=80=9Cvalues=E2=80=9D version, it would be something like= =E2=80=9CReturn two values: the Cabal file for the package NAME-VERSION and its hash....=E2=80= =9D I cribbed this wording from the Guile manual, but I worry that the referent of that last =E2=80=9Cits=E2=80=9D is not clear. It=E2=80=99s pro= bably good enough, but maybe you can do better. ;) It=E2=80=99s the =E2=80=9Ctwo values=E2= =80=9D part that=E2=80=99s important. Also, please try to keep the line lengths under 80 columns. > +If the version part is omitted from the package name, then return the la= test > version." > (guard (c ((and (http-get-error? c) > (=3D 404 (http-get-error-code c))) > @@ -127,10 +133,18 @@ version." > (let-values (((name version) (package-name->name+version name-versio= n))) > (let* ((url (hackage-cabal-url name version)) > (port (http-fetch url)) > - (result (read-cabal (canonical-newline-port port)))) > + (result (read-cabal-and-hash port))) > (close-port port) > result)))) >=20=20 > +(define (hackage-fetch name-version) > + "Return the Cabal file for the package NAME-VERSION, or #f on failure.= If > +the version part is omitted from the package name, then return the latest > +version." > + (match (hackage-fetch-and-hash name-version) > + ((cabal . hash) cabal) > + (_ #f))) > + This will have to become a =E2=80=9Clet-values=E2=80=9D form. > (define string->license > ;; List of valid values from > ;; https://www.haskell.org > @@ -198,15 +212,19 @@ package being processed and is used to filter refer= ences to itself." > (cons own-name ghc-standard-libraries= )))) > dependencies)) >=20=20 > -(define* (hackage-module->sexp cabal #:key (include-test-dependencies? #= t)) > +(define* (hackage-module->sexp cabal cabal-hash #:key (include-test-depe= ndencies? #t)) Another long line. You could line up =E2=80=9C#:key=E2=80=9D under the fir= st =E2=80=9Ccabal=E2=80=9D. > "Return the `package' S-expression for a Cabal package. CABAL is the > -representation of a Cabal file as produced by 'read-cabal'." > +representation of a Cabal file as produced by 'read-cabal'. CABAL-HASH is There should be two spaces after a period ------------------^ > +the hash of the Cabal file." >=20=20 > (define name > (cabal-package-name cabal)) >=20=20 > (define version > (cabal-package-version cabal)) > + > + (define revision > + (cabal-package-revision cabal)) >=20=20=20=20 > (define source-url > (hackage-source-url name version)) > @@ -252,9 +270,17 @@ representation of a Cabal file as produced by 'read-= cabal'." > (list 'quasiquote inputs)))))) >=20=20=20=20 > (define (maybe-arguments) > - (if (not include-test-dependencies?) > - '((arguments `(#:tests? #f))) > - '())) > + (define testargs (if (not include-test-dependencies?) > + '(#:tests? #f) > + '())) > + (define revargs (if (not (string-null? revision)) > + `(#:cabal-revision (,revision ,cabal-hash)) > + '())) > + (define args (append testargs revargs)) > + (if (not (nil? args)) > + (let ((qargs `(,'quasiquote ,args))) > + `((arguments ,qargs))) > + '())) I think that this would be a little clearer using =E2=80=9Cmatch=E2=80=9D a= nd without the intermediary definitions: (match (append (if (not include-test-dependencies?) '(#:tests? #f) '()) (if (not (string-null? revision)) `(#:cabal-revision (,revision ,cabal-hash)) '())) (() '()) (args `((arguments (,'quasiquote ,args))))) >=20=20 > (let ((tarball (with-store store > (download-to-store store source-url)))) > @@ -294,13 +320,16 @@ symbol 'true' or 'false'. The value associated wit= h other keys has to conform > to the Cabal file format definition. The default value associated with = the > keys \"os\", \"arch\" and \"impl\" is \"linux\", \"x86_64\" and \"ghc\" > respectively." > - (let ((cabal-meta (if port > - (read-cabal (canonical-newline-port port)) > - (hackage-fetch package-name)))) > - (and=3D> cabal-meta (compose (cut hackage-module->sexp <> > - #:include-test-dependencies? > - include-test-dependencies?) > - (cut eval-cabal <> cabal-environment))))) > + (match > + (if port (read-cabal-and-hash port) > + (hackage-fetch-and-hash package-name)) > + ((cabal-meta . cabal-hash) > + (and=3D> cabal-meta (compose (cut hackage-module->sexp <> > + cabal-hash > + #:include-test-dependencies? > + include-test-dependencies?) > + (cut eval-cabal <> cabal-environment)))) > + (_ #f))) This will also need to be a =E2=80=9Clet-values=E2=80=9D form for the multi= ple values. Fortunately, it will look almost identical to the old =E2=80=9Clet=E2=80=9D= form, so that=E2=80=99s kinda nice (if you=E2=80=99re as easily amused as I am). :) > (define hackage->guix-package/m ;memoized variant > (memoize hackage->guix-package)) > diff --git a/tests/hackage.scm b/tests/hackage.scm > index 38a5825af7..fe4e0efb69 100644 > --- a/tests/hackage.scm > +++ b/tests/hackage.scm > @@ -274,6 +274,52 @@ executable cabal > (test-assert "hackage->guix-package test multiline desc (braced)" > (eval-test-with-cabal test-cabal-multiline-braced match-ghc-foo)) >=20=20 > +;; test hackage cabal revisions To be consistent with the other comments in the file, I would suggest: ;; Check Hackage Cabal revisions. (I know that some of the comments are missing a period at the end, but most of them have it, and it should be there.) > +(define test-cabal-revision > + "name: foo > +version: 1.0.0 > +x-revision: 2 > +homepage: http://test.org > +synopsis: synopsis > +description: description > +license: BSD3 > +executable cabal > + build-depends: > + HTTP >=3D 4000.2.5 && < 4000.3, > + mtl >=3D 2.0 && < 3 > +") > + > +(define-package-matcher match-ghc-foo-revision > + ('package > + ('name "ghc-foo") > + ('version "1.0.0") > + ('source > + ('origin > + ('method 'url-fetch) > + ('uri ('string-append > + "https://hackage.haskell.org/package/foo/foo-" > + 'version > + ".tar.gz")) > + ('sha256 > + ('base32 > + (? string? hash))))) > + ('build-system 'haskell-build-system) > + ('inputs > + ('quasiquote > + (("ghc-http" ('unquote 'ghc-http))))) > + ('arguments > + ('quasiquote > + ('#:cabal-revision > + ("2" "0xxd88fb659f0krljidbvvmkh9ppjnx83j0nqzx8whcg4n5qbyng")))) > + ('home-page "http://test.org") > + ('synopsis (? string?)) > + ('description (? string?)) > + ('license 'bsd-3))) > + > +(test-assert "hackage->guix-package test cabal revision" > + (eval-test-with-cabal test-cabal-revision match-ghc-foo-revision)) > + > + I think there=E2=80=99s an extra line break here. > (test-assert "read-cabal test 1" > (match (call-with-input-string test-read-cabal-1 read-cabal) > ((("name" ("test-me")) Overall, it looks pretty good. Bonus points for including a test! With the few tweaks I mentioned, I think it will be ready to go. Thanks again. -- Tim From unknown Tue Jun 17 21:52:50 2025 X-Loop: help-debbugs@gnu.org Subject: [bug#36048] [PATCH] guix: import: hackage: handle hackage revisions References: <20190601223636.74362-1-rob@vllmrt.net> In-Reply-To: <20190601223636.74362-1-rob@vllmrt.net> Resent-From: Robert Vollmert Original-Sender: "Debbugs-submit" Resent-CC: guix-patches@gnu.org Resent-Date: Thu, 13 Jun 2019 16:04:02 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 36048 X-GNU-PR-Package: guix-patches X-GNU-PR-Keywords: patch To: 36048@debbugs.gnu.org Cc: Robert Vollmert Received: via spool by 36048-submit@debbugs.gnu.org id=B36048.156044180930575 (code B ref 36048); Thu, 13 Jun 2019 16:04:02 +0000 Received: (at 36048) by debbugs.gnu.org; 13 Jun 2019 16:03:29 +0000 Received: from localhost ([127.0.0.1]:35932 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1hbSCH-0007x4-0H for submit@debbugs.gnu.org; Thu, 13 Jun 2019 12:03:29 -0400 Received: from mx1.mailbox.org ([80.241.60.212]:50982) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1hbSCE-0007wi-0T for 36048@debbugs.gnu.org; Thu, 13 Jun 2019 12:03:27 -0400 Received: from smtp1.mailbox.org (smtp1.mailbox.org [80.241.60.240]) (using TLSv1.2 with cipher ECDHE-RSA-CHACHA20-POLY1305 (256/256 bits)) (No client certificate requested) by mx1.mailbox.org (Postfix) with ESMTPS id C6C5D4D99D; Thu, 13 Jun 2019 18:03:19 +0200 (CEST) X-Virus-Scanned: amavisd-new at heinlein-support.de Received: from smtp1.mailbox.org ([80.241.60.240]) by hefe.heinlein-support.de (hefe.heinlein-support.de [91.198.250.172]) (amavisd-new, port 10030) with ESMTP id iQfd2BHYuXJQ; Thu, 13 Jun 2019 18:03:13 +0200 (CEST) From: Robert Vollmert Date: Thu, 13 Jun 2019 18:02:29 +0200 Message-Id: <20190613160228.10875-1-rob@vllmrt.net> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Spam-Score: -0.7 (/) X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -1.7 (-) Hackage packages can have metadata revision (cabal-file only) that aren't reflected in the source archive. haskell-build-system has support for this, but previously `guix import hackage` would create a definition based on the new cabal file but building using the old cabal file. Compare https://debbugs.gnu.org/cgi/bugreport.cgi?bug=35750. * guix/import/cabal.scm: Parse `x-revision:` property. * guix/import/hackage.scm: Compute hash of cabal file, and write cabal-revision build system arguments. * guix/tests/hackage.scm: Test import of cabal revision. --- Revised patch which addresses the formatting and documentation concernse, but not yet the multiple return values. guix/import/cabal.scm | 7 +++-- guix/import/hackage.scm | 61 +++++++++++++++++++++++++++++------------ tests/hackage.scm | 45 ++++++++++++++++++++++++++++++ 3 files changed, 94 insertions(+), 19 deletions(-) diff --git a/guix/import/cabal.scm b/guix/import/cabal.scm index 1a87be0b00..7dfe771e41 100644 --- a/guix/import/cabal.scm +++ b/guix/import/cabal.scm @@ -40,6 +40,7 @@ cabal-package? cabal-package-name cabal-package-version + cabal-package-revision cabal-package-license cabal-package-home-page cabal-package-source-repository @@ -638,13 +639,14 @@ If #f use the function 'port-filename' to obtain it." ;; information of the Cabal file, but only the ones we currently are ;; interested in. (define-record-type - (make-cabal-package name version license home-page source-repository + (make-cabal-package name version revision license home-page source-repository synopsis description executables lib test-suites flags eval-environment custom-setup) cabal-package? (name cabal-package-name) (version cabal-package-version) + (revision cabal-package-revision) (license cabal-package-license) (home-page cabal-package-home-page) (source-repository cabal-package-source-repository) @@ -838,6 +840,7 @@ See the manual for limitations."))))))) (define (cabal-evaluated-sexp->package evaluated-sexp) (let* ((name (lookup-join evaluated-sexp "name")) (version (lookup-join evaluated-sexp "version")) + (revision (lookup-join evaluated-sexp "x-revision")) (license (lookup-join evaluated-sexp "license")) (home-page (lookup-join evaluated-sexp "homepage")) (home-page-or-hackage @@ -856,7 +859,7 @@ See the manual for limitations."))))))) (custom-setup (match (make-cabal-section evaluated-sexp 'custom-setup) ((x) x) (_ #f)))) - (make-cabal-package name version license home-page-or-hackage + (make-cabal-package name version revision license home-page-or-hackage source-repository synopsis description executables lib test-suites flags eval-environment custom-setup))) diff --git a/guix/import/hackage.scm b/guix/import/hackage.scm index 366256b40d..2853037797 100644 --- a/guix/import/hackage.scm +++ b/guix/import/hackage.scm @@ -117,20 +117,34 @@ version is returned." (#f name) (m (match:substring m 1))))))) -(define (hackage-fetch name-version) - "Return the Cabal file for the package NAME-VERSION, or #f on failure. If -the version part is omitted from the package name, then return the latest -version." +(define (read-cabal-and-hash port) + "Read a cabal file and its base32 hash from a port." + (let-values (((port get-hash) (open-sha256-input-port port))) + (cons (read-cabal (canonical-newline-port port)) + (bytevector->nix-base32-string (get-hash))))) + +(define (hackage-fetch-and-hash name-version) + "Return the Cabal file and hash for the package NAME-VERSION, or #f on +failure. If the version part is omitted from the package name, then return +the latest version." (guard (c ((and (http-get-error? c) (= 404 (http-get-error-code c))) #f)) ;"expected" if package is unknown (let-values (((name version) (package-name->name+version name-version))) (let* ((url (hackage-cabal-url name version)) (port (http-fetch url)) - (result (read-cabal (canonical-newline-port port)))) + (result (read-cabal-and-hash port))) (close-port port) result)))) +(define (hackage-fetch name-version) + "Return the Cabal file for the package NAME-VERSION, or #f on failure. If +the version part is omitted from the package name, then return the latest +version." + (match (hackage-fetch-and-hash name-version) + ((cabal . hash) cabal) + (_ #f))) + (define string->license ;; List of valid values from ;; https://www.haskell.org @@ -198,15 +212,20 @@ package being processed and is used to filter references to itself." (cons own-name ghc-standard-libraries)))) dependencies)) -(define* (hackage-module->sexp cabal #:key (include-test-dependencies? #t)) +(define* (hackage-module->sexp cabal cabal-hash + #:key (include-test-dependencies? #t)) "Return the `package' S-expression for a Cabal package. CABAL is the -representation of a Cabal file as produced by 'read-cabal'." +representation of a Cabal file as produced by 'read-cabal'. CABAL-HASH is +the hash of the Cabal file." (define name (cabal-package-name cabal)) (define version (cabal-package-version cabal)) + + (define revision + (cabal-package-revision cabal)) (define source-url (hackage-source-url name version)) @@ -252,9 +271,14 @@ representation of a Cabal file as produced by 'read-cabal'." (list 'quasiquote inputs)))))) (define (maybe-arguments) - (if (not include-test-dependencies?) - '((arguments `(#:tests? #f))) - '())) + (match (append (if (not include-test-dependencies?) + '(#:tests? #f) + '()) + (if (not (string-null? revision)) + `(#:cabal-revision (,revision ,cabal-hash)) + '())) + (() '()) + (args `((arguments (,'quasiquote ,args)))))) (let ((tarball (with-store store (download-to-store store source-url)))) @@ -294,13 +318,16 @@ symbol 'true' or 'false'. The value associated with other keys has to conform to the Cabal file format definition. The default value associated with the keys \"os\", \"arch\" and \"impl\" is \"linux\", \"x86_64\" and \"ghc\" respectively." - (let ((cabal-meta (if port - (read-cabal (canonical-newline-port port)) - (hackage-fetch package-name)))) - (and=> cabal-meta (compose (cut hackage-module->sexp <> - #:include-test-dependencies? - include-test-dependencies?) - (cut eval-cabal <> cabal-environment))))) + (match + (if port (read-cabal-and-hash port) + (hackage-fetch-and-hash package-name)) + ((cabal-meta . cabal-hash) + (and=> cabal-meta (compose (cut hackage-module->sexp <> + cabal-hash + #:include-test-dependencies? + include-test-dependencies?) + (cut eval-cabal <> cabal-environment)))) + (_ #f))) (define hackage->guix-package/m ;memoized variant (memoize hackage->guix-package)) diff --git a/tests/hackage.scm b/tests/hackage.scm index 38a5825af7..14176b2cf9 100644 --- a/tests/hackage.scm +++ b/tests/hackage.scm @@ -274,6 +274,51 @@ executable cabal (test-assert "hackage->guix-package test multiline desc (braced)" (eval-test-with-cabal test-cabal-multiline-braced match-ghc-foo)) +;; Check Hackage Cabal revisions. +(define test-cabal-revision + "name: foo +version: 1.0.0 +x-revision: 2 +homepage: http://test.org +synopsis: synopsis +description: description +license: BSD3 +executable cabal + build-depends: + HTTP >= 4000.2.5 && < 4000.3, + mtl >= 2.0 && < 3 +") + +(define-package-matcher match-ghc-foo-revision + ('package + ('name "ghc-foo") + ('version "1.0.0") + ('source + ('origin + ('method 'url-fetch) + ('uri ('string-append + "https://hackage.haskell.org/package/foo/foo-" + 'version + ".tar.gz")) + ('sha256 + ('base32 + (? string? hash))))) + ('build-system 'haskell-build-system) + ('inputs + ('quasiquote + (("ghc-http" ('unquote 'ghc-http))))) + ('arguments + ('quasiquote + ('#:cabal-revision + ("2" "0xxd88fb659f0krljidbvvmkh9ppjnx83j0nqzx8whcg4n5qbyng")))) + ('home-page "http://test.org") + ('synopsis (? string?)) + ('description (? string?)) + ('license 'bsd-3))) + +(test-assert "hackage->guix-package test cabal revision" + (eval-test-with-cabal test-cabal-revision match-ghc-foo-revision)) + (test-assert "read-cabal test 1" (match (call-with-input-string test-read-cabal-1 read-cabal) ((("name" ("test-me")) -- 2.20.1 (Apple Git-117) From unknown Tue Jun 17 21:52:50 2025 X-Loop: help-debbugs@gnu.org Subject: [bug#36048] [PATCH] guix: import: hackage: handle hackage revisions Resent-From: Robert Vollmert Original-Sender: "Debbugs-submit" Resent-CC: guix-patches@gnu.org Resent-Date: Thu, 13 Jun 2019 16:12:01 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 36048 X-GNU-PR-Package: guix-patches X-GNU-PR-Keywords: patch To: Timothy Sample Cc: 36048@debbugs.gnu.org Received: via spool by 36048-submit@debbugs.gnu.org id=B36048.156044227431624 (code B ref 36048); Thu, 13 Jun 2019 16:12:01 +0000 Received: (at 36048) by debbugs.gnu.org; 13 Jun 2019 16:11:14 +0000 Received: from localhost ([127.0.0.1]:35951 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1hbSJl-0008E0-Tv for submit@debbugs.gnu.org; Thu, 13 Jun 2019 12:11:14 -0400 Received: from mx1.mailbox.org ([80.241.60.212]:27528) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1hbSJk-0008Dg-4M for 36048@debbugs.gnu.org; Thu, 13 Jun 2019 12:11:12 -0400 Received: from smtp2.mailbox.org (smtp2.mailbox.org [80.241.60.241]) (using TLSv1.2 with cipher ECDHE-RSA-CHACHA20-POLY1305 (256/256 bits)) (No client certificate requested) by mx1.mailbox.org (Postfix) with ESMTPS id 0BB1E4EBB2; Thu, 13 Jun 2019 18:11:05 +0200 (CEST) X-Virus-Scanned: amavisd-new at heinlein-support.de Received: from smtp2.mailbox.org ([80.241.60.241]) by spamfilter04.heinlein-hosting.de (spamfilter04.heinlein-hosting.de [80.241.56.122]) (amavisd-new, port 10030) with ESMTP id T7DCt4ciB-7A; Thu, 13 Jun 2019 18:11:02 +0200 (CEST) Content-Type: text/plain; charset=utf-8 Mime-Version: 1.0 (Mac OS X Mail 12.4 \(3445.104.11\)) From: Robert Vollmert In-Reply-To: <87sgse43sc.fsf@ngyro.com> Date: Thu, 13 Jun 2019 18:11:00 +0200 Content-Transfer-Encoding: quoted-printable Message-Id: References: <20190601223636.74362-1-rob@vllmrt.net> <87sgse43sc.fsf@ngyro.com> X-Spam-Score: -0.7 (/) X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -1.7 (-) Hi Timothy, thanks for the detailed feedback, this is very helpful! I=E2=80=99ve sent an updated patch addressing some of the concerns, but = have some questions regarding others. (I just realized that the documentation updates probably anticipate multiple return values.) > On 13. Jun 2019, at 04:28, Timothy Sample wrote: >> + (let-values (((port get-hash) (open-sha256-input-port port))) >> + (cons >> + (read-cabal (canonical-newline-port port)) >> + (bytevector->nix-base32-string (get-hash))))) [=E2=80=A6] > Also, I think returning multiple values would be more natural here > (i.e., replace =E2=80=9Ccons=E2=80=9D with =E2=80=9Cvalues=E2=80=9D). I tried building it that way to begin with, but I=E2=80=99m having = issues making it work (nicely, or maybe at all). I think it comes down to later functions optionally failing with a single #f-value. Judging by the lack of infrastructure, I imagine functions that return different numbers of values are not idiomatic scheme. Should this be changed to return two values (#f #f) on failure? Or to raise an exception and handle it higher up when we want to ignore a failure? Currently, implementing this with values/let-values results in me doing more or less a combination of let-values and match, at which point it seems that any potential benefits of using multiple values as opposed to a pair/list are lost. (There=E2=80=99s no match-values = form is there?) Cheers Rob From unknown Tue Jun 17 21:52:50 2025 X-Loop: help-debbugs@gnu.org Subject: [bug#36048] [PATCH] guix: import: hackage: handle hackage revisions Resent-From: Timothy Sample Original-Sender: "Debbugs-submit" Resent-CC: guix-patches@gnu.org Resent-Date: Thu, 13 Jun 2019 18:10:02 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 36048 X-GNU-PR-Package: guix-patches X-GNU-PR-Keywords: patch To: Robert Vollmert Cc: 36048@debbugs.gnu.org Received: via spool by 36048-submit@debbugs.gnu.org id=B36048.156044936212105 (code B ref 36048); Thu, 13 Jun 2019 18:10:02 +0000 Received: (at 36048) by debbugs.gnu.org; 13 Jun 2019 18:09:22 +0000 Received: from localhost ([127.0.0.1]:36073 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1hbUA5-00039A-NN for submit@debbugs.gnu.org; Thu, 13 Jun 2019 14:09:22 -0400 Received: from wout3-smtp.messagingengine.com ([64.147.123.19]:57397) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1hbUA3-00038v-6s for 36048@debbugs.gnu.org; Thu, 13 Jun 2019 14:09:20 -0400 Received: from compute4.internal (compute4.nyi.internal [10.202.2.44]) by mailout.west.internal (Postfix) with ESMTP id 02568438; Thu, 13 Jun 2019 14:09:12 -0400 (EDT) Received: from mailfrontend2 ([10.202.2.163]) by compute4.internal (MEProxy); Thu, 13 Jun 2019 14:09:13 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d= messagingengine.com; h=cc:content-type:date:from:in-reply-to :message-id:mime-version:references:subject:to:x-me-proxy :x-me-proxy:x-me-sender:x-me-sender:x-sasl-enc; s=fm3; bh=p28jQ5 3LVruCTCnaGdHGDHkxi7cpgNC50jPE59tZEEU=; b=RaEwpmuQGDHujvu9w86Hkc CUAsBH+6kF3AW7afP6mgcWvrbB5Zi272Uv6qIkp2zCu8KdITOnteLe+NpbAHQUkC 6kG2FYliJo5TTR6d/NLhJAddj6ko/qeRJDTq6N4zLMbaDWUI7I1zEAqbQAPyZmWP VNbIQtkddNVfQlgK/IHV2Rx3jtu1M5DopE/yg80WRQZX+y9eRx+qqx6VirzsA3Lp Z5o1/uIAC0SK4W3JhavVcAKLzBxoXWB/HBET5Vn44RR3Zvh/Bv/Y1PxCTC4/lYfP vfNnoj8cAr25TmGOB+FLcyWJJckpe/d0mhgClabBVjoMy2EgkeWZH8icGUQJT5mQ == X-ME-Sender: X-ME-Proxy-Cause: gggruggvucftvghtrhhoucdtuddrgeduuddrudehledguddvudcutefuodetggdotefrod ftvfcurfhrohhfihhlvgemucfhrghsthforghilhdpqfgfvfdpuffrtefokffrpgfnqfgh necuuegrihhlohhuthemuceftddtnecunecujfgurhephffvufhfffgjkfgfgggtsehmtd erredtreejnecuhfhrohhmpefvihhmohhthhihucfurghmphhlvgcuoehsrghmphhlvght sehnghihrhhordgtohhmqeenucfkphepjeegrdduudeirddukeeirdeggeenucfrrghrrg hmpehmrghilhhfrhhomhepshgrmhhplhgvthesnhhghihrohdrtghomhenucevlhhushht vghrufhiiigvpedt X-ME-Proxy: Received: from mrblack (74-116-186-44.qc.dsl.ebox.net [74.116.186.44]) by mail.messagingengine.com (Postfix) with ESMTPA id A35E6380088; Thu, 13 Jun 2019 14:09:11 -0400 (EDT) From: Timothy Sample References: <20190601223636.74362-1-rob@vllmrt.net> <87sgse43sc.fsf@ngyro.com> Date: Thu, 13 Jun 2019 14:09:10 -0400 In-Reply-To: (Robert Vollmert's message of "Thu, 13 Jun 2019 18:11:00 +0200") Message-ID: <87lfy59x2x.fsf@ngyro.com> User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/26.2 (gnu/linux) MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="=-=-=" X-Spam-Score: -0.7 (/) X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -1.7 (-) --=-=-= Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: quoted-printable Hi Robert, Robert Vollmert writes: > Hi Timothy, > > thanks for the detailed feedback, this is very helpful! You=E2=80=99re welcome! > I=E2=80=99ve sent an updated patch addressing some of the concerns, but h= ave > some questions regarding others. (I just realized that the documentation > updates probably anticipate multiple return values.) Yes. >> On 13. Jun 2019, at 04:28, Timothy Sample wrote: >>> + (let-values (((port get-hash) (open-sha256-input-port port))) > >>> + (cons >>> + (read-cabal (canonical-newline-port port)) >>> + (bytevector->nix-base32-string (get-hash))))) > > [=E2=80=A6] > >> Also, I think returning multiple values would be more natural here >> (i.e., replace =E2=80=9Ccons=E2=80=9D with =E2=80=9Cvalues=E2=80=9D). > > I tried building it that way to begin with, but I=E2=80=99m having issues > making it work (nicely, or maybe at all). I think it comes down to > later functions optionally failing with a single #f-value. Judging > by the lack of infrastructure, I imagine functions that return different > numbers of values are not idiomatic scheme. Should this be changed to > return two values (#f #f) on failure? Or to raise an exception and > handle it higher up when we want to ignore a failure? > > Currently, implementing this with values/let-values results in me > doing more or less a combination of let-values and match, at which > point it seems that any potential benefits of using multiple values > as opposed to a pair/list are lost. (There=E2=80=99s no match-values form= is > there?) I=E2=80=99m not sure I understand the problem. Here=E2=80=99s what I had i= n mind: --=-=-= Content-Type: text/x-patch Content-Disposition: inline; filename=values.patch Content-Description: values diff --git a/guix/import/hackage.scm b/guix/import/hackage.scm index 2853037797..9ba3c4b58e 100644 --- a/guix/import/hackage.scm +++ b/guix/import/hackage.scm @@ -120,8 +120,8 @@ version is returned." (define (read-cabal-and-hash port) "Read a cabal file and its base32 hash from a port." (let-values (((port get-hash) (open-sha256-input-port port))) - (cons (read-cabal (canonical-newline-port port)) - (bytevector->nix-base32-string (get-hash))))) + (values (read-cabal (canonical-newline-port port)) + (bytevector->nix-base32-string (get-hash))))) (define (hackage-fetch-and-hash name-version) "Return the Cabal file and hash for the package NAME-VERSION, or #f on @@ -129,7 +129,7 @@ failure. If the version part is omitted from the package name, then return the latest version." (guard (c ((and (http-get-error? c) (= 404 (http-get-error-code c))) - #f)) ;"expected" if package is unknown + (values #f #f))) ;"expected" if package is unknown (let-values (((name version) (package-name->name+version name-version))) (let* ((url (hackage-cabal-url name version)) (port (http-fetch url)) @@ -141,9 +141,8 @@ the latest version." "Return the Cabal file for the package NAME-VERSION, or #f on failure. If the version part is omitted from the package name, then return the latest version." - (match (hackage-fetch-and-hash name-version) - ((cabal . hash) cabal) - (_ #f))) + (let-values (((cabal hash) (hackage-fetch-and-hash name-version))) + cabal)) (define string->license ;; List of valid values from @@ -318,16 +317,14 @@ symbol 'true' or 'false'. The value associated with other keys has to conform to the Cabal file format definition. The default value associated with the keys \"os\", \"arch\" and \"impl\" is \"linux\", \"x86_64\" and \"ghc\" respectively." - (match - (if port (read-cabal-and-hash port) - (hackage-fetch-and-hash package-name)) - ((cabal-meta . cabal-hash) - (and=> cabal-meta (compose (cut hackage-module->sexp <> - cabal-hash - #:include-test-dependencies? - include-test-dependencies?) - (cut eval-cabal <> cabal-environment)))) - (_ #f))) + (let-values (((cabal-meta cabal-hash) + (if port + (read-cabal-and-hash (canonical-newline-port port)) + (hackage-fetch-and-hash package-name)))) + (and=> cabal-meta (compose (cut hackage-module->sexp <> cabal-hash + #:include-test-dependencies? + include-test-dependencies?) + (cut eval-cabal <> cabal-environment))))) (define hackage->guix-package/m ;memoized variant (memoize hackage->guix-package)) --=-=-= Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: quoted-printable As far as I see, this behaves the same as the cons-and-match version. Did I miss something? By the way, you make a good point about =E2=80=9Cmatch-values=E2=80=9D. Th= at would be handy. In general, we love =E2=80=9Cmatch=E2=80=9D in Guile and in Guix in= particular, but multiple values are part of the Scheme standard =E2=80=93 there=E2=80= =99s no reason to avoid them. They are perfect for situations like this in place of wrapping the values up into a pair or list and then immediately unwrapping them. -- Tim --=-=-=-- From unknown Tue Jun 17 21:52:50 2025 X-Loop: help-debbugs@gnu.org Subject: [bug#36048] [PATCH] guix: import: hackage: handle hackage revisions References: <20190601223636.74362-1-rob@vllmrt.net> In-Reply-To: <20190601223636.74362-1-rob@vllmrt.net> Resent-From: Robert Vollmert Original-Sender: "Debbugs-submit" Resent-CC: guix-patches@gnu.org Resent-Date: Thu, 13 Jun 2019 19:40:02 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 36048 X-GNU-PR-Package: guix-patches X-GNU-PR-Keywords: patch To: 36048@debbugs.gnu.org Cc: Robert Vollmert Received: via spool by 36048-submit@debbugs.gnu.org id=B36048.156045477921257 (code B ref 36048); Thu, 13 Jun 2019 19:40:02 +0000 Received: (at 36048) by debbugs.gnu.org; 13 Jun 2019 19:39:39 +0000 Received: from localhost ([127.0.0.1]:36166 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1hbVZS-0005Wm-Jw for submit@debbugs.gnu.org; Thu, 13 Jun 2019 15:39:39 -0400 Received: from mx1.mailbox.org ([80.241.60.212]:34048) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1hbVZQ-0005WZ-Uh for 36048@debbugs.gnu.org; Thu, 13 Jun 2019 15:39:38 -0400 Received: from smtp1.mailbox.org (smtp1.mailbox.org [80.241.60.240]) (using TLSv1.2 with cipher ECDHE-RSA-CHACHA20-POLY1305 (256/256 bits)) (No client certificate requested) by mx1.mailbox.org (Postfix) with ESMTPS id 2422A4FFAD; Thu, 13 Jun 2019 21:39:31 +0200 (CEST) X-Virus-Scanned: amavisd-new at heinlein-support.de Received: from smtp1.mailbox.org ([80.241.60.240]) by spamfilter05.heinlein-hosting.de (spamfilter05.heinlein-hosting.de [80.241.56.123]) (amavisd-new, port 10030) with ESMTP id VHOagrWd8dTI; Thu, 13 Jun 2019 21:39:19 +0200 (CEST) From: Robert Vollmert Date: Thu, 13 Jun 2019 21:39:14 +0200 Message-Id: <20190613193914.11552-1-rob@vllmrt.net> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Spam-Score: -0.7 (/) X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -1.7 (-) Hackage packages can have metadata revision (cabal-file only) that aren't reflected in the source archive. haskell-build-system has support for this, but previously `guix import hackage` would create a definition based on the new cabal file but building using the old cabal file. Compare https://debbugs.gnu.org/cgi/bugreport.cgi?bug=35750. * guix/import/cabal.scm: Parse `x-revision:` property. * guix/import/hackage.scm: Compute hash of cabal file, and write cabal-revision build system arguments. * guix/tests/hackage.scm: Test import of cabal revision. --- guix/import/cabal.scm | 7 +++-- guix/import/hackage.scm | 69 ++++++++++++++++++++++++++++------------- tests/hackage.scm | 45 +++++++++++++++++++++++++++ 3 files changed, 98 insertions(+), 23 deletions(-) diff --git a/guix/import/cabal.scm b/guix/import/cabal.scm index 1a87be0b00..7dfe771e41 100644 --- a/guix/import/cabal.scm +++ b/guix/import/cabal.scm @@ -40,6 +40,7 @@ cabal-package? cabal-package-name cabal-package-version + cabal-package-revision cabal-package-license cabal-package-home-page cabal-package-source-repository @@ -638,13 +639,14 @@ If #f use the function 'port-filename' to obtain it." ;; information of the Cabal file, but only the ones we currently are ;; interested in. (define-record-type - (make-cabal-package name version license home-page source-repository + (make-cabal-package name version revision license home-page source-repository synopsis description executables lib test-suites flags eval-environment custom-setup) cabal-package? (name cabal-package-name) (version cabal-package-version) + (revision cabal-package-revision) (license cabal-package-license) (home-page cabal-package-home-page) (source-repository cabal-package-source-repository) @@ -838,6 +840,7 @@ See the manual for limitations."))))))) (define (cabal-evaluated-sexp->package evaluated-sexp) (let* ((name (lookup-join evaluated-sexp "name")) (version (lookup-join evaluated-sexp "version")) + (revision (lookup-join evaluated-sexp "x-revision")) (license (lookup-join evaluated-sexp "license")) (home-page (lookup-join evaluated-sexp "homepage")) (home-page-or-hackage @@ -856,7 +859,7 @@ See the manual for limitations."))))))) (custom-setup (match (make-cabal-section evaluated-sexp 'custom-setup) ((x) x) (_ #f)))) - (make-cabal-package name version license home-page-or-hackage + (make-cabal-package name version revision license home-page-or-hackage source-repository synopsis description executables lib test-suites flags eval-environment custom-setup))) diff --git a/guix/import/hackage.scm b/guix/import/hackage.scm index 366256b40d..b739b61157 100644 --- a/guix/import/hackage.scm +++ b/guix/import/hackage.scm @@ -117,19 +117,34 @@ version is returned." (#f name) (m (match:substring m 1))))))) +(define (read-cabal-and-hash port) + "Given an input PORT, read a cabal file and its base32 hash from it, +and return both values." + (let-values (((port get-hash) (open-sha256-input-port port))) + (values (read-cabal (canonical-newline-port port)) + (bytevector->nix-base32-string (get-hash))))) + +(define (hackage-fetch-and-hash name-version) + "Fetch the latest Cabal revision for the package NAME-VERSION, and return +two values: the parsed Cabal file and its base32 hash. If the version part +is omitted from the package name, then fetch the latest version. Return #f +on failure." + (guard (c ((and (http-get-error? c) + (= 404 (http-get-error-code c))) + (values #f #f))) ;"expected" if package is unknown + (let*-values (((name version) (package-name->name+version name-version)) + ((url) (hackage-cabal-url name version)) + ((port) (http-fetch url)) + ((cabal hash) (read-cabal-and-hash port))) + (close-port port) + (values cabal hash)))) + (define (hackage-fetch name-version) "Return the Cabal file for the package NAME-VERSION, or #f on failure. If the version part is omitted from the package name, then return the latest version." - (guard (c ((and (http-get-error? c) - (= 404 (http-get-error-code c))) - #f)) ;"expected" if package is unknown - (let-values (((name version) (package-name->name+version name-version))) - (let* ((url (hackage-cabal-url name version)) - (port (http-fetch url)) - (result (read-cabal (canonical-newline-port port)))) - (close-port port) - result)))) + (let-values (((cabal hash) (hackage-fetch-and-hash name-version))) + cabal)) (define string->license ;; List of valid values from @@ -198,15 +213,20 @@ package being processed and is used to filter references to itself." (cons own-name ghc-standard-libraries)))) dependencies)) -(define* (hackage-module->sexp cabal #:key (include-test-dependencies? #t)) +(define* (hackage-module->sexp cabal cabal-hash + #:key (include-test-dependencies? #t)) "Return the `package' S-expression for a Cabal package. CABAL is the -representation of a Cabal file as produced by 'read-cabal'." +representation of a Cabal file as produced by 'read-cabal'. CABAL-HASH is +the hash of the Cabal file." (define name (cabal-package-name cabal)) (define version (cabal-package-version cabal)) + + (define revision + (cabal-package-revision cabal)) (define source-url (hackage-source-url name version)) @@ -252,9 +272,14 @@ representation of a Cabal file as produced by 'read-cabal'." (list 'quasiquote inputs)))))) (define (maybe-arguments) - (if (not include-test-dependencies?) - '((arguments `(#:tests? #f))) - '())) + (match (append (if (not include-test-dependencies?) + '(#:tests? #f) + '()) + (if (not (string-null? revision)) + `(#:cabal-revision (,revision ,cabal-hash)) + '())) + (() '()) + (args `((arguments (,'quasiquote ,args)))))) (let ((tarball (with-store store (download-to-store store source-url)))) @@ -294,13 +319,15 @@ symbol 'true' or 'false'. The value associated with other keys has to conform to the Cabal file format definition. The default value associated with the keys \"os\", \"arch\" and \"impl\" is \"linux\", \"x86_64\" and \"ghc\" respectively." - (let ((cabal-meta (if port - (read-cabal (canonical-newline-port port)) - (hackage-fetch package-name)))) - (and=> cabal-meta (compose (cut hackage-module->sexp <> - #:include-test-dependencies? - include-test-dependencies?) - (cut eval-cabal <> cabal-environment))))) + (let-values (((cabal hash) + (if port + (read-cabal-and-hash port) + (hackage-fetch-and-hash package-name)))) + (and=> cabal (compose (cut hackage-module->sexp <> + hash + #:include-test-dependencies? + include-test-dependencies?) + (cut eval-cabal <> cabal-environment))))) (define hackage->guix-package/m ;memoized variant (memoize hackage->guix-package)) diff --git a/tests/hackage.scm b/tests/hackage.scm index 38a5825af7..14176b2cf9 100644 --- a/tests/hackage.scm +++ b/tests/hackage.scm @@ -274,6 +274,51 @@ executable cabal (test-assert "hackage->guix-package test multiline desc (braced)" (eval-test-with-cabal test-cabal-multiline-braced match-ghc-foo)) +;; Check Hackage Cabal revisions. +(define test-cabal-revision + "name: foo +version: 1.0.0 +x-revision: 2 +homepage: http://test.org +synopsis: synopsis +description: description +license: BSD3 +executable cabal + build-depends: + HTTP >= 4000.2.5 && < 4000.3, + mtl >= 2.0 && < 3 +") + +(define-package-matcher match-ghc-foo-revision + ('package + ('name "ghc-foo") + ('version "1.0.0") + ('source + ('origin + ('method 'url-fetch) + ('uri ('string-append + "https://hackage.haskell.org/package/foo/foo-" + 'version + ".tar.gz")) + ('sha256 + ('base32 + (? string? hash))))) + ('build-system 'haskell-build-system) + ('inputs + ('quasiquote + (("ghc-http" ('unquote 'ghc-http))))) + ('arguments + ('quasiquote + ('#:cabal-revision + ("2" "0xxd88fb659f0krljidbvvmkh9ppjnx83j0nqzx8whcg4n5qbyng")))) + ('home-page "http://test.org") + ('synopsis (? string?)) + ('description (? string?)) + ('license 'bsd-3))) + +(test-assert "hackage->guix-package test cabal revision" + (eval-test-with-cabal test-cabal-revision match-ghc-foo-revision)) + (test-assert "read-cabal test 1" (match (call-with-input-string test-read-cabal-1 read-cabal) ((("name" ("test-me")) -- 2.20.1 (Apple Git-117) From unknown Tue Jun 17 21:52:50 2025 X-Loop: help-debbugs@gnu.org Subject: [bug#36048] [PATCH] guix: import: hackage: handle hackage revisions Resent-From: Robert Vollmert Original-Sender: "Debbugs-submit" Resent-CC: guix-patches@gnu.org Resent-Date: Thu, 13 Jun 2019 19:41:03 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 36048 X-GNU-PR-Package: guix-patches X-GNU-PR-Keywords: patch To: Timothy Sample Cc: 36048@debbugs.gnu.org Received: via spool by 36048-submit@debbugs.gnu.org id=B36048.156045483221354 (code B ref 36048); Thu, 13 Jun 2019 19:41:03 +0000 Received: (at 36048) by debbugs.gnu.org; 13 Jun 2019 19:40:32 +0000 Received: from localhost ([127.0.0.1]:36170 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1hbVaK-0005YM-B9 for submit@debbugs.gnu.org; Thu, 13 Jun 2019 15:40:32 -0400 Received: from mx1.mailbox.org ([80.241.60.212]:36790) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1hbVaI-0005Y8-Aq for 36048@debbugs.gnu.org; Thu, 13 Jun 2019 15:40:30 -0400 Received: from smtp1.mailbox.org (smtp1.mailbox.org [80.241.60.240]) (using TLSv1.2 with cipher ECDHE-RSA-CHACHA20-POLY1305 (256/256 bits)) (No client certificate requested) by mx1.mailbox.org (Postfix) with ESMTPS id D7590503A6; Thu, 13 Jun 2019 21:40:24 +0200 (CEST) X-Virus-Scanned: amavisd-new at heinlein-support.de Received: from smtp1.mailbox.org ([80.241.60.240]) by gerste.heinlein-support.de (gerste.heinlein-support.de [91.198.250.173]) (amavisd-new, port 10030) with ESMTP id 99Mn0Mjribl3; Thu, 13 Jun 2019 21:40:16 +0200 (CEST) Content-Type: text/plain; charset=utf-8 Mime-Version: 1.0 (Mac OS X Mail 12.4 \(3445.104.11\)) From: Robert Vollmert In-Reply-To: <87lfy59x2x.fsf@ngyro.com> Date: Thu, 13 Jun 2019 21:40:15 +0200 Content-Transfer-Encoding: quoted-printable Message-Id: <635BD0E2-BADE-4385-8A4C-A3AE36A392BC@vllmrt.net> References: <20190601223636.74362-1-rob@vllmrt.net> <87sgse43sc.fsf@ngyro.com> <87lfy59x2x.fsf@ngyro.com> X-Spam-Score: -0.7 (/) X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -1.7 (-) > On 13. Jun 2019, at 20:09, Timothy Sample wrote: >=20 > Hi Robert, >=20 > Robert Vollmert writes: >=20 >> Hi Timothy, >>=20 >> thanks for the detailed feedback, this is very helpful! >=20 > You=E2=80=99re welcome! >=20 >> I=E2=80=99ve sent an updated patch addressing some of the concerns, = but have >> some questions regarding others. (I just realized that the = documentation >> updates probably anticipate multiple return values.) >=20 > Yes. >=20 >>> On 13. Jun 2019, at 04:28, Timothy Sample wrote: >>>> + (let-values (((port get-hash) (open-sha256-input-port port))) >>=20 >>>> + (cons >>>> + (read-cabal (canonical-newline-port port)) >>>> + (bytevector->nix-base32-string (get-hash))))) >>=20 >> [=E2=80=A6] >>=20 >>> Also, I think returning multiple values would be more natural here >>> (i.e., replace =E2=80=9Ccons=E2=80=9D with =E2=80=9Cvalues=E2=80=9D). >>=20 >> I tried building it that way to begin with, but I=E2=80=99m having = issues >> making it work (nicely, or maybe at all). I think it comes down to >> later functions optionally failing with a single #f-value. Judging >> by the lack of infrastructure, I imagine functions that return = different >> numbers of values are not idiomatic scheme. Should this be changed to >> return two values (#f #f) on failure? Or to raise an exception and >> handle it higher up when we want to ignore a failure? >>=20 >> Currently, implementing this with values/let-values results in me >> doing more or less a combination of let-values and match, at which >> point it seems that any potential benefits of using multiple values >> as opposed to a pair/list are lost. (There=E2=80=99s no match-values = form is >> there?) >=20 > I=E2=80=99m not sure I understand the problem. Here=E2=80=99s what I = had in mind: >=20 > diff --git a/guix/import/hackage.scm b/guix/import/hackage.scm > index 2853037797..9ba3c4b58e 100644 > --- a/guix/import/hackage.scm > +++ b/guix/import/hackage.scm > @@ -120,8 +120,8 @@ version is returned." > (define (read-cabal-and-hash port) > "Read a cabal file and its base32 hash from a port." > (let-values (((port get-hash) (open-sha256-input-port port))) > - (cons (read-cabal (canonical-newline-port port)) > - (bytevector->nix-base32-string (get-hash))))) > + (values (read-cabal (canonical-newline-port port)) > + (bytevector->nix-base32-string (get-hash))))) >=20 > (define (hackage-fetch-and-hash name-version) > "Return the Cabal file and hash for the package NAME-VERSION, or #f = on > @@ -129,7 +129,7 @@ failure. If the version part is omitted from the = package name, then return > the latest version." > (guard (c ((and (http-get-error? c) > (=3D 404 (http-get-error-code c))) > - #f)) ;"expected" if package is = unknown > + (values #f #f))) ;"expected" if package is = unknown This is the point: I tried to keep returning a single #f to signal = failure. I sent an updated patch, let me know if I missed something. Thanks! Robert From unknown Tue Jun 17 21:52:50 2025 MIME-Version: 1.0 X-Mailer: MIME-tools 5.505 (Entity 5.505) X-Loop: help-debbugs@gnu.org From: help-debbugs@gnu.org (GNU bug Tracking System) To: Robert Vollmert Subject: bug#36048: closed (Re: [bug#36048] [PATCH] guix: import: hackage: handle hackage revisions) Message-ID: References: <87blz0aojf.fsf@ngyro.com> <20190601223636.74362-1-rob@vllmrt.net> X-Gnu-PR-Message: they-closed 36048 X-Gnu-PR-Package: guix-patches X-Gnu-PR-Keywords: patch Reply-To: 36048@debbugs.gnu.org Date: Fri, 14 Jun 2019 02:29:02 +0000 Content-Type: multipart/mixed; boundary="----------=_1560479342-4688-1" This is a multi-part message in MIME format... ------------=_1560479342-4688-1 Content-Disposition: inline Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Your bug report #36048: [PATCH] guix: import: hackage: handle hackage revisions which was filed against the guix-patches package, has been closed. The explanation is attached below, along with your original report. If you require more details, please reply to 36048@debbugs.gnu.org. --=20 36048: http://debbugs.gnu.org/cgi/bugreport.cgi?bug=3D36048 GNU Bug Tracking System Contact help-debbugs@gnu.org with problems ------------=_1560479342-4688-1 Content-Type: message/rfc822 Content-Disposition: inline Content-Transfer-Encoding: 7bit Received: (at 36048-done) by debbugs.gnu.org; 14 Jun 2019 02:28:37 +0000 Received: from localhost ([127.0.0.1]:36354 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1hbbxB-0001CW-Em for submit@debbugs.gnu.org; Thu, 13 Jun 2019 22:28:37 -0400 Received: from wout2-smtp.messagingengine.com ([64.147.123.25]:60285) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1hbbx6-0001CB-O0 for 36048-done@debbugs.gnu.org; Thu, 13 Jun 2019 22:28:29 -0400 Received: from compute4.internal (compute4.nyi.internal [10.202.2.44]) by mailout.west.internal (Postfix) with ESMTP id E91EA12F1; Thu, 13 Jun 2019 22:28:22 -0400 (EDT) Received: from mailfrontend2 ([10.202.2.163]) by compute4.internal (MEProxy); Thu, 13 Jun 2019 22:28:23 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d= messagingengine.com; h=cc:content-transfer-encoding:content-type :date:from:in-reply-to:message-id:mime-version:references :subject:to:x-me-proxy:x-me-proxy:x-me-sender:x-me-sender :x-sasl-enc; s=fm3; bh=zfjKtufY2nMfwKSY4VCxqD5mxhPCRwQoRI2SL7jbK Hs=; b=SUwEazzeATjGEM3SR8B6EYijTmafm3CNdOm63w0iCAcV9PRZD8Css/wDa pQ60SyzCtuzz47FD34WCbVBCdsb3hI9q111+HNIH/llKHNyEAdjk3UN+cxaPOtW5 tWtUkj+PrkCVUJ+cjg2OoUNBYhWHnFeATrTTXopdYpOCx1IbF3wIQN/JXc8Fxx8E E8GTOMHZH5Px3nMc1hOjnMMWWJm7pz0to6XvBMSExrvaYFwMbL6Iq/07s5niCaKf HTOWuAL3c9Tc/qAtJsurF/BQoEZ1aNAtbCewTsfZLut+6REYifwDdZh7uW4+DtM1 baDEM2t3oVGwzmEjvt/+ijAsYIrPw== X-ME-Sender: X-ME-Proxy-Cause: gggruggvucftvghtrhhoucdtuddrgeduuddrudeitddgheekucetufdoteggodetrfdotf fvucfrrhhofhhilhgvmecuhfgrshhtofgrihhlpdfqfgfvpdfurfetoffkrfgpnffqhgen uceurghilhhouhhtmecufedttdenucenucfjughrpefhvffufhffjgfkfgggtgfgsehtqh ertddtreejnecuhfhrohhmpefvihhmohhthhihucfurghmphhlvgcuoehsrghmphhlvght sehnghihrhhordgtohhmqeenucffohhmrghinhepthgvshhtrdhorhhgpdhhrghskhgvlh hlrdhorhhgpdhgnhhurdhorhhgnecukfhppeejgedrudduiedrudekiedrgeegnecurfgr rhgrmhepmhgrihhlfhhrohhmpehsrghmphhlvghtsehnghihrhhordgtohhmnecuvehluh hsthgvrhfuihiivgeptd X-ME-Proxy: Received: from mrblack (74-116-186-44.qc.dsl.ebox.net [74.116.186.44]) by mail.messagingengine.com (Postfix) with ESMTPA id DFAAE380084; Thu, 13 Jun 2019 22:28:20 -0400 (EDT) From: Timothy Sample To: Robert Vollmert Subject: Re: [bug#36048] [PATCH] guix: import: hackage: handle hackage revisions References: <20190601223636.74362-1-rob@vllmrt.net> <20190613193914.11552-1-rob@vllmrt.net> Date: Thu, 13 Jun 2019 22:28:20 -0400 In-Reply-To: <20190613193914.11552-1-rob@vllmrt.net> (Robert Vollmert's message of "Thu, 13 Jun 2019 21:39:14 +0200") Message-ID: <87blz0aojf.fsf@ngyro.com> User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/26.2 (gnu/linux) MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: quoted-printable X-Spam-Score: -0.7 (/) X-Debbugs-Envelope-To: 36048-done Cc: 36048-done@debbugs.gnu.org X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -1.7 (-) Hi Robert, Robert Vollmert writes: > Hackage packages can have metadata revision (cabal-file only) > that aren't reflected in the source archive. haskell-build-system > has support for this, but previously `guix import hackage` would > create a definition based on the new cabal file but building using > the old cabal file. > > Compare https://debbugs.gnu.org/cgi/bugreport.cgi?bug=3D35750. > > * guix/import/cabal.scm: Parse `x-revision:` property. > * guix/import/hackage.scm: Compute hash of cabal file, and write > cabal-revision build system arguments. > * guix/tests/hackage.scm: Test import of cabal revision. > --- > guix/import/cabal.scm | 7 +++-- > guix/import/hackage.scm | 69 ++++++++++++++++++++++++++++------------- > tests/hackage.scm | 45 +++++++++++++++++++++++++++ > 3 files changed, 98 insertions(+), 23 deletions(-) > > diff --git a/guix/import/cabal.scm b/guix/import/cabal.scm > index 1a87be0b00..7dfe771e41 100644 > --- a/guix/import/cabal.scm > +++ b/guix/import/cabal.scm > @@ -40,6 +40,7 @@ > cabal-package? > cabal-package-name > cabal-package-version > + cabal-package-revision > cabal-package-license > cabal-package-home-page > cabal-package-source-repository > @@ -638,13 +639,14 @@ If #f use the function 'port-filename' to obtain it= ." > ;; information of the Cabal file, but only the ones we currently are > ;; interested in. > (define-record-type > - (make-cabal-package name version license home-page source-repository > + (make-cabal-package name version revision license home-page source-rep= ository > synopsis description > executables lib test-suites > flags eval-environment custom-setup) > cabal-package? > (name cabal-package-name) > (version cabal-package-version) > + (revision cabal-package-revision) > (license cabal-package-license) > (home-page cabal-package-home-page) > (source-repository cabal-package-source-repository) > @@ -838,6 +840,7 @@ See the manual for limitations."))))))) > (define (cabal-evaluated-sexp->package evaluated-sexp) > (let* ((name (lookup-join evaluated-sexp "name")) > (version (lookup-join evaluated-sexp "version")) > + (revision (lookup-join evaluated-sexp "x-revision")) > (license (lookup-join evaluated-sexp "license")) > (home-page (lookup-join evaluated-sexp "homepage")) > (home-page-or-hackage > @@ -856,7 +859,7 @@ See the manual for limitations."))))))) > (custom-setup (match (make-cabal-section evaluated-sexp 'cust= om-setup) > ((x) x) > (_ #f)))) > - (make-cabal-package name version license home-page-or-hackage > + (make-cabal-package name version revision license home-page-or-hac= kage > source-repository synopsis description executa= bles lib > test-suites flags eval-environment custom-setu= p))) >=20=20 > diff --git a/guix/import/hackage.scm b/guix/import/hackage.scm > index 366256b40d..b739b61157 100644 > --- a/guix/import/hackage.scm > +++ b/guix/import/hackage.scm > @@ -117,19 +117,34 @@ version is returned." > (#f name) > (m (match:substring m 1))))))) >=20=20 > +(define (read-cabal-and-hash port) > + "Given an input PORT, read a cabal file and its base32 hash from it, > +and return both values." > + (let-values (((port get-hash) (open-sha256-input-port port))) > + (values (read-cabal (canonical-newline-port port)) > + (bytevector->nix-base32-string (get-hash))))) > + > +(define (hackage-fetch-and-hash name-version) > + "Fetch the latest Cabal revision for the package NAME-VERSION, and ret= urn > +two values: the parsed Cabal file and its base32 hash. If the version pa= rt > +is omitted from the package name, then fetch the latest version. Return = #f > +on failure." > + (guard (c ((and (http-get-error? c) > + (=3D 404 (http-get-error-code c))) > + (values #f #f))) ;"expected" if package is unknown > + (let*-values (((name version) (package-name->name+version name-versi= on)) > + ((url) (hackage-cabal-url name version)) > + ((port) (http-fetch url)) > + ((cabal hash) (read-cabal-and-hash port))) > + (close-port port) > + (values cabal hash)))) > + > (define (hackage-fetch name-version) > "Return the Cabal file for the package NAME-VERSION, or #f on failure.= If > the version part is omitted from the package name, then return the latest > version." > - (guard (c ((and (http-get-error? c) > - (=3D 404 (http-get-error-code c))) > - #f)) ;"expected" if package is unknown > - (let-values (((name version) (package-name->name+version name-versio= n))) > - (let* ((url (hackage-cabal-url name version)) > - (port (http-fetch url)) > - (result (read-cabal (canonical-newline-port port)))) > - (close-port port) > - result)))) > + (let-values (((cabal hash) (hackage-fetch-and-hash name-version))) > + cabal)) >=20=20 > (define string->license > ;; List of valid values from > @@ -198,15 +213,20 @@ package being processed and is used to filter refer= ences to itself." > (cons own-name ghc-standard-libraries= )))) > dependencies)) >=20=20 > -(define* (hackage-module->sexp cabal #:key (include-test-dependencies? #= t)) > +(define* (hackage-module->sexp cabal cabal-hash > + #:key (include-test-dependencies? #t)) > "Return the `package' S-expression for a Cabal package. CABAL is the > -representation of a Cabal file as produced by 'read-cabal'." > +representation of a Cabal file as produced by 'read-cabal'. CABAL-HASH = is > +the hash of the Cabal file." >=20=20 > (define name > (cabal-package-name cabal)) >=20=20 > (define version > (cabal-package-version cabal)) > + > + (define revision > + (cabal-package-revision cabal)) >=20=20=20=20 > (define source-url > (hackage-source-url name version)) > @@ -252,9 +272,14 @@ representation of a Cabal file as produced by 'read-= cabal'." > (list 'quasiquote inputs)))))) >=20=20=20=20 > (define (maybe-arguments) > - (if (not include-test-dependencies?) > - '((arguments `(#:tests? #f))) > - '())) > + (match (append (if (not include-test-dependencies?) > + '(#:tests? #f) > + '()) > + (if (not (string-null? revision)) > + `(#:cabal-revision (,revision ,cabal-hash)) > + '())) > + (() '()) > + (args `((arguments (,'quasiquote ,args)))))) >=20=20 > (let ((tarball (with-store store > (download-to-store store source-url)))) > @@ -294,13 +319,15 @@ symbol 'true' or 'false'. The value associated wit= h other keys has to conform > to the Cabal file format definition. The default value associated with = the > keys \"os\", \"arch\" and \"impl\" is \"linux\", \"x86_64\" and \"ghc\" > respectively." > - (let ((cabal-meta (if port > - (read-cabal (canonical-newline-port port)) > - (hackage-fetch package-name)))) > - (and=3D> cabal-meta (compose (cut hackage-module->sexp <> > - #:include-test-dependencies? > - include-test-dependencies?) > - (cut eval-cabal <> cabal-environment))))) > + (let-values (((cabal hash) > + (if port > + (read-cabal-and-hash port) > + (hackage-fetch-and-hash package-name)))) > + (and=3D> cabal (compose (cut hackage-module->sexp <> > + hash > + #:include-test-dependencies? > + include-test-dependencies?) > + (cut eval-cabal <> cabal-environment))))) >=20=20 > (define hackage->guix-package/m ;memoized variant > (memoize hackage->guix-package)) > diff --git a/tests/hackage.scm b/tests/hackage.scm > index 38a5825af7..14176b2cf9 100644 > --- a/tests/hackage.scm > +++ b/tests/hackage.scm > @@ -274,6 +274,51 @@ executable cabal > (test-assert "hackage->guix-package test multiline desc (braced)" > (eval-test-with-cabal test-cabal-multiline-braced match-ghc-foo)) >=20=20 > +;; Check Hackage Cabal revisions. > +(define test-cabal-revision > + "name: foo > +version: 1.0.0 > +x-revision: 2 > +homepage: http://test.org > +synopsis: synopsis > +description: description > +license: BSD3 > +executable cabal > + build-depends: > + HTTP >=3D 4000.2.5 && < 4000.3, > + mtl >=3D 2.0 && < 3 > +") > + > +(define-package-matcher match-ghc-foo-revision > + ('package > + ('name "ghc-foo") > + ('version "1.0.0") > + ('source > + ('origin > + ('method 'url-fetch) > + ('uri ('string-append > + "https://hackage.haskell.org/package/foo/foo-" > + 'version > + ".tar.gz")) > + ('sha256 > + ('base32 > + (? string? hash))))) > + ('build-system 'haskell-build-system) > + ('inputs > + ('quasiquote > + (("ghc-http" ('unquote 'ghc-http))))) > + ('arguments > + ('quasiquote > + ('#:cabal-revision > + ("2" "0xxd88fb659f0krljidbvvmkh9ppjnx83j0nqzx8whcg4n5qbyng")))) > + ('home-page "http://test.org") > + ('synopsis (? string?)) > + ('description (? string?)) > + ('license 'bsd-3))) > + > +(test-assert "hackage->guix-package test cabal revision" > + (eval-test-with-cabal test-cabal-revision match-ghc-foo-revision)) > + > (test-assert "read-cabal test 1" > (match (call-with-input-string test-read-cabal-1 read-cabal) > ((("name" ("test-me")) Applied as ca45da9fc9b1eee399ce4344b18cbb129daeca4c! I did make a few changes. Most notably, I tried importing a package and it didn=E2=80=99t work! It turns out that =E2=80=9Chttp-fetch=E2=80=9D ret= urns two values, so I told =E2=80=9Clet-values=E2=80=9D to ignore the second one. Other than tha= t, I made a few changes to the commit message and docstrings, and kept =E2=80=9Ccabal-m= eta=E2=80=9D and =E2=80=9Ccabal-hash=E2=80=9D from before (instead of =E2=80=9Ccabal=E2= =80=9D and =E2=80=9Chash=E2=80=9D). Thanks for the patch! -- Tim ------------=_1560479342-4688-1 Content-Type: message/rfc822 Content-Disposition: inline Content-Transfer-Encoding: 7bit Received: (at submit) by debbugs.gnu.org; 1 Jun 2019 22:37:01 +0000 Received: from localhost ([127.0.0.1]:38946 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1hXCcX-000401-5G for submit@debbugs.gnu.org; Sat, 01 Jun 2019 18:37:01 -0400 Received: from eggs.gnu.org ([209.51.188.92]:33566) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1hXCcU-0003zo-Do for submit@debbugs.gnu.org; Sat, 01 Jun 2019 18:36:59 -0400 Received: from lists.gnu.org ([209.51.188.17]:39389) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1hXCcP-0004VH-7I for submit@debbugs.gnu.org; Sat, 01 Jun 2019 18:36:53 -0400 Received: from eggs.gnu.org ([209.51.188.92]:47948) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1hXCcN-0006rq-C4 for guix-patches@gnu.org; Sat, 01 Jun 2019 18:36:53 -0400 X-Spam-Checker-Version: SpamAssassin 3.3.2 (2011-06-06) on eggs.gnu.org X-Spam-Level: X-Spam-Status: No, score=0.1 required=5.0 tests=BAYES_50,RCVD_IN_DNSWL_LOW, URIBL_BLOCKED autolearn=disabled version=3.3.2 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1hXCcL-0004Th-Kv for guix-patches@gnu.org; Sat, 01 Jun 2019 18:36:51 -0400 Received: from mx1.mailbox.org ([80.241.60.212]:27650) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1hXCcL-0004SJ-C6 for guix-patches@gnu.org; Sat, 01 Jun 2019 18:36:49 -0400 Received: from smtp1.mailbox.org (smtp1.mailbox.org [IPv6:2001:67c:2050:105:465:1:1:0]) (using TLSv1.2 with cipher ECDHE-RSA-CHACHA20-POLY1305 (256/256 bits)) (No client certificate requested) by mx1.mailbox.org (Postfix) with ESMTPS id 368E34E8DD; Sun, 2 Jun 2019 00:36:46 +0200 (CEST) X-Virus-Scanned: amavisd-new at heinlein-support.de Received: from smtp1.mailbox.org ([80.241.60.240]) by spamfilter01.heinlein-hosting.de (spamfilter01.heinlein-hosting.de [80.241.56.115]) (amavisd-new, port 10030) with ESMTP id c-kscZiOC9pD; Sun, 2 Jun 2019 00:36:37 +0200 (CEST) From: Robert Vollmert To: guix-patches@gnu.org Subject: [PATCH] guix: import: hackage: handle hackage revisions Date: Sun, 2 Jun 2019 00:36:36 +0200 Message-Id: <20190601223636.74362-1-rob@vllmrt.net> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 80.241.60.212 X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.6.x X-Spam-Score: -1.6 (-) X-Debbugs-Envelope-To: submit Cc: Robert Vollmert X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -2.6 (--) Hackage packages can have metadata revision (cabal-file only) that aren't reflected in the source archive. haskell-build-system has support for this, but previously `guix import hackage` would create a definition based on the new cabal file but building using the old cabal file. Compare https://debbugs.gnu.org/cgi/bugreport.cgi?bug=3D35750. * guix/import/cabal.scm: Parse `x-revision:` property. * guix/import/hackage.scm: Compute hash of cabal file, and write cabal-revision build system arguments. * guix/tests/hackage.scm: Test import of cabal revision. --- guix/import/cabal.scm | 7 +++-- guix/import/hackage.scm | 61 ++++++++++++++++++++++++++++++----------- tests/hackage.scm | 46 +++++++++++++++++++++++++++++++ 3 files changed, 96 insertions(+), 18 deletions(-) diff --git a/guix/import/cabal.scm b/guix/import/cabal.scm index 1a87be0b00..7dfe771e41 100644 --- a/guix/import/cabal.scm +++ b/guix/import/cabal.scm @@ -40,6 +40,7 @@ cabal-package? cabal-package-name cabal-package-version + cabal-package-revision cabal-package-license cabal-package-home-page cabal-package-source-repository @@ -638,13 +639,14 @@ If #f use the function 'port-filename' to obtain it= ." ;; information of the Cabal file, but only the ones we currently are ;; interested in. (define-record-type - (make-cabal-package name version license home-page source-repository + (make-cabal-package name version revision license home-page source-rep= ository synopsis description executables lib test-suites flags eval-environment custom-setup) cabal-package? (name cabal-package-name) (version cabal-package-version) + (revision cabal-package-revision) (license cabal-package-license) (home-page cabal-package-home-page) (source-repository cabal-package-source-repository) @@ -838,6 +840,7 @@ See the manual for limitations."))))))) (define (cabal-evaluated-sexp->package evaluated-sexp) (let* ((name (lookup-join evaluated-sexp "name")) (version (lookup-join evaluated-sexp "version")) + (revision (lookup-join evaluated-sexp "x-revision")) (license (lookup-join evaluated-sexp "license")) (home-page (lookup-join evaluated-sexp "homepage")) (home-page-or-hackage @@ -856,7 +859,7 @@ See the manual for limitations."))))))) (custom-setup (match (make-cabal-section evaluated-sexp 'cust= om-setup) ((x) x) (_ #f)))) - (make-cabal-package name version license home-page-or-hackage + (make-cabal-package name version revision license home-page-or-hac= kage source-repository synopsis description executa= bles lib test-suites flags eval-environment custom-setu= p))) =20 diff --git a/guix/import/hackage.scm b/guix/import/hackage.scm index 366256b40d..cf8219143a 100644 --- a/guix/import/hackage.scm +++ b/guix/import/hackage.scm @@ -117,9 +117,15 @@ version is returned." (#f name) (m (match:substring m 1))))))) =20 -(define (hackage-fetch name-version) - "Return the Cabal file for the package NAME-VERSION, or #f on failure.= If -the version part is omitted from the package name, then return the lates= t +(define (read-cabal-and-hash port) + (let-values (((port get-hash) (open-sha256-input-port port))) + (cons + (read-cabal (canonical-newline-port port)) + (bytevector->nix-base32-string (get-hash))))) + +(define (hackage-fetch-and-hash name-version) + "Return the Cabal file and hash for the package NAME-VERSION, or #f on= failure. +If the version part is omitted from the package name, then return the la= test version." (guard (c ((and (http-get-error? c) (=3D 404 (http-get-error-code c))) @@ -127,10 +133,18 @@ version." (let-values (((name version) (package-name->name+version name-versio= n))) (let* ((url (hackage-cabal-url name version)) (port (http-fetch url)) - (result (read-cabal (canonical-newline-port port)))) + (result (read-cabal-and-hash port))) (close-port port) result)))) =20 +(define (hackage-fetch name-version) + "Return the Cabal file for the package NAME-VERSION, or #f on failure.= If +the version part is omitted from the package name, then return the lates= t +version." + (match (hackage-fetch-and-hash name-version) + ((cabal . hash) cabal) + (_ #f))) + (define string->license ;; List of valid values from ;; https://www.haskell.org @@ -198,15 +212,19 @@ package being processed and is used to filter refer= ences to itself." (cons own-name ghc-standard-libraries= )))) dependencies)) =20 -(define* (hackage-module->sexp cabal #:key (include-test-dependencies? #= t)) +(define* (hackage-module->sexp cabal cabal-hash #:key (include-test-depe= ndencies? #t)) "Return the `package' S-expression for a Cabal package. CABAL is the -representation of a Cabal file as produced by 'read-cabal'." +representation of a Cabal file as produced by 'read-cabal'. CABAL-HASH i= s +the hash of the Cabal file." =20 (define name (cabal-package-name cabal)) =20 (define version (cabal-package-version cabal)) + + (define revision + (cabal-package-revision cabal)) =20 (define source-url (hackage-source-url name version)) @@ -252,9 +270,17 @@ representation of a Cabal file as produced by 'read-= cabal'." (list 'quasiquote inputs)))))) =20 (define (maybe-arguments) - (if (not include-test-dependencies?) - '((arguments `(#:tests? #f))) - '())) + (define testargs (if (not include-test-dependencies?) + '(#:tests? #f) + '())) + (define revargs (if (not (string-null? revision)) + `(#:cabal-revision (,revision ,cabal-hash)) + '())) + (define args (append testargs revargs)) + (if (not (nil? args)) + (let ((qargs `(,'quasiquote ,args))) + `((arguments ,qargs))) + '())) =20 (let ((tarball (with-store store (download-to-store store source-url)))) @@ -294,13 +320,16 @@ symbol 'true' or 'false'. The value associated wit= h other keys has to conform to the Cabal file format definition. The default value associated with = the keys \"os\", \"arch\" and \"impl\" is \"linux\", \"x86_64\" and \"ghc\" respectively." - (let ((cabal-meta (if port - (read-cabal (canonical-newline-port port)) - (hackage-fetch package-name)))) - (and=3D> cabal-meta (compose (cut hackage-module->sexp <> - #:include-test-dependencies? - include-test-dependencies?) - (cut eval-cabal <> cabal-environment))))) + (match + (if port (read-cabal-and-hash port) + (hackage-fetch-and-hash package-name)) + ((cabal-meta . cabal-hash) + (and=3D> cabal-meta (compose (cut hackage-module->sexp <> + cabal-hash + #:include-test-dependencies? + include-test-dependencies?) + (cut eval-cabal <> cabal-environment)))) + (_ #f))) =20 (define hackage->guix-package/m ;memoized variant (memoize hackage->guix-package)) diff --git a/tests/hackage.scm b/tests/hackage.scm index 38a5825af7..fe4e0efb69 100644 --- a/tests/hackage.scm +++ b/tests/hackage.scm @@ -274,6 +274,52 @@ executable cabal (test-assert "hackage->guix-package test multiline desc (braced)" (eval-test-with-cabal test-cabal-multiline-braced match-ghc-foo)) =20 +;; test hackage cabal revisions +(define test-cabal-revision + "name: foo +version: 1.0.0 +x-revision: 2 +homepage: http://test.org +synopsis: synopsis +description: description +license: BSD3 +executable cabal + build-depends: + HTTP >=3D 4000.2.5 && < 4000.3, + mtl >=3D 2.0 && < 3 +") + +(define-package-matcher match-ghc-foo-revision + ('package + ('name "ghc-foo") + ('version "1.0.0") + ('source + ('origin + ('method 'url-fetch) + ('uri ('string-append + "https://hackage.haskell.org/package/foo/foo-" + 'version + ".tar.gz")) + ('sha256 + ('base32 + (? string? hash))))) + ('build-system 'haskell-build-system) + ('inputs + ('quasiquote + (("ghc-http" ('unquote 'ghc-http))))) + ('arguments + ('quasiquote + ('#:cabal-revision + ("2" "0xxd88fb659f0krljidbvvmkh9ppjnx83j0nqzx8whcg4n5qbyng")))) + ('home-page "http://test.org") + ('synopsis (? string?)) + ('description (? string?)) + ('license 'bsd-3))) + +(test-assert "hackage->guix-package test cabal revision" + (eval-test-with-cabal test-cabal-revision match-ghc-foo-revision)) + + (test-assert "read-cabal test 1" (match (call-with-input-string test-read-cabal-1 read-cabal) ((("name" ("test-me")) --=20 2.20.1 (Apple Git-117) ------------=_1560479342-4688-1--