From patchwork Sun Jun 13 09:46:18 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Xinglu Chen X-Patchwork-Id: 30209 Return-Path: X-Original-To: patchwork@mira.cbaines.net Delivered-To: patchwork@mira.cbaines.net Received: by mira.cbaines.net (Postfix, from userid 113) id 009C427BC81; Sun, 13 Jun 2021 10:47:11 +0100 (BST) X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on mira.cbaines.net X-Spam-Level: X-Spam-Status: No, score=-2.8 required=5.0 tests=BAYES_00,DKIM_SIGNED, MAILING_LIST_MULTI,RCVD_IN_MSPIKE_H4,RCVD_IN_MSPIKE_WL,SPF_HELO_PASS, T_DKIM_INVALID,URIBL_BLOCKED autolearn=unavailable autolearn_force=no version=3.4.2 Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mira.cbaines.net (Postfix) with ESMTPS id 5BBDA27BC78 for ; Sun, 13 Jun 2021 10:47:11 +0100 (BST) Received: from localhost ([::1]:39954 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1lsMhy-0001Ak-Ey for patchwork@mira.cbaines.net; Sun, 13 Jun 2021 05:47:10 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:33684) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1lsMhq-00018Q-O6 for guix-patches@gnu.org; Sun, 13 Jun 2021 05:47:02 -0400 Received: from debbugs.gnu.org ([209.51.188.43]:59353) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1lsMhq-00006T-Fq for guix-patches@gnu.org; Sun, 13 Jun 2021 05:47:02 -0400 Received: from Debian-debbugs by debbugs.gnu.org with local (Exim 4.84_2) (envelope-from ) id 1lsMhq-00015P-D6 for guix-patches@gnu.org; Sun, 13 Jun 2021 05:47:02 -0400 X-Loop: help-debbugs@gnu.org Subject: [bug#48999] [PATCH] import: hackage: Accept local source for package. Resent-From: Xinglu Chen Original-Sender: "Debbugs-submit" Resent-CC: guix-patches@gnu.org Resent-Date: Sun, 13 Jun 2021 09:47:02 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: report 48999 X-GNU-PR-Package: guix-patches X-GNU-PR-Keywords: patch To: 48999@debbugs.gnu.org X-Debbugs-Original-To: guix-patches@gnu.org Received: via spool by submit@debbugs.gnu.org id=B.16235775994144 (code B ref -1); Sun, 13 Jun 2021 09:47:02 +0000 Received: (at submit) by debbugs.gnu.org; 13 Jun 2021 09:46:39 +0000 Received: from localhost ([127.0.0.1]:42666 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1lsMhT-00014m-79 for submit@debbugs.gnu.org; Sun, 13 Jun 2021 05:46:39 -0400 Received: from lists.gnu.org ([209.51.188.17]:55044) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1lsMhQ-00014e-Ud for submit@debbugs.gnu.org; Sun, 13 Jun 2021 05:46:37 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:33566) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1lsMhQ-0000i2-LK for guix-patches@gnu.org; Sun, 13 Jun 2021 05:46:36 -0400 Received: from h87-96-130-155.cust.a3fiber.se ([87.96.130.155]:53950 helo=mail.yoctocell.xyz) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1lsMhN-00089e-Db for guix-patches@gnu.org; Sun, 13 Jun 2021 05:46:35 -0400 From: Xinglu Chen DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=yoctocell.xyz; s=mail; t=1623577588; bh=13HwuM+W10K50OxZZqlbf5b4vPH1I4XgZpSAPa1+Rw0=; h=From:To:Subject:Date; b=cJCsMgxH/WYPOGp6qUhyJbJPhNKzCkfYBeZcEL09mGXMrqjmBMMN19mAGrE4yNNmM mHPsNACk67K++LdcNfEocRhLugQt9j2WousfzPqF5kQqzFALjR/zVjQGDV6Ava6cJK Nw4zhE5jWfEN0W8UtoS1HL9iScUQZPEcKM24ZtbU= Message-Id: Date: Sun, 13 Jun 2021 11:46:18 +0200 MIME-Version: 1.0 Received-SPF: pass client-ip=87.96.130.155; envelope-from=public@yoctocell.xyz; helo=mail.yoctocell.xyz X-Spam_score_int: 30 X-Spam_score: 3.0 X-Spam_bar: +++ X-Spam_report: (3.0 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, FROM_SUSPICIOUS_NTLD=0.498, FROM_SUSPICIOUS_NTLD_FP=1.593, PDS_OTHER_BAD_TLD=1.997, RDNS_DYNAMIC=0.982, SPF_HELO_NONE=0.001, SPF_PASS=-0.001, T_FILL_THIS_FORM_SHORT=0.01 autolearn=no autolearn_force=no X-Spam_action: no action X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list X-BeenThere: guix-patches@gnu.org List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: guix-patches-bounces+patchwork=mira.cbaines.net@gnu.org Sender: "Guix-patches" X-getmail-retrieved-from-mailbox: Patches When developing a Haskell package it is often useful to have a Guix package definition for that package, previously one would have to write that package definition by hand, and if the .cabal file changed one would manually update the Guix package definition. This commit allows one to specify a custom source for their package, meaning that one could programatically generate a Guix package definition for their local Haskell package. If the .cabal file changes, the generated package definition will also change accordingly. One could for instance write the following in a guix.scm file: (define-values (ghc-haskeme deps) (call-with-input-file "haskeme.cabal" (lambda (port) (hackage->guix-package "haskeme" #:port port #:source (local-file "." "haskeme-checkout" #:recursive? #t #:select? hg-predicate))))) ghc-haskeme Invoking ‘guix build -f guix.scm’ would then always build an up-to-date version of the package. * guix/import/hackage.scm (hackage-module->sexp): Add optional keyword argument ‘source’ (hackage->guix-package): Likewise. * tests/hackage.scm (eval-test-with-cabal): Likewise. ("hackage->guix-package local source"): New test. --- Without this I would have to manually write my Guix package definition, and manually update the ‘inputs’ field if I added a new dependency in my .cabal file. This patch offers something similar to pkgs.callCabal2nix (I could find any link to the docs, classic Nix) in Nixpkgs where i can just write the following --8<---------------cut here---------------start------------->8--- let haskellPackages = pkgs.haskell.packages.${compiler}.override { overrides = hpNew: hpOld: { haskeme = hpNew.callCabal2nix "haskeme" ./. { }; }; }; in { haskeme = haskellPackages.haskeme; } --8<---------------cut here---------------end--------------->8--- to get a Nix package definition of my Haskell package. guix/import/hackage.scm | 43 ++++++++++++++++++++++++++--------------- tests/hackage.scm | 28 +++++++++++++++++++++++++-- 2 files changed, 53 insertions(+), 18 deletions(-) base-commit: acb858881901aa28499f83f40d3e04d6e4749453 diff --git a/guix/import/hackage.scm b/guix/import/hackage.scm index f94a1e7087..326ab92365 100644 --- a/guix/import/hackage.scm +++ b/guix/import/hackage.scm @@ -227,10 +227,13 @@ package being processed and is used to filter references to itself." dependencies)) (define* (hackage-module->sexp cabal cabal-hash - #:key (include-test-dependencies? #t)) + #:key + (include-test-dependencies? #t) + (source #f)) "Return the `package' S-expression for a Cabal package. CABAL is the -representation of a Cabal file as produced by 'read-cabal'. CABAL-HASH is -the hash of the Cabal file." +representation of a Cabal file as produced by 'read-cabal'. CABAL-HASH is the +hash of the Cabal file. If SOURCE is specified, it will be used as the source +for the package." (define name (cabal-package-name cabal)) @@ -294,20 +297,24 @@ the hash of the Cabal file." (() '()) (args `((arguments (,'quasiquote ,args)))))) - (let ((tarball (with-store store - (download-to-store store source-url)))) + (let ((tarball (if source + #f + (with-store store + (download-to-store store source-url))))) (values `(package (name ,(hackage-name->package-name name)) (version ,version) - (source (origin - (method url-fetch) - (uri (string-append ,@(factorize-uri source-url version))) - (sha256 - (base32 - ,(if tarball - (bytevector->nix-base32-string (file-sha256 tarball)) - "failed to download tar archive"))))) + (source ,(if source + source + `(origin + (method url-fetch) + (uri (string-append ,@(factorize-uri source-url version))) + (sha256 + (base32 + ,(if tarball + (bytevector->nix-base32-string (file-sha256 tarball)) + "failed to download tar archive")))))) (build-system haskell-build-system) ,@(maybe-inputs 'inputs dependencies) ,@(maybe-inputs 'native-inputs native-dependencies) @@ -321,10 +328,12 @@ the hash of the Cabal file." (define* (hackage->guix-package package-name #:key (include-test-dependencies? #t) (port #f) + (source #f) (cabal-environment '())) "Fetch the Cabal file for PACKAGE-NAME from hackage.haskell.org, or, if the -called with keyword parameter PORT, from PORT. Return the `package' -S-expression corresponding to that package, or #f on failure. +called with keyword parameter PORT, from PORT. If SOURCE is specified, use it +as the source for the package instead of trying to fetch a tarball. Return +the `package' S-expression corresponding to that package, or #f on failure. CABAL-ENVIRONMENT is an alist defining the environment in which the Cabal conditionals are evaluated. The accepted keys are: \"os\", \"arch\", \"impl\" and the name of a flag. The value associated with a flag has to be either the @@ -338,7 +347,9 @@ respectively." (hackage-fetch-and-hash package-name)))) (and=> cabal-meta (compose (cut hackage-module->sexp <> cabal-hash #:include-test-dependencies? - include-test-dependencies?) + include-test-dependencies? + #:source + source) (cut eval-cabal <> cabal-environment))))) (define hackage->guix-package/m ;memoized variant diff --git a/tests/hackage.scm b/tests/hackage.scm index 66a13d9881..54590dcece 100644 --- a/tests/hackage.scm +++ b/tests/hackage.scm @@ -22,6 +22,7 @@ #:use-module (guix import cabal) #:use-module (guix import hackage) #:use-module (guix tests) + #:use-module (guix gexp) #:use-module (srfi srfi-64) #:use-module (ice-9 match)) @@ -186,9 +187,28 @@ library ('description (? string?)) ('license 'license:bsd-3))) -(define* (eval-test-with-cabal test-cabal matcher #:key (cabal-environment '())) +(define-package-matcher match-ghc-foo-local-source + ('package + ('name "ghc-foo") + ('version "1.0.0") + ('source + (? file-like?)) + ('build-system 'haskell-build-system) + ('inputs + ('quasiquote + (("ghc-http" ('unquote 'ghc-http))))) + ('home-page "http://test.org") + ('synopsis (? string?)) + ('description (? string?)) + ('license 'license:bsd-3))) + +(define* (eval-test-with-cabal test-cabal matcher + #:key (cabal-environment '()) (source #f)) (define port (open-input-string test-cabal)) - (matcher (hackage->guix-package "foo" #:port port #:cabal-environment cabal-environment))) + (matcher (hackage->guix-package "foo" + #:port port + #:cabal-environment cabal-environment + #:source source))) (test-assert "hackage->guix-package test 1" (eval-test-with-cabal test-cabal-1 match-ghc-foo)) @@ -208,6 +228,10 @@ library (eval-test-with-cabal test-cabal-5 match-ghc-foo #:cabal-environment '(("impl" . "ghc-7.8")))) +(test-assert "hackage->guix-package local source" + (eval-test-with-cabal test-cabal-1 match-ghc-foo-local-source + #:source (plain-file "dummy source" "source"))) + (define-package-matcher match-ghc-foo-6 ('package ('name "ghc-foo")