Patchwork gnu: Add clojure.

login
register
mail settings
Submitter Alex Vong
Date July 14, 2016, 1:22 p.m.
Message ID <87h9bs4amm.fsf@gmail.com>
Download mbox | patch
Permalink /patch/13794/
State New
Headers show

Comments

Alex Vong - July 14, 2016, 1:22 p.m.
Ricardo Wurmus <rekado@elephly.net> writes:

> Hi Alex,
>
>> This patch adds clojure 1.6 to 1.8.
>
> Wow.  Thanks!
>
Thanks for the review too!

> Usually, we just keep the latest version unless there are packages that
> dependend on an older version.  In the case of the IcedTea packages, for
> example, we need version 6 to be able to bootstrap the others.
>
> In my opinion we should just add Clojure version 1.8 for now.  In any
> case (if other people decide that we should have more than one version)
> please only add one package per patch.  It’s a little tedious to split
> stuff up, I know, but it makes handling repository history and partial
> reverts much easier. 
>
I see. So the general policy here is to be lazy and packaged by need :)
This time only version 1.8 is added. Does this apply to splitting
bundled libraries as well? I see clojure has some java libraries bundled
such as ASM. Currently, I suppose no other packages depend on it.

> I see that you added a very large patch to make this work.  In Guix we
> usually avoid patching upstream software unless it’s absolutely
> necessary.  Have you thought about submitting your patch upstream to
> enable compilation with GCJ?  I think we should not add extensive
> patches like that unless they are considered by the upstream developers.
>
> It’s also not so pretty that you have to call “gcj” and “g++” in a
> somewhat complicated build phase “build-native”.  If you can get
> upstream to accept your patches to build with GCJ maybe you can slip in
> a patch to add a new Makefile target as well?  This would greatly
> simplify the build phases.
>
I see clojure is written only in java and clojure. I will ask for
upstream advice on this one.

> Mmyeah… this is really not pretty.  Also: wrapping the whole package
> expression in this “get-version” let-binding is not nice.
>
> Have you thought of instead writing a procedure that produces a Clojure
> package given a particular version?  Similar to the “custom-gcc”
> procedure maybe?
>
Now only version 1.8 is added, the problem has gone temporarily. But it
is interesting to know how the gcc package solves this problem.

> Again, thanks a lot for the effort!  I really hope we can add Clojure to
> Guix soon.
>
> ~~ Ricardo

Thanks,
Alex
Ricardo Wurmus - July 24, 2016, 9:15 p.m.
Hi Alex,

> I see. So the general policy here is to be lazy and packaged by need :)
> This time only version 1.8 is added. Does this apply to splitting
> bundled libraries as well? I see clojure has some java libraries bundled
> such as ASM. Currently, I suppose no other packages depend on it.

Usually, we will split bundled libraries.  For bundled “jar” archives
this is necessary in any case as a “jar” file is a binary.

If the libraries are bundled in source form (not as “jar” archives) and
if they are closely tied to clojure (or if they were forked from
upstream libraries to better fit clojure), we could make an exception.

Packaging Java libraries for Guix still isn’t very easy as we lack a
bootstrapped set of core libraries, but you might be able to use the
“ant-build-system” to get closer to that goal.  I also have a couple of
packages for Java core libraries that haven’t yet been pushed.  If you
intend to work on this I can share my current work in progress.

>> I see that you added a very large patch to make this work.  In Guix we
>> usually avoid patching upstream software unless it’s absolutely
>> necessary.  Have you thought about submitting your patch upstream to
>> enable compilation with GCJ?  I think we should not add extensive
>> patches like that unless they are considered by the upstream developers.
>>
>> It’s also not so pretty that you have to call “gcj” and “g++” in a
>> somewhat complicated build phase “build-native”.  If you can get
>> upstream to accept your patches to build with GCJ maybe you can slip in
>> a patch to add a new Makefile target as well?  This would greatly
>> simplify the build phases.
>>
> I see clojure is written only in java and clojure. I will ask for
> upstream advice on this one.

Thank you.  Please let us know when a decision has been reached.

Here are some more comments about the patch you sent:

> +           (replace 'install
> +             (lambda* (#:key outputs #:allow-other-keys)
> +               (let ((java-dir (string-append (assoc-ref outputs "out")
> +                                              "/share/java/")))
> +                 ;; Do not install clojure.jar to avoid collisions.
> +                 (install-file (string-append "clojure-" ,version ".jar")
> +                               java-dir)
> +                 #t)))

You don’t need this.  The “ant-build-system” allows you to override the
name of the “jar” archive.  You can change the name to “(string-append
"clojure-" ,version ".jar")” there without needing to override the
install phase.

> +           (add-after 'build 'build-doc
> +             (lambda _
> +               (let* ((markdown-regex "(.*)\\.(md|markdown|txt)")
> +                      (gsub regexp-substitute/global)
> +                      (markdown->html (lambda (src-name)
> +                                        (zero? (system*
> +                                                "pandoc"
> +                                                "--output" (gsub #f
> +                                                                 markdown-regex
> +                                                                 src-name
> +                                                                 1 ".html")
> +                                                "--verbose"
> +                                                "--from" "markdown_github"
> +                                                "--to" "html"
> +                                                src-name)))))
> +                 (every markdown->html
> +                        (find-files "./" markdown-regex)))))

Why is this needed?  Is there no target for building the documentation?
If you added “pandoc” to the inputs only for building the documentation
please reconsider this decision.  The closure of the “pandoc” package is
*massive* as it depends on countless Haskell packages.  You would make
the “clojure” package dependent on both Java (which is large) and an
even larger set of packages consisting of GHC and numerous packages.

Couldn’t you just install the markdown files as they are?

> +           (add-after 'install 'install-doc
> +             (lambda* (#:key outputs #:allow-other-keys)
> +               (let ((doc-dir (string-append (assoc-ref outputs "out")
> +                                             "/share/doc/clojure-"
> +                                             ,version "/"))
> +                     (copy-file-to-dir (lambda (file dir)
> +                                         (copy-file file
> +                                                    (string-append dir
> +                                                                   file)))))
> +                 (for-each delete-file
> +                           (find-files "doc/clojure/"
> +                                       ".*\\.(md|markdown|txt)"))
> +                 (copy-recursively "doc/clojure/" doc-dir)
> +                 (for-each (cut copy-file-to-dir <> doc-dir)
> +                           (filter (cut string-match ".*\\.(html|txt)" <>)
> +                                   (scandir "./")))
> +                 #t))))))

Similar comments here.  Why delete the markdown documentation?  I’d much
prefer to have the original plain text files.

What do you think?

~~ Ricardo

Patch

From 69cb51c65014083a5838238bff688d7652e862a2 Mon Sep 17 00:00:00 2001
From: Alex Vong <alexvong1995@gmail.com>
Date: Tue, 5 Jul 2016 16:24:20 +0800
Subject: [PATCH] gnu: Add clojure.

* gnu/packages/java.scm (clojure): New variables.
---
 gnu/packages/java.scm | 202 ++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 202 insertions(+)

diff --git a/gnu/packages/java.scm b/gnu/packages/java.scm
index 753fb77..0a8956b 100644
--- a/gnu/packages/java.scm
+++ b/gnu/packages/java.scm
@@ -41,6 +41,7 @@ 
   #:use-module (gnu packages ghostscript) ;lcms
   #:use-module (gnu packages gnome)
   #:use-module (gnu packages gtk)
+  #:use-module (gnu packages haskell)
   #:use-module (gnu packages image)
   #:use-module (gnu packages linux) ;alsa
   #:use-module (gnu packages wget)
@@ -141,6 +142,207 @@  is implemented.")
               license:mpl2.0
               license:lgpl2.1+))))
 
+(define-public clojure
+  (let ((remove-archives '(begin
+                            (for-each delete-file
+                                      (find-files "./" ".*\\.(jar|zip)"))
+                            #t)))
+    (package
+      (name "clojure")
+      (version "1.8.0")
+      (source
+       (origin
+         (method url-fetch)
+         (uri
+          (string-append "http://repo1.maven.org/maven2/org/clojure/clojure/"
+                         version "/clojure-" version ".zip"))
+         (sha256
+          (base32 "1nip095fz5c492sw15skril60i1vd21ibg6szin4jcvyy3xr6cym"))
+         (modules '((guix build utils)))
+         (snippet remove-archives)))
+      (build-system ant-build-system)
+      (arguments
+       `(#:modules ((guix build ant-build-system)
+                    (guix build utils)
+                    (ice-9 ftw)
+                    (ice-9 regex)
+                    (srfi srfi-1)
+                    (srfi srfi-26))
+         #:test-target "test"
+         #:phases
+         (modify-phases %standard-phases
+           (add-after 'unpack 'unpack-submodule-sources
+             (lambda* (#:key inputs #:allow-other-keys)
+               (let ((unpack
+                      (lambda (src-name)
+                        (and (mkdir-p src-name)
+                             (with-directory-excursion src-name
+                               (zero? (system* "tar"
+                                               ;; Use xz since tarball is repacked.
+                                               "--xz"
+                                               "--extract"
+                                               "--verbose"
+                                               "--file" (assoc-ref inputs
+                                                                   src-name)
+                                               "--strip-components=1"))))))
+                     (copy (lambda (src-name)
+                             (copy-recursively
+                              (string-append src-name "/src/main/clojure/")
+                              "src/clj/"))))
+                 (every (lambda (src)
+                          (unpack src)
+                          (copy src))
+                        '("data-generators-src" "java-classpath-src"
+                          "test-check-src" "test-generative-src"
+                          "tools-namespace-src" "tools-reader-src")))))
+           (add-after 'build 'build-doc
+             (lambda _
+               (let* ((markdown-regex "(.*)\\.(md|markdown|txt)")
+                      (gsub regexp-substitute/global)
+                      (markdown->html (lambda (src-name)
+                                        (zero? (system*
+                                                "pandoc"
+                                                "--output" (gsub #f
+                                                                 markdown-regex
+                                                                 src-name
+                                                                 1 ".html")
+                                                "--verbose"
+                                                "--from" "markdown_github"
+                                                "--to" "html"
+                                                src-name)))))
+                 (every markdown->html
+                        (find-files "./" markdown-regex)))))
+           (replace 'install
+             (lambda* (#:key outputs #:allow-other-keys)
+               (let ((java-dir (string-append (assoc-ref outputs "out")
+                                              "/share/java/")))
+                 ;; Do not install clojure.jar to avoid collisions.
+                 (install-file (string-append "clojure-" ,version ".jar")
+                               java-dir)
+                 #t)))
+           (add-after 'install 'install-doc
+             (lambda* (#:key outputs #:allow-other-keys)
+               (let ((doc-dir (string-append (assoc-ref outputs "out")
+                                             "/share/doc/clojure-"
+                                             ,version "/"))
+                     (copy-file-to-dir (lambda (file dir)
+                                         (copy-file file
+                                                    (string-append dir
+                                                                   file)))))
+                 (for-each delete-file
+                           (find-files "doc/clojure/"
+                                       ".*\\.(md|markdown|txt)"))
+                 (copy-recursively "doc/clojure/" doc-dir)
+                 (for-each (cut copy-file-to-dir <> doc-dir)
+                           (filter (cut string-match ".*\\.(html|txt)" <>)
+                                   (scandir "./")))
+                 #t))))))
+      (native-inputs
+       `(("ghc-pandoc" ,ghc-pandoc)
+         ;; The native-inputs below are needed to run the tests.
+         ("data-generators-src"
+          ,(let ((version "0.1.2"))
+             (origin
+               (method url-fetch)
+               (uri (string-append "https://github.com/clojure"
+                                   "/data.generators/archive/data.generators-"
+                                   version ".tar.gz"))
+               (sha256
+                (base32
+                 "0kki093jp4ckwxzfnw8ylflrfqs8b1i1wi9iapmwcsy328dmgzp1"))
+               (modules '((guix build utils)
+                          (ice-9 ftw)))
+               (snippet remove-archives))))
+         ("java-classpath-src"
+          ,(let ((version "0.2.3"))
+             (origin
+               (method url-fetch)
+               (uri
+                (string-append "https://github.com/clojure"
+                               "/java.classpath/archive/java.classpath-"
+                               version ".tar.gz"))
+               (sha256
+                (base32
+                 "0sjymly9xh1lkvwn5ygygpsfwz4dabblnlq0c9bx76rkvq62fyng"))
+               (modules '((guix build utils)))
+               (snippet remove-archives))))
+         ("test-check-src"
+          ,(let ((version "0.9.0"))
+             (origin
+               (method url-fetch)
+               (uri
+                (string-append "https://github.com/clojure"
+                               "/test.check/archive/test.check-"
+                               version ".tar.gz"))
+               (sha256
+                (base32
+                 "0p0mnyhr442bzkz0s4k5ra3i6l5lc7kp6ajaqkkyh4c2k5yck1md"))
+               (modules '((guix build utils)))
+               (snippet remove-archives))))
+         ("test-generative-src"
+          ,(let ((version "0.5.2"))
+             (origin
+               (method url-fetch)
+               (uri (string-append "https://github.com/clojure"
+                                   "/test.generative/archive/test.generative-"
+                                   version ".tar.gz"))
+               (sha256
+                (base32
+                 "1pjafy1i7yblc7ixmcpfq1lfbyf3jaljvkgrajn70sws9xs7a9f8"))
+               (modules '((guix build utils)))
+               (snippet remove-archives))))
+         ("tools-namespace-src"
+          ,(let ((version "0.2.11"))
+             (origin
+               (method url-fetch)
+               (uri (string-append "https://github.com/clojure"
+                                   "/tools.namespace/archive/tools.namespace-"
+                                   version ".tar.gz"))
+               (sha256
+                (base32
+                 "10baak8v0hnwz2hr33bavshm7y49mmn9zsyyms1dwjz45p5ymhy0"))
+               (modules '((guix build utils)))
+               (snippet remove-archives))))
+         ("tools-reader-src"
+          ,(let ((version "0.10.0"))
+             (origin
+               (method url-fetch)
+               (uri
+                (string-append "https://github.com/clojure"
+                               "/tools.reader/archive/tools.reader-"
+                               version ".tar.gz"))
+               (sha256
+                (base32
+                 "09i3lzbhr608h76mhdjm3932gg9xi8sflscla3c5f0v1nkc28cnr"))
+               (modules '((guix build utils)))
+               (snippet remove-archives))))))
+      (home-page "https://clojure.org/")
+      (synopsis "Lisp dialect running on the JVM")
+      (description "Clojure is a dynamic, general-purpose programming language,
+combining the approachability and interactive development of a scripting
+language with an efficient and robust infrastructure for multithreaded
+programming. Clojure is a compiled language, yet remains completely dynamic
+– every feature supported by Clojure is supported at runtime. Clojure provides
+ easy access to the Java frameworks, with optional type hints and type
+inference, to ensure that calls to Java can avoid reflection.
+
+Clojure is a dialect of Lisp, and shares with Lisp the code-as-data philosophy
+and a powerful macro system. Clojure is predominantly a functional programming
+language, and features a rich set of immutable, persistent data structures.
+When mutable state is needed, Clojure offers a software transactional memory
+system and reactive Agent system that ensure clean, correct, multithreaded
+designs.")
+      ;; Clojure is licensed under EPL1.0
+      ;; ASM bytecode manipulation library is licensed under BSD-3
+      ;; Guava Murmur3 hash implementation is licensed under under APL2.0
+      ;; src/clj/repl.clj is licensed under under CPL1.0
+      ;;
+      ;; See readme.html or readme.txt for details.
+      (license (list license:epl1.0
+                     license:bsd-3
+                     license:asl2.0
+                     license:cpl1.0)))))
+
 (define-public ant
   (package
     (name "ant")
-- 
2.9.0