all messages for Guix-related lists mirrored at yhetil.org
 help / color / mirror / code / Atom feed
* [bug#35859] [PATCH] hackage import: Setup.hs generation and revision support
@ 2019-05-22 20:11 Robert Vollmert
  2019-05-23  8:50 ` [bug#35859] line ending fix Robert Vollmert
                   ` (3 more replies)
  0 siblings, 4 replies; 5+ messages in thread
From: Robert Vollmert @ 2019-05-22 20:11 UTC (permalink / raw)
  To: 35859

[-- Attachment #1: Type: text/plain, Size: 459 bytes --]

These patches are on top of

https://debbugs.gnu.org/cgi/bugreport.cgi?bug=35812 (fix cabal tests)
https://debbugs.gnu.org/cgi/bugreport.cgi?bug=35846 (braced properties)

- substitute missing Setup.hs and remove manual per-package workarounds
- handle hackage metadata revisions

I believe the code works, but some may not be the most idiomatic scheme
code. Particularly around building the quoted argument list and returning
a pair of cabal data and hash.


[-- Attachment #2: 0001-gnu-ghc-easy-plot-remove-superfluous-Setup.hs-rename.patch --]
[-- Type: application/octet-stream, Size: 1289 bytes --]

From 44c8df36d718940bcb1081e17dad17e2df42dd78 Mon Sep 17 00:00:00 2001
From: Robert Vollmert <rob@vllmrt.net>
Date: Fri, 17 May 2019 16:28:44 +0200
Subject: [PATCH 1/5] gnu: ghc-easy-plot: remove superfluous Setup.hs rename
 step

haskell-build-system already uses whichever of Setup.hs and
Setup.lhs exists.

* gnu/packages/haskell.scm (ghc-easy-plot): don't rename
Setup.lhs to Setup.hs
---
 gnu/packages/haskell.scm | 4 ----
 1 file changed, 4 deletions(-)

diff --git a/gnu/packages/haskell.scm b/gnu/packages/haskell.scm
index 61c6119322..c40581a8cd 100644
--- a/gnu/packages/haskell.scm
+++ b/gnu/packages/haskell.scm
@@ -8063,10 +8063,6 @@ interface for statistics based on hmatrix and GSL.")
         (base32 "18kndgvdj2apjpfga6fp7m16y1gx8zrwp3c5vfj03sx4v6jvciqk"))))
     (build-system haskell-build-system)
     (propagated-inputs `(("gnuplot" ,gnuplot)))
-    (arguments
-     `(#:phases (modify-phases %standard-phases
-                  (add-after 'unpack 'fix-setup-suffix
-                    (lambda _ (rename-file "Setup.lhs" "Setup.hs") #t)))))
     (home-page "https://hub.darcs.net/scravy/easyplot")
     (synopsis "Haskell plotting library based on gnuplot")
     (description "This package provides a plotting library for
-- 
2.21.0


[-- Attachment #3: 0002-guix-haskell-build-system-correct-haddock-phase-docu.patch --]
[-- Type: application/octet-stream, Size: 958 bytes --]

From 59fa86edcda6769bd5d9fb90342302a26e231e65 Mon Sep 17 00:00:00 2001
From: Robert Vollmert <rob@vllmrt.net>
Date: Fri, 17 May 2019 18:58:55 +0200
Subject: [PATCH 2/5] guix: haskell-build-system: correct haddock phase
 documentation

* guix/build/haskell-build-system.scm (haddock): Correct docstring
---
 guix/build/haskell-build-system.scm | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/guix/build/haskell-build-system.scm b/guix/build/haskell-build-system.scm
index 23d97e6602..5c5b32322b 100644
--- a/guix/build/haskell-build-system.scm
+++ b/guix/build/haskell-build-system.scm
@@ -260,7 +260,7 @@ given Haskell package."
   #t)
 
 (define* (haddock #:key outputs haddock? haddock-flags #:allow-other-keys)
-  "Run the test suite of a given Haskell package."
+  "Generate haddock documentation of a given Haskell package."
   (when haddock?
     (run-setuphs "haddock" haddock-flags))
   #t)
-- 
2.21.0


[-- Attachment #4: 0003-guix-haskell-build-system-generate-Setup.hs-if-not-e.patch --]
[-- Type: application/octet-stream, Size: 1721 bytes --]

From 9c2c8202f490a20340e2db5522a5813f0dd7183f Mon Sep 17 00:00:00 2001
From: Robert Vollmert <rob@vllmrt.net>
Date: Fri, 17 May 2019 16:26:31 +0200
Subject: [PATCH 3/5] guix: haskell-build-system: generate Setup.hs if not
 exists

The default Setup.hs is boilerplate that is frequently left out of
source packages, causing build failure for package definitions as
generated by `guix import hackage`. Compare
<https://github.com/phadej/time-compat/issues/4>

* guix/build/haskell-build-system.scm: Generate Setup.hs if missing,
after unpack phase.
---
 guix/build/haskell-build-system.scm | 12 ++++++++++++
 1 file changed, 12 insertions(+)

diff --git a/guix/build/haskell-build-system.scm b/guix/build/haskell-build-system.scm
index 5c5b32322b..0c648e510f 100644
--- a/guix/build/haskell-build-system.scm
+++ b/guix/build/haskell-build-system.scm
@@ -275,9 +275,21 @@ given Haskell package."
       (_ (error "Could not find a Cabal file to patch."))))
   #t)
 
+(define* (generate-setup #:rest empty)
+  "Generate boilerplate Setup.hs if missing."
+  (when (not (or (file-exists? "Setup.hs")
+                 (file-exists? "Setup.lhs")))
+    (format #t "generating missing Setup.hs~%")
+    (with-output-to-file "Setup.hs"
+      (lambda ()
+        (format #t "import Distribution.Simple~%")
+        (format #t "main = defaultMain~%"))))
+  #t)
+
 (define %standard-phases
   (modify-phases gnu:%standard-phases
     (add-after 'unpack 'patch-cabal-file patch-cabal-file)
+    (add-after 'unpack 'generate-setup generate-setup)
     (delete 'bootstrap)
     (add-before 'configure 'setup-compiler setup-compiler)
     (add-before 'install 'haddock haddock)
-- 
2.21.0


[-- Attachment #5: 0004-gnu-haskell-leave-Setup.hs-generation-to-build-syste.patch --]
[-- Type: application/octet-stream, Size: 3481 bytes --]

From 77952a3fe2fdbe027552149eef9d676b828b9e92 Mon Sep 17 00:00:00 2001
From: Robert Vollmert <rob@vllmrt.net>
Date: Fri, 17 May 2019 16:29:08 +0200
Subject: [PATCH 4/5] gnu: haskell: leave Setup.hs generation to build system

Remove explicit Setup.hs generation from the configure step
now that haskell-build-system does it.

* gnu/packages/haskell.scm (ghc-foundation, ghc-inline-c,
ghc-inline-c-cpp, ghc-rio): Don't generate Setup.hs
---
 gnu/packages/haskell.scm | 42 ----------------------------------------
 1 file changed, 42 deletions(-)

diff --git a/gnu/packages/haskell.scm b/gnu/packages/haskell.scm
index c40581a8cd..f12371f3ce 100644
--- a/gnu/packages/haskell.scm
+++ b/gnu/packages/haskell.scm
@@ -9688,16 +9688,6 @@ packages.")
         (base32
          "1q43y8wfj0wf9gdq2kzphwjwq6m5pvryy1lqgk954aq5z3ks1lsf"))))
     (build-system haskell-build-system)
-    (arguments
-     `(#:phases
-       (modify-phases %standard-phases
-         (add-after 'unpack 'add-setup-script
-           (lambda _
-             ;; The usual "Setup.hs" script is missing from the source.
-             (with-output-to-file "Setup.hs"
-               (lambda ()
-                 (format #t "import Distribution.Simple~%")
-                 (format #t "main = defaultMain~%"))))))))
     (inputs `(("ghc-basement" ,ghc-basement)))
     (home-page "https://github.com/haskell-foundation/foundation")
     (synopsis "Alternative prelude with batteries and no dependencies")
@@ -10575,16 +10565,6 @@ widths to the Char type.")
         (base32
          "064h8a4hp53a479d3ak0vmqbx8hi0cpg7zn4wp23rjy26dka8p7g"))))
     (build-system haskell-build-system)
-    (arguments
-     `(#:phases
-       (modify-phases %standard-phases
-         (add-after 'unpack 'add-setup-script
-           (lambda _
-             ;; The usual "Setup.hs" script is missing from the source.
-             (with-output-to-file "Setup.hs"
-               (lambda ()
-                 (format #t "import Distribution.Simple~%")
-                 (format #t "main = defaultMain~%"))))))))
     (inputs
      `(("ghc-exceptions" ,ghc-exceptions)
        ("ghc-hashable" ,ghc-hashable)
@@ -11107,17 +11087,6 @@ DOS/Windows paths and markup languages (such as XML).")
         (base32
          "0vbfrsqsi7mdziqsnj68bsqlwbqxxhvrmy9rv6w8z18d1m8w3n6h"))))
     (build-system haskell-build-system)
-    (arguments
-     `(#:phases
-       (modify-phases %standard-phases
-         (add-after 'unpack 'create-Setup.hs
-           (lambda _
-             (with-output-to-file "Setup.hs"
-               (lambda _
-                 (display "\
-import Distribution.Simple
-main = defaultMain")))
-             #t)))))
     (inputs
      `(("ghc-ansi-wl-pprint" ,ghc-ansi-wl-pprint)
        ("ghc-cryptohash" ,ghc-cryptohash)
@@ -11251,17 +11220,6 @@ handling wrong.")
         (base32
          "1rk7fmpkmxw9hhwr8df29kadnf0ybnwj64ggdbnsdrpfyhnkisci"))))
     (build-system haskell-build-system)
-    (arguments
-     `(#:phases
-       (modify-phases %standard-phases
-         (add-after 'unpack 'create-Setup.hs
-           (lambda _
-             (with-output-to-file "Setup.hs"
-               (lambda _
-                 (display "\
-import Distribution.Simple
-main = defaultMain")))
-             #t)))))
     (inputs
      `(("ghc-inline-c" ,ghc-inline-c)
        ("ghc-safe-exceptions" ,ghc-safe-exceptions)))
-- 
2.21.0


[-- Attachment #6: 0005-guix-import-hackage-handle-hackage-revisions.patch --]
[-- Type: application/octet-stream, Size: 7906 bytes --]

From 3b899cfd69dbc19fa542a0a790bee124868058ca Mon Sep 17 00:00:00 2001
From: Robert Vollmert <rob@vllmrt.net>
Date: Fri, 17 May 2019 22:52:24 +0200
Subject: [PATCH 5/5] guix: import: hackage: handle hackage revisions

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/import/cabal.scm   |  7 +++--
 guix/import/hackage.scm | 61 ++++++++++++++++++++++++++++++-----------
 2 files changed, 50 insertions(+), 18 deletions(-)

diff --git a/guix/import/cabal.scm b/guix/import/cabal.scm
index 383702f2be..97105eb154 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
@@ -640,13 +641,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 <cabal-package>
-  (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)
@@ -840,6 +842,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
@@ -858,7 +861,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 5b80a7ea1d..fe0c6d13e4 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)))))))
 
-(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)
+  (let-values (((port get-hash) (open-sha256-input-port port)))
+    (cons
+      (read-cabal 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)))
@@ -127,10 +133,18 @@ version."
     (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 (canonical-newline-port 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
@@ -196,15 +210,19 @@ 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))
@@ -250,9 +268,17 @@ representation of a Cabal file as produced by 'read-cabal'."
                    (list 'quasiquote inputs))))))
   
   (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)))
+      '()))
 
   (let ((tarball (with-store store
                    (download-to-store store source-url))))
@@ -293,13 +319,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 (canonical-newline-port 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
   (memoize hackage->guix-package-impl))
-- 
2.21.0


^ permalink raw reply related	[flat|nested] 5+ messages in thread

* [bug#35859] line ending fix
  2019-05-22 20:11 [bug#35859] [PATCH] hackage import: Setup.hs generation and revision support Robert Vollmert
@ 2019-05-23  8:50 ` Robert Vollmert
  2019-05-23 13:27 ` [bug#35859] fixed patch set, including test fixes Robert Vollmert
                   ` (2 subsequent siblings)
  3 siblings, 0 replies; 5+ messages in thread
From: Robert Vollmert @ 2019-05-23  8:50 UTC (permalink / raw)
  To: 35859

[-- Attachment #1: Type: text/plain, Size: 73 bytes --]

Updated patch to deal with CRLF line endings when computing cabal hash.


[-- Attachment #2: 0005-guix-import-hackage-handle-hackage-revisions.patch --]
[-- Type: application/octet-stream, Size: 7881 bytes --]

From ee2300e5605745a71e77c0972aebc21e826c581a Mon Sep 17 00:00:00 2001
From: Robert Vollmert <rob@vllmrt.net>
Date: Fri, 17 May 2019 22:52:24 +0200
Subject: [PATCH 5/5] guix: import: hackage: handle hackage revisions

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/import/cabal.scm   |  7 +++--
 guix/import/hackage.scm | 61 ++++++++++++++++++++++++++++++-----------
 2 files changed, 50 insertions(+), 18 deletions(-)

diff --git a/guix/import/cabal.scm b/guix/import/cabal.scm
index 3028ed2882..312927a573 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 <cabal-package>
-  (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 5b80a7ea1d..0bd9034087 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)))))))
 
-(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)
+  (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)))
@@ -127,10 +133,18 @@ version."
     (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
@@ -196,15 +210,19 @@ 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))
@@ -250,9 +268,17 @@ representation of a Cabal file as produced by 'read-cabal'."
                    (list 'quasiquote inputs))))))
   
   (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)))
+      '()))
 
   (let ((tarball (with-store store
                    (download-to-store store source-url))))
@@ -293,13 +319,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
   (memoize hackage->guix-package-impl))
-- 
2.21.0


^ permalink raw reply related	[flat|nested] 5+ messages in thread

* [bug#35859] fixed patch set, including test fixes
  2019-05-22 20:11 [bug#35859] [PATCH] hackage import: Setup.hs generation and revision support Robert Vollmert
  2019-05-23  8:50 ` [bug#35859] line ending fix Robert Vollmert
@ 2019-05-23 13:27 ` Robert Vollmert
  2019-05-24 14:56 ` [bug#35859] fixes bug in patch 0003 Robert Vollmert
  2019-05-24 14:58 ` [bug#35859] improves output in patch 0010 Robert Vollmert
  3 siblings, 0 replies; 5+ messages in thread
From: Robert Vollmert @ 2019-05-23 13:27 UTC (permalink / raw)
  To: 35859

[-- Attachment #1: Type: text/plain, Size: 379 bytes --]

The previous version of this patch caused some test failures due
to conflict with the hackage-fetch mocking in tests/hackage.scm.

This set reworks the tests to not mock, and incorporates updated
versions of the previous patch sets

https://debbugs.gnu.org/cgi/bugreport.cgi?bug=35812
 (fix cabal tests)

https://debbugs.gnu.org/cgi/bugreport.cgi?bug=35846
 (braced properties)


[-- Attachment #2: 0001-tests-fix-cabal-tests-to-test-and-pass.patch --]
[-- Type: application/octet-stream, Size: 5453 bytes --]

From 8b6dac85a9f6c4e851c1a75a4958dff7915fb2f1 Mon Sep 17 00:00:00 2001
From: Robert Vollmert <rob@vllmrt.net>
Date: Fri, 17 May 2019 10:48:42 +0200
Subject: [PATCH 01/11] tests: fix cabal tests to test and pass

* guix/import/hackage.scm: export unmemoized import function
* tests/hackage.scm: use unmemoized import function to make tests independent
* tests/hackage.scm: fix failing test-cabal-6 by providing expected output
---
 guix/import/hackage.scm | 31 +++++++++++++++++--------------
 tests/hackage.scm       | 39 ++++++++++++++++++++++++++++++++++++---
 2 files changed, 53 insertions(+), 17 deletions(-)

diff --git a/guix/import/hackage.scm b/guix/import/hackage.scm
index 2a51420d14..5b80a7ea1d 100644
--- a/guix/import/hackage.scm
+++ b/guix/import/hackage.scm
@@ -40,6 +40,7 @@
   #:use-module (guix packages)
   #:use-module ((guix utils) #:select (call-with-temporary-output-file))
   #:export (hackage->guix-package
+            hackage->guix-package-impl
             hackage-recursive-import
             %hackage-updater
 
@@ -277,13 +278,12 @@ representation of a Cabal file as produced by 'read-cabal'."
         (license ,(string->license (cabal-package-license cabal))))
      (append hackage-dependencies hackage-native-dependencies))))
 
-(define hackage->guix-package
-  (memoize
-   (lambda* (package-name #:key
-                          (include-test-dependencies? #t)
-                          (port #f)
-                          (cabal-environment '()))
-     "Fetch the Cabal file for PACKAGE-NAME from hackage.haskell.org, or, if the
+(define hackage->guix-package-impl
+  (lambda* (package-name #:key
+                         (include-test-dependencies? #t)
+                         (port #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.
 CABAL-ENVIRONMENT is an alist defining the environment in which the Cabal
@@ -293,13 +293,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)))))))
+   (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))))))
+
+(define hackage->guix-package
+  (memoize hackage->guix-package-impl))
 
 (define* (hackage-recursive-import package-name . args)
   (recursive-import package-name #f
diff --git a/tests/hackage.scm b/tests/hackage.scm
index e17851a213..e56aa996d6 100644
--- a/tests/hackage.scm
+++ b/tests/hackage.scm
@@ -161,7 +161,7 @@ library
     (lambda (name-version)
       (call-with-input-string test-cabal
         read-cabal)))
-   (match (hackage->guix-package "foo" #:cabal-environment cabal-environment)
+   (match (hackage->guix-package-impl "foo" #:cabal-environment cabal-environment)
      (('package
         ('name "ghc-foo")
         ('version "1.0.0")
@@ -207,8 +207,41 @@ library
                         #:cabal-environment '(("impl" . "ghc-7.8"))))
 
 (test-assert "hackage->guix-package test 6"
-  (eval-test-with-cabal test-cabal-6
-                        #:cabal-environment '(("impl" . "ghc-7.8"))))
+  (mock
+   ((guix import hackage) hackage-fetch
+    (lambda (name-version)
+      (call-with-input-string test-cabal-6
+        read-cabal)))
+   (match (hackage->guix-package-impl "foo")
+     (('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-b" ('unquote 'ghc-b))
+           ("ghc-http" ('unquote 'ghc-http))
+           ("ghc-mtl" ('unquote 'ghc-mtl)))))
+        ('native-inputs
+         ('quasiquote
+          (("ghc-haskell-gi" ('unquote 'ghc-haskell-gi)))))
+        ('home-page "http://test.org")
+        ('synopsis (? string?))
+        ('description (? string?))
+        ('license 'bsd-3))
+      #t)
+     (x
+      (pk 'fail x #f)))))
 
 (test-assert "read-cabal test 1"
   (match (call-with-input-string test-read-cabal-1 read-cabal)
-- 
2.21.0


[-- Attachment #3: 0002-tests-hackage-test-multiline-cabal-description.patch --]
[-- Type: application/octet-stream, Size: 1514 bytes --]

From 1a001cd80d8f5c3e763f8632e10f959775aa7887 Mon Sep 17 00:00:00 2001
From: Robert Vollmert <rob@vllmrt.net>
Date: Sat, 18 May 2019 03:37:43 +0200
Subject: [PATCH 02/11] tests: hackage: test multiline cabal description

* tests/hackage.scm: Add test case with multi-line description.
---
 tests/hackage.scm | 19 +++++++++++++++++++
 1 file changed, 19 insertions(+)

diff --git a/tests/hackage.scm b/tests/hackage.scm
index e56aa996d6..41cea73fe7 100644
--- a/tests/hackage.scm
+++ b/tests/hackage.scm
@@ -128,6 +128,21 @@ library
       mtl        >= 2.0      && < 3
 ")
 
+;; Check multi-line layouted description
+(define test-cabal-7
+  "name: foo
+version: 1.0.0
+homepage: http://test.org
+synopsis: synopsis
+description:   first line
+               second line
+license: BSD3
+executable cabal
+  build-depends:
+    HTTP       >= 4000.2.5 && < 4000.3,
+    mtl        >= 2.0      && < 3
+")
+
 ;; A fragment of a real Cabal file with minor modification to check precedence
 ;; of 'and' over 'or', missing final newline, spaces between keywords and
 ;; parentheses and between key and column.
@@ -243,6 +258,10 @@ library
      (x
       (pk 'fail x #f)))))
 
+(test-assert "hackage->guix-package test 7"
+  (eval-test-with-cabal test-cabal-7
+                        #:cabal-environment '(("impl" . "ghc-7.8"))))
+
 (test-assert "read-cabal test 1"
   (match (call-with-input-string test-read-cabal-1 read-cabal)
     ((("name" ("test-me"))
-- 
2.21.0


[-- Attachment #4: 0003-guix-import-cabal-parse-braced-description-propertie.patch --]
[-- Type: application/octet-stream, Size: 5244 bytes --]

From 59ab5435e3cb77831a97831d82f5ab419345719b Mon Sep 17 00:00:00 2001
From: Robert Vollmert <rob@vllmrt.net>
Date: Fri, 17 May 2019 14:26:36 +0200
Subject: [PATCH 03/11] guix: import: cabal: parse braced description
 properties

* guix/import/cabal.scm: generalize property bracing to both
                         layouted and simple braced blocks
* guix/tests/hackage.scm: test braced description import
---
 guix/import/cabal.scm | 35 ++++++++++++++++++++++++++++-------
 tests/hackage.scm     | 22 ++++++++++++++++++++++
 2 files changed, 50 insertions(+), 7 deletions(-)

diff --git a/guix/import/cabal.scm b/guix/import/cabal.scm
index 13c2f3f48c..3028ed2882 100644
--- a/guix/import/cabal.scm
+++ b/guix/import/cabal.scm
@@ -270,6 +270,10 @@ following lines with indentation larger than MIN-INDENT."
                 (peek-next-line-indent port)))
         val)))
 
+(define* (read-braced-value port)
+  "Read up to a closing brace."
+  (string-trim-both (read-delimited "}" port 'trim)))
+
 (define (lex-white-space port bol)
   "Consume white spaces and comment lines on PORT.  If a new line is started return #t,
 otherwise return BOL (beginning-of-line)."
@@ -343,8 +347,11 @@ matching a string against the created regexp."
                 (make-regexp pat))))
     (cut regexp-exec rx <>)))
 
-(define is-property (make-rx-matcher "([a-z0-9-]+)[ \t]*:[ \t]*(\\w?.*)$"
-                                     regexp/icase))
+(define is-layout-property (make-rx-matcher "([a-z0-9-]+)[ \t]*:[ \t]*(\\w?[^\\{\\}]*)$"
+                                            regexp/icase))
+
+(define is-braced-property (make-rx-matcher "([a-z0-9-]+)[ \t]*:[ \t]*\\{[ \t]*$"
+                                            regexp/icase))
 
 (define is-flag (make-rx-matcher "^flag +([a-z0-9_-]+)"
                                  regexp/icase))
@@ -435,13 +442,19 @@ string with the read characters."
                  (begin (unread-char c) (list->string res)))))
           (else (list->string res)))))
 
-(define (lex-property k-v-rx-res loc port)
+(define (lex-layout-property k-v-rx-res loc port)
   (let ((key (string-downcase (match:substring k-v-rx-res 1)))
         (value (match:substring k-v-rx-res 2)))
     (make-lexical-token
      'PROPERTY loc
      (list key `(,(read-value port value (current-indentation)))))))
 
+(define (lex-braced-property k-rx-res loc port)
+  (let ((key (string-downcase (match:substring k-rx-res 1))))
+    (make-lexical-token
+     'PROPERTY loc
+     (list key `(,(read-braced-value port))))))
+
 (define (lex-rx-res rx-res token loc)
   (let ((name (string-downcase (match:substring rx-res 1))))
     (make-lexical-token token loc name)))
@@ -552,7 +565,6 @@ LOC is the current port location."
 the current port location."
   (let* ((s (read-delimited "\n{}" port 'peek)))
     (cond
-     ((is-property s) => (cut lex-property <> loc port))
      ((is-flag s) => (cut lex-flag <> loc))
      ((is-src-repo s) => (cut lex-src-repo <> loc))
      ((is-exec s) => (cut lex-exec <> loc))
@@ -561,13 +573,22 @@ the current port location."
      ((is-benchmark s) => (cut lex-benchmark <> loc))
      ((is-lib s) (lex-lib loc))
      ((is-else s) (lex-else loc))
-     (else
-      #f))))
+     (else (unread-string s port) #f))))
+
+(define (lex-property port loc)
+  (let* ((s (read-delimited "\n" port 'peek)))
+    (cond
+      ((is-braced-property s) => (cut lex-braced-property <> loc port))
+      ((is-layout-property s) => (cut lex-layout-property <> loc port))
+      (else #f))))
 
 (define (lex-token port)
   (let* ((loc (make-source-location (cabal-file-name) (port-line port)
                                     (port-column port) -1 -1)))
-    (or (lex-single-char port loc) (lex-word port loc) (lex-line port loc))))
+    (or (lex-single-char port loc)
+        (lex-word port loc)
+        (lex-line port loc)
+        (lex-property port loc))))
 
 ;; Lexer- and error-function generators
 
diff --git a/tests/hackage.scm b/tests/hackage.scm
index 41cea73fe7..733d540c20 100644
--- a/tests/hackage.scm
+++ b/tests/hackage.scm
@@ -143,6 +143,24 @@ executable cabal
     mtl        >= 2.0      && < 3
 ")
 
+;; Check braces instead of layout
+(define test-cabal-8
+  "name: foo
+version: 1.0.0
+homepage: http://test.org
+synopsis: synopsis
+description: {
+first line
+second line
+}
+license: BSD3
+executable cabal
+  build-depends:
+    HTTP       >= 4000.2.5 && < 4000.3,
+    mtl        >= 2.0      && < 3
+")
+
+
 ;; A fragment of a real Cabal file with minor modification to check precedence
 ;; of 'and' over 'or', missing final newline, spaces between keywords and
 ;; parentheses and between key and column.
@@ -262,6 +280,10 @@ library
   (eval-test-with-cabal test-cabal-7
                         #:cabal-environment '(("impl" . "ghc-7.8"))))
 
+(test-assert "hackage->guix-package test 8"
+  (eval-test-with-cabal test-cabal-8
+                        #:cabal-environment '(("impl" . "ghc-7.8"))))
+
 (test-assert "read-cabal test 1"
   (match (call-with-input-string test-read-cabal-1 read-cabal)
     ((("name" ("test-me"))
-- 
2.21.0


[-- Attachment #5: 0004-tests-hackage-avoid-mock-and-extract-test-data.patch --]
[-- Type: application/octet-stream, Size: 6445 bytes --]

From 716761b051b27d78bf1f374ac287a94b14cc2bca Mon Sep 17 00:00:00 2001
From: Robert Vollmert <rob@vllmrt.net>
Date: Sat, 18 May 2019 04:58:18 +0200
Subject: [PATCH 04/11] tests: hackage: avoid mock, and extract test data

This is partially in order to make tests depend less on the
implementation of `hackage-fetch`, in preparation for hackage
revision import.

* tests/hackage.scm: Provide cabal input port directly, instead
of mocking hackage-fetch. And make cabal tests more explicit and
consistent by defining package pattern per test.
---
 tests/hackage.scm | 141 +++++++++++++++++++++-------------------------
 1 file changed, 65 insertions(+), 76 deletions(-)

diff --git a/tests/hackage.scm b/tests/hackage.scm
index 733d540c20..5f47e909c6 100644
--- a/tests/hackage.scm
+++ b/tests/hackage.scm
@@ -188,101 +188,90 @@ library
 
 (test-begin "hackage")
 
-(define* (eval-test-with-cabal test-cabal #:key (cabal-environment '()))
-  (mock
-   ((guix import hackage) hackage-fetch
-    (lambda (name-version)
-      (call-with-input-string test-cabal
-        read-cabal)))
-   (match (hackage->guix-package-impl "foo" #:cabal-environment cabal-environment)
-     (('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))
-           ("ghc-mtl" ('unquote 'ghc-mtl)))))
-        ('home-page "http://test.org")
-        ('synopsis (? string?))
-        ('description (? string?))
-        ('license 'bsd-3))
-      #t)
-     (x
-      (pk 'fail x #f)))))
+(define ghc-foo-pattern
+ '('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))
+       ("ghc-mtl" ('unquote 'ghc-mtl)))))
+    ('home-page "http://test.org")
+    ('synopsis (? string?))
+    ('description (? string?))
+    ('license 'bsd-3)))
+
+(define* (eval-test-with-cabal test-cabal package-pattern #:key (cabal-environment '()))
+  (define port (open-input-string test-cabal))
+  (match (hackage->guix-package-impl "foo" #:port port #:cabal-environment cabal-environment)
+    (package-pattern #t)
+    (x               (pk 'fail x #f))))
 
 (test-assert "hackage->guix-package test 1"
-  (eval-test-with-cabal test-cabal-1))
+  (eval-test-with-cabal test-cabal-1 ghc-foo-pattern))
 
 (test-assert "hackage->guix-package test 2"
-  (eval-test-with-cabal test-cabal-2))
+  (eval-test-with-cabal test-cabal-2 ghc-foo-pattern))
 
 (test-assert "hackage->guix-package test 3"
-  (eval-test-with-cabal test-cabal-3
+  (eval-test-with-cabal test-cabal-3 ghc-foo-pattern
                         #:cabal-environment '(("impl" . "ghc-7.8"))))
 
 (test-assert "hackage->guix-package test 4"
-  (eval-test-with-cabal test-cabal-4
+  (eval-test-with-cabal test-cabal-4 ghc-foo-pattern
                         #:cabal-environment '(("impl" . "ghc-7.8"))))
 
 (test-assert "hackage->guix-package test 5"
-  (eval-test-with-cabal test-cabal-5
+  (eval-test-with-cabal test-cabal-5 ghc-foo-pattern
                         #:cabal-environment '(("impl" . "ghc-7.8"))))
 
+(define ghc-foo-pattern-6
+ '('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-b" ('unquote 'ghc-b))
+       ("ghc-http" ('unquote 'ghc-http))
+       ("ghc-mtl" ('unquote 'ghc-mtl)))))
+    ('native-inputs
+     ('quasiquote
+      (("ghc-haskell-gi" ('unquote 'ghc-haskell-gi)))))
+    ('home-page "http://test.org")
+    ('synopsis (? string?))
+    ('description (? string?))
+    ('license 'bsd-3)))
+
 (test-assert "hackage->guix-package test 6"
-  (mock
-   ((guix import hackage) hackage-fetch
-    (lambda (name-version)
-      (call-with-input-string test-cabal-6
-        read-cabal)))
-   (match (hackage->guix-package-impl "foo")
-     (('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-b" ('unquote 'ghc-b))
-           ("ghc-http" ('unquote 'ghc-http))
-           ("ghc-mtl" ('unquote 'ghc-mtl)))))
-        ('native-inputs
-         ('quasiquote
-          (("ghc-haskell-gi" ('unquote 'ghc-haskell-gi)))))
-        ('home-page "http://test.org")
-        ('synopsis (? string?))
-        ('description (? string?))
-        ('license 'bsd-3))
-      #t)
-     (x
-      (pk 'fail x #f)))))
+  (eval-test-with-cabal test-cabal-6 ghc-foo-pattern-6))
 
 (test-assert "hackage->guix-package test 7"
-  (eval-test-with-cabal test-cabal-7
-                        #:cabal-environment '(("impl" . "ghc-7.8"))))
+  (eval-test-with-cabal test-cabal-7 ghc-foo-pattern))
 
 (test-assert "hackage->guix-package test 8"
-  (eval-test-with-cabal test-cabal-8
-                        #:cabal-environment '(("impl" . "ghc-7.8"))))
+  (eval-test-with-cabal test-cabal-8 ghc-foo-pattern))
 
 (test-assert "read-cabal test 1"
   (match (call-with-input-string test-read-cabal-1 read-cabal)
-- 
2.21.0


[-- Attachment #6: 0005-gnu-ghc-easy-plot-remove-superfluous-Setup.hs-rename.patch --]
[-- Type: application/octet-stream, Size: 1291 bytes --]

From 03d28f656160a541cbc33c9b8dc693d2b9b4774c Mon Sep 17 00:00:00 2001
From: Robert Vollmert <rob@vllmrt.net>
Date: Fri, 17 May 2019 16:28:44 +0200
Subject: [PATCH 05/11] gnu: ghc-easy-plot: remove superfluous Setup.hs rename
 step

haskell-build-system already uses whichever of Setup.hs and
Setup.lhs exists.

* gnu/packages/haskell.scm (ghc-easy-plot): don't rename
Setup.lhs to Setup.hs
---
 gnu/packages/haskell.scm | 4 ----
 1 file changed, 4 deletions(-)

diff --git a/gnu/packages/haskell.scm b/gnu/packages/haskell.scm
index 61c6119322..c40581a8cd 100644
--- a/gnu/packages/haskell.scm
+++ b/gnu/packages/haskell.scm
@@ -8063,10 +8063,6 @@ interface for statistics based on hmatrix and GSL.")
         (base32 "18kndgvdj2apjpfga6fp7m16y1gx8zrwp3c5vfj03sx4v6jvciqk"))))
     (build-system haskell-build-system)
     (propagated-inputs `(("gnuplot" ,gnuplot)))
-    (arguments
-     `(#:phases (modify-phases %standard-phases
-                  (add-after 'unpack 'fix-setup-suffix
-                    (lambda _ (rename-file "Setup.lhs" "Setup.hs") #t)))))
     (home-page "https://hub.darcs.net/scravy/easyplot")
     (synopsis "Haskell plotting library based on gnuplot")
     (description "This package provides a plotting library for
-- 
2.21.0


[-- Attachment #7: 0006-guix-haskell-build-system-correct-haddock-phase-docu.patch --]
[-- Type: application/octet-stream, Size: 960 bytes --]

From 97d51b39acb8d08a63f39256c0c763b948085d01 Mon Sep 17 00:00:00 2001
From: Robert Vollmert <rob@vllmrt.net>
Date: Fri, 17 May 2019 18:58:55 +0200
Subject: [PATCH 06/11] guix: haskell-build-system: correct haddock phase
 documentation

* guix/build/haskell-build-system.scm (haddock): Correct docstring
---
 guix/build/haskell-build-system.scm | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/guix/build/haskell-build-system.scm b/guix/build/haskell-build-system.scm
index 23d97e6602..5c5b32322b 100644
--- a/guix/build/haskell-build-system.scm
+++ b/guix/build/haskell-build-system.scm
@@ -260,7 +260,7 @@ given Haskell package."
   #t)
 
 (define* (haddock #:key outputs haddock? haddock-flags #:allow-other-keys)
-  "Run the test suite of a given Haskell package."
+  "Generate haddock documentation of a given Haskell package."
   (when haddock?
     (run-setuphs "haddock" haddock-flags))
   #t)
-- 
2.21.0


[-- Attachment #8: 0007-guix-haskell-build-system-generate-Setup.hs-if-not-e.patch --]
[-- Type: application/octet-stream, Size: 1723 bytes --]

From a502063aa4c26f171f081fdcab30a2b157534de8 Mon Sep 17 00:00:00 2001
From: Robert Vollmert <rob@vllmrt.net>
Date: Fri, 17 May 2019 16:26:31 +0200
Subject: [PATCH 07/11] guix: haskell-build-system: generate Setup.hs if not
 exists

The default Setup.hs is boilerplate that is frequently left out of
source packages, causing build failure for package definitions as
generated by `guix import hackage`. Compare
<https://github.com/phadej/time-compat/issues/4>

* guix/build/haskell-build-system.scm: Generate Setup.hs if missing,
after unpack phase.
---
 guix/build/haskell-build-system.scm | 12 ++++++++++++
 1 file changed, 12 insertions(+)

diff --git a/guix/build/haskell-build-system.scm b/guix/build/haskell-build-system.scm
index 5c5b32322b..0c648e510f 100644
--- a/guix/build/haskell-build-system.scm
+++ b/guix/build/haskell-build-system.scm
@@ -275,9 +275,21 @@ given Haskell package."
       (_ (error "Could not find a Cabal file to patch."))))
   #t)
 
+(define* (generate-setup #:rest empty)
+  "Generate boilerplate Setup.hs if missing."
+  (when (not (or (file-exists? "Setup.hs")
+                 (file-exists? "Setup.lhs")))
+    (format #t "generating missing Setup.hs~%")
+    (with-output-to-file "Setup.hs"
+      (lambda ()
+        (format #t "import Distribution.Simple~%")
+        (format #t "main = defaultMain~%"))))
+  #t)
+
 (define %standard-phases
   (modify-phases gnu:%standard-phases
     (add-after 'unpack 'patch-cabal-file patch-cabal-file)
+    (add-after 'unpack 'generate-setup generate-setup)
     (delete 'bootstrap)
     (add-before 'configure 'setup-compiler setup-compiler)
     (add-before 'install 'haddock haddock)
-- 
2.21.0


[-- Attachment #9: 0008-gnu-haskell-leave-Setup.hs-generation-to-build-syste.patch --]
[-- Type: application/octet-stream, Size: 3483 bytes --]

From f013a4894022606d526020eb64fb5301832096d7 Mon Sep 17 00:00:00 2001
From: Robert Vollmert <rob@vllmrt.net>
Date: Fri, 17 May 2019 16:29:08 +0200
Subject: [PATCH 08/11] gnu: haskell: leave Setup.hs generation to build system

Remove explicit Setup.hs generation from the configure step
now that haskell-build-system does it.

* gnu/packages/haskell.scm (ghc-foundation, ghc-inline-c,
ghc-inline-c-cpp, ghc-rio): Don't generate Setup.hs
---
 gnu/packages/haskell.scm | 42 ----------------------------------------
 1 file changed, 42 deletions(-)

diff --git a/gnu/packages/haskell.scm b/gnu/packages/haskell.scm
index c40581a8cd..f12371f3ce 100644
--- a/gnu/packages/haskell.scm
+++ b/gnu/packages/haskell.scm
@@ -9688,16 +9688,6 @@ packages.")
         (base32
          "1q43y8wfj0wf9gdq2kzphwjwq6m5pvryy1lqgk954aq5z3ks1lsf"))))
     (build-system haskell-build-system)
-    (arguments
-     `(#:phases
-       (modify-phases %standard-phases
-         (add-after 'unpack 'add-setup-script
-           (lambda _
-             ;; The usual "Setup.hs" script is missing from the source.
-             (with-output-to-file "Setup.hs"
-               (lambda ()
-                 (format #t "import Distribution.Simple~%")
-                 (format #t "main = defaultMain~%"))))))))
     (inputs `(("ghc-basement" ,ghc-basement)))
     (home-page "https://github.com/haskell-foundation/foundation")
     (synopsis "Alternative prelude with batteries and no dependencies")
@@ -10575,16 +10565,6 @@ widths to the Char type.")
         (base32
          "064h8a4hp53a479d3ak0vmqbx8hi0cpg7zn4wp23rjy26dka8p7g"))))
     (build-system haskell-build-system)
-    (arguments
-     `(#:phases
-       (modify-phases %standard-phases
-         (add-after 'unpack 'add-setup-script
-           (lambda _
-             ;; The usual "Setup.hs" script is missing from the source.
-             (with-output-to-file "Setup.hs"
-               (lambda ()
-                 (format #t "import Distribution.Simple~%")
-                 (format #t "main = defaultMain~%"))))))))
     (inputs
      `(("ghc-exceptions" ,ghc-exceptions)
        ("ghc-hashable" ,ghc-hashable)
@@ -11107,17 +11087,6 @@ DOS/Windows paths and markup languages (such as XML).")
         (base32
          "0vbfrsqsi7mdziqsnj68bsqlwbqxxhvrmy9rv6w8z18d1m8w3n6h"))))
     (build-system haskell-build-system)
-    (arguments
-     `(#:phases
-       (modify-phases %standard-phases
-         (add-after 'unpack 'create-Setup.hs
-           (lambda _
-             (with-output-to-file "Setup.hs"
-               (lambda _
-                 (display "\
-import Distribution.Simple
-main = defaultMain")))
-             #t)))))
     (inputs
      `(("ghc-ansi-wl-pprint" ,ghc-ansi-wl-pprint)
        ("ghc-cryptohash" ,ghc-cryptohash)
@@ -11251,17 +11220,6 @@ handling wrong.")
         (base32
          "1rk7fmpkmxw9hhwr8df29kadnf0ybnwj64ggdbnsdrpfyhnkisci"))))
     (build-system haskell-build-system)
-    (arguments
-     `(#:phases
-       (modify-phases %standard-phases
-         (add-after 'unpack 'create-Setup.hs
-           (lambda _
-             (with-output-to-file "Setup.hs"
-               (lambda _
-                 (display "\
-import Distribution.Simple
-main = defaultMain")))
-             #t)))))
     (inputs
      `(("ghc-inline-c" ,ghc-inline-c)
        ("ghc-safe-exceptions" ,ghc-safe-exceptions)))
-- 
2.21.0


[-- Attachment #10: 0009-guix-import-hackage-handle-hackage-revisions.patch --]
[-- Type: application/octet-stream, Size: 7883 bytes --]

From 649804c95c3946aac9ea146889dcbafdd300bb22 Mon Sep 17 00:00:00 2001
From: Robert Vollmert <rob@vllmrt.net>
Date: Fri, 17 May 2019 22:52:24 +0200
Subject: [PATCH 09/11] guix: import: hackage: handle hackage revisions

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/import/cabal.scm   |  7 +++--
 guix/import/hackage.scm | 61 ++++++++++++++++++++++++++++++-----------
 2 files changed, 50 insertions(+), 18 deletions(-)

diff --git a/guix/import/cabal.scm b/guix/import/cabal.scm
index 3028ed2882..312927a573 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 <cabal-package>
-  (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 5b80a7ea1d..0bd9034087 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)))))))
 
-(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)
+  (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)))
@@ -127,10 +133,18 @@ version."
     (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
@@ -196,15 +210,19 @@ 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))
@@ -250,9 +268,17 @@ representation of a Cabal file as produced by 'read-cabal'."
                    (list 'quasiquote inputs))))))
   
   (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)))
+      '()))
 
   (let ((tarball (with-store store
                    (download-to-store store source-url))))
@@ -293,13 +319,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
   (memoize hackage->guix-package-impl))
-- 
2.21.0


[-- Attachment #11: 0010-guix-import-hackage-log-when-we-start-with-a-file.patch --]
[-- Type: application/octet-stream, Size: 1105 bytes --]

From 742b3db4c60e052e65c21dae1d5771f32cf01963 Mon Sep 17 00:00:00 2001
From: Robert Vollmert <rob@vllmrt.net>
Date: Sat, 18 May 2019 03:37:27 +0200
Subject: [PATCH 10/11] guix: import: hackage: log when we start with a file

This helps figuring out what errors are in relation to, particularly
during recursive import.

* guix/import/hackage.scm: Log before fetching/parsing a cabal file.
---
 guix/import/hackage.scm | 1 +
 1 file changed, 1 insertion(+)

diff --git a/guix/import/hackage.scm b/guix/import/hackage.scm
index 0bd9034087..d8baac0850 100644
--- a/guix/import/hackage.scm
+++ b/guix/import/hackage.scm
@@ -319,6 +319,7 @@ 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."
+   (format (current-error-port) "reading cabal file for ~a~%" package-name)
    (match
      (if port (read-cabal-and-hash port)
               (hackage-fetch-and-hash package-name))
-- 
2.21.0


^ permalink raw reply related	[flat|nested] 5+ messages in thread

* [bug#35859] fixes bug in patch 0003
  2019-05-22 20:11 [bug#35859] [PATCH] hackage import: Setup.hs generation and revision support Robert Vollmert
  2019-05-23  8:50 ` [bug#35859] line ending fix Robert Vollmert
  2019-05-23 13:27 ` [bug#35859] fixed patch set, including test fixes Robert Vollmert
@ 2019-05-24 14:56 ` Robert Vollmert
  2019-05-24 14:58 ` [bug#35859] improves output in patch 0010 Robert Vollmert
  3 siblings, 0 replies; 5+ messages in thread
From: Robert Vollmert @ 2019-05-24 14:56 UTC (permalink / raw)
  To: 35859

[-- Attachment #1: Type: text/plain, Size: 128 bytes --]

Patch 0003 introduced a bug where descriptions with backslash characters were no longer parsed.
This is an updated version.


[-- Attachment #2: 0003-guix-import-cabal-parse-braced-description-propertie.patch --]
[-- Type: application/octet-stream, Size: 5240 bytes --]

From fd4786852510221c56a3eeba4ed41e11903a1438 Mon Sep 17 00:00:00 2001
From: Robert Vollmert <rob@vllmrt.net>
Date: Fri, 17 May 2019 14:26:36 +0200
Subject: [PATCH 03/13] guix: import: cabal: parse braced description
 properties

* guix/import/cabal.scm: generalize property bracing to both
                         layouted and simple braced blocks
* guix/tests/hackage.scm: test braced description import
---
 guix/import/cabal.scm | 35 ++++++++++++++++++++++++++++-------
 tests/hackage.scm     | 22 ++++++++++++++++++++++
 2 files changed, 50 insertions(+), 7 deletions(-)

diff --git a/guix/import/cabal.scm b/guix/import/cabal.scm
index 13c2f3f48c..1a87be0b00 100644
--- a/guix/import/cabal.scm
+++ b/guix/import/cabal.scm
@@ -270,6 +270,10 @@ following lines with indentation larger than MIN-INDENT."
                 (peek-next-line-indent port)))
         val)))
 
+(define* (read-braced-value port)
+  "Read up to a closing brace."
+  (string-trim-both (read-delimited "}" port 'trim)))
+
 (define (lex-white-space port bol)
   "Consume white spaces and comment lines on PORT.  If a new line is started return #t,
 otherwise return BOL (beginning-of-line)."
@@ -343,8 +347,11 @@ matching a string against the created regexp."
                 (make-regexp pat))))
     (cut regexp-exec rx <>)))
 
-(define is-property (make-rx-matcher "([a-z0-9-]+)[ \t]*:[ \t]*(\\w?.*)$"
-                                     regexp/icase))
+(define is-layout-property (make-rx-matcher "([a-z0-9-]+)[ \t]*:[ \t]*(\\w?[^{}]*)$"
+                                            regexp/icase))
+
+(define is-braced-property (make-rx-matcher "([a-z0-9-]+)[ \t]*:[ \t]*\\{[ \t]*$"
+                                            regexp/icase))
 
 (define is-flag (make-rx-matcher "^flag +([a-z0-9_-]+)"
                                  regexp/icase))
@@ -435,13 +442,19 @@ string with the read characters."
                  (begin (unread-char c) (list->string res)))))
           (else (list->string res)))))
 
-(define (lex-property k-v-rx-res loc port)
+(define (lex-layout-property k-v-rx-res loc port)
   (let ((key (string-downcase (match:substring k-v-rx-res 1)))
         (value (match:substring k-v-rx-res 2)))
     (make-lexical-token
      'PROPERTY loc
      (list key `(,(read-value port value (current-indentation)))))))
 
+(define (lex-braced-property k-rx-res loc port)
+  (let ((key (string-downcase (match:substring k-rx-res 1))))
+    (make-lexical-token
+     'PROPERTY loc
+     (list key `(,(read-braced-value port))))))
+
 (define (lex-rx-res rx-res token loc)
   (let ((name (string-downcase (match:substring rx-res 1))))
     (make-lexical-token token loc name)))
@@ -552,7 +565,6 @@ LOC is the current port location."
 the current port location."
   (let* ((s (read-delimited "\n{}" port 'peek)))
     (cond
-     ((is-property s) => (cut lex-property <> loc port))
      ((is-flag s) => (cut lex-flag <> loc))
      ((is-src-repo s) => (cut lex-src-repo <> loc))
      ((is-exec s) => (cut lex-exec <> loc))
@@ -561,13 +573,22 @@ the current port location."
      ((is-benchmark s) => (cut lex-benchmark <> loc))
      ((is-lib s) (lex-lib loc))
      ((is-else s) (lex-else loc))
-     (else
-      #f))))
+     (else (unread-string s port) #f))))
+
+(define (lex-property port loc)
+  (let* ((s (read-delimited "\n" port 'peek)))
+    (cond
+      ((is-braced-property s) => (cut lex-braced-property <> loc port))
+      ((is-layout-property s) => (cut lex-layout-property <> loc port))
+      (else #f))))
 
 (define (lex-token port)
   (let* ((loc (make-source-location (cabal-file-name) (port-line port)
                                     (port-column port) -1 -1)))
-    (or (lex-single-char port loc) (lex-word port loc) (lex-line port loc))))
+    (or (lex-single-char port loc)
+        (lex-word port loc)
+        (lex-line port loc)
+        (lex-property port loc))))
 
 ;; Lexer- and error-function generators
 
diff --git a/tests/hackage.scm b/tests/hackage.scm
index 41cea73fe7..733d540c20 100644
--- a/tests/hackage.scm
+++ b/tests/hackage.scm
@@ -143,6 +143,24 @@ executable cabal
     mtl        >= 2.0      && < 3
 ")
 
+;; Check braces instead of layout
+(define test-cabal-8
+  "name: foo
+version: 1.0.0
+homepage: http://test.org
+synopsis: synopsis
+description: {
+first line
+second line
+}
+license: BSD3
+executable cabal
+  build-depends:
+    HTTP       >= 4000.2.5 && < 4000.3,
+    mtl        >= 2.0      && < 3
+")
+
+
 ;; A fragment of a real Cabal file with minor modification to check precedence
 ;; of 'and' over 'or', missing final newline, spaces between keywords and
 ;; parentheses and between key and column.
@@ -262,6 +280,10 @@ library
   (eval-test-with-cabal test-cabal-7
                         #:cabal-environment '(("impl" . "ghc-7.8"))))
 
+(test-assert "hackage->guix-package test 8"
+  (eval-test-with-cabal test-cabal-8
+                        #:cabal-environment '(("impl" . "ghc-7.8"))))
+
 (test-assert "read-cabal test 1"
   (match (call-with-input-string test-read-cabal-1 read-cabal)
     ((("name" ("test-me"))
-- 
2.21.0


^ permalink raw reply related	[flat|nested] 5+ messages in thread

* [bug#35859] improves output in patch 0010
  2019-05-22 20:11 [bug#35859] [PATCH] hackage import: Setup.hs generation and revision support Robert Vollmert
                   ` (2 preceding siblings ...)
  2019-05-24 14:56 ` [bug#35859] fixes bug in patch 0003 Robert Vollmert
@ 2019-05-24 14:58 ` Robert Vollmert
  3 siblings, 0 replies; 5+ messages in thread
From: Robert Vollmert @ 2019-05-24 14:58 UTC (permalink / raw)
  To: 35859

[-- Attachment #1: Type: text/plain, Size: 167 bytes --]

Patch 0010 adds a logging statement to hackage import.
This is an updated version that provides better output considering
optional cabal reading from standard input.


[-- Attachment #2: 0010-guix-import-hackage-log-when-we-start-with-a-file.patch --]
[-- Type: application/octet-stream, Size: 1190 bytes --]

From c2aae7aa837ac8ac578e0cb46e72e26db08dfca4 Mon Sep 17 00:00:00 2001
From: Robert Vollmert <rob@vllmrt.net>
Date: Sat, 18 May 2019 03:37:27 +0200
Subject: [PATCH 10/13] guix: import: hackage: log when we start with a file

This helps figuring out what errors are in relation to, particularly
during recursive import.

* guix/import/hackage.scm: Log before fetching/parsing a cabal file.
---
 guix/import/hackage.scm | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/guix/import/hackage.scm b/guix/import/hackage.scm
index 0bd9034087..405294d186 100644
--- a/guix/import/hackage.scm
+++ b/guix/import/hackage.scm
@@ -319,6 +319,10 @@ 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."
+   (format (current-error-port)
+     (if port "Importing haskell package from ~a~%"
+              "Importing `~a` from hackage~%")
+     package-name)
    (match
      (if port (read-cabal-and-hash port)
               (hackage-fetch-and-hash package-name))
-- 
2.21.0


^ permalink raw reply related	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2019-05-24 15:08 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-05-22 20:11 [bug#35859] [PATCH] hackage import: Setup.hs generation and revision support Robert Vollmert
2019-05-23  8:50 ` [bug#35859] line ending fix Robert Vollmert
2019-05-23 13:27 ` [bug#35859] fixed patch set, including test fixes Robert Vollmert
2019-05-24 14:56 ` [bug#35859] fixes bug in patch 0003 Robert Vollmert
2019-05-24 14:58 ` [bug#35859] improves output in patch 0010 Robert Vollmert

Code repositories for project(s) associated with this external index

	https://git.savannah.gnu.org/cgit/guix.git

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.