diff mbox series

[bug#54021] Add rhino javascript package

Message ID 87pmnnr2qq.fsf@gmail.com
State Accepted
Headers show
Series [bug#54021] Add rhino javascript package | expand

Checks

Context Check Description
cbaines/comparison success View comparision
cbaines/git branch success View Git branch
cbaines/applying patch fail View Laminar job
cbaines/issue success View issue

Commit Message

Frank Pursel Feb. 16, 2022, 1:58 a.m. UTC
Hi,

Rhino javascript has been around a long time.  It has also been built
upon by many others.  I needed to build this version for another package
and wanted to send it on as it might be useful.

Regards,
Frank


From c386b47786fc318cdfa0b1157a22590ebc279460 Mon Sep 17 00:00:00 2001
Message-Id: <c386b47786fc318cdfa0b1157a22590ebc279460.1644976508.git.frank.pursel@gmail.com>
From: Frank Pursel <frank.pursel@gmail.com>
Date: Tue, 15 Feb 2022 14:07:28 -0800
Subject: [PATCH] Adding rhino javascript guix package.

       * guix/gnu/package/javascript.scm (rhino): Added package.
---
 gnu/packages/javascript.scm | 65 +++++++++++++++++++++++++++++++++++++
 1 file changed, 65 insertions(+)

Comments

M Feb. 16, 2022, 5 p.m. UTC | #1
Frank Pursel schreef op di 15-02-2022 om 17:58 [-0800]:
> +                        (if tests?
> +                            (setenv "ANT_OPTS" "-Doffline=true")
> +                            (invoke "ant" "junit")) #t))

This does 'setenv' when tests?, and runs "ant junit" when (not tests?),
which doesn't seem useful.

Did you mean

  (when tests?
    (setenv ...)
    (invoke ...))

instead?  Also, you can drop the trailing #t, while they used to be
necessary, they don't have a meaning anymore and are gradually removed
from existing packages.

Greetings,
Maxime.
M Feb. 16, 2022, 5:02 p.m. UTC | #2
Frank Pursel schreef op di 15-02-2022 om 17:58 [-0800]:
> +      (inputs (list java-junit java-hamcrest-core
> +                    `(,icedtea "jdk")))

'java-junit' is for testing and icedtea:jdk is for building Java source
code to Jaa bytecode, so these seem 'native-inputs' to me.  The
distinction between 'inputs' and 'native-inputs' is cross-compiling.

I'm not familiar enough with rhino and java-hamcrest-core to tell if
'java-hamcrest-core' would be an input or a native-input.

Greetings,
Maxime.
M Feb. 16, 2022, 5:08 p.m. UTC | #3
Frank Pursel schreef op di 15-02-2022 om 17:58 [-0800]:
> +      (synopsis "Javascript implemented in java")

AFAICT, the standard spelling of JavaScript is JavaScript,
and the spelling of Java is Java, not java.

> +      (description
> +       "The Rhino engine, created primarily by Norris
> +Boyd (also at Netscape)

The author information is not important for people searching for
packages (using "guix search" or the like) satisfying their criteria.

>  is a JavaScript implementation written in
> +Java. Rhino is ECMA-262 Edition 5 compliant.")

The last sentence almost implies that rhino has been certified for
compliance or something.  Instead, I would write something like

‘Rhino implements ECMAScript, also known as JavaScript, as specified
in  the fifth edition of ECMA-262.’

Greetings,
Maxime.
Julien Lepiller Feb. 16, 2022, 5:08 p.m. UTC | #4
Hi!

Very cool work on rhino! It's a dependency I needed to work on kotlin's bootstrap :)

hamcrest-core is used by junit, so it should be a native-input too. Icedtea is useless here, because it's already an implicit input of the ant-build-system.

On February 16, 2022 6:02:38 PM GMT+01:00, Maxime Devos <maximedevos@telenet.be> wrote:
>Frank Pursel schreef op di 15-02-2022 om 17:58 [-0800]:
>> +      (inputs (list java-junit java-hamcrest-core
>> +                    `(,icedtea "jdk")))
>
>'java-junit' is for testing and icedtea:jdk is for building Java source
>code to Jaa bytecode, so these seem 'native-inputs' to me.  The
>distinction between 'inputs' and 'native-inputs' is cross-compiling.
>
>I'm not familiar enough with rhino and java-hamcrest-core to tell if
>'java-hamcrest-core' would be an input or a native-input.
>
>Greetings,
>Maxime.
M Feb. 16, 2022, 5:09 p.m. UTC | #5
Frank Pursel schreef op di 15-02-2022 om 17:58 [-0800]:
> +                                      (which "java")

'which' looks in the native-inputs, which is incorrect here when cross-
compiling.   I suggest using '(search-input-file inputs "/bin/java")'
instead.

Greetings,
Maxime.
M Feb. 16, 2022, 5:21 p.m. UTC | #6
Frank Pursel schreef op di 15-02-2022 om 17:58 [-0800]:
> +(define-public rhino
> +  (let* ((rel-ver "1.7.7.2") (rel-git-tag "Rhino1_7_7_2_Release")
> +         (git-commitv "935942527ff434b205e797df4185518e5369466e")
> +         (git-short-commit (substring git-commitv 0 6))
> +         (hash "09i4yr98hs6855fs7fhgmrpiwpr90lhxdv2bvfj97nn4rv1d7wl8"))

This is quite a bit more complicated than necessary ...

 * 'rel-git-tag' is unused.
 * Conventionally, a let-bound commit string has as name 'commit', not
   'git-commitv'.  (guix upstream) expects 'commit', not 'git-commitv',
   and will fail at auto-updating if a different name is used.
 * (see later)

> +    (package
> +      (name "rhino")
> +      (version git-short-commit)

'git-short-commit' is a (shortened) commit string, not a version
number.  This needs to be (version "1.7.7.2") instead.

> +      (source (origin
> +                (method git-fetch)
> +                (uri (git-reference
> +                      (url "https://github.com/mozilla/rhino.git")
> +                      (commit git-short-commit)))

There is no need to shorten the commit string, you can use the full
"git-commitv" here.

> +                (file-name (git-file-name name git-short-commit))

We have a version number, so you can do (git-file-name name version)
here.

> +                (sha256
> +                 (base32
> +                  hash))))

The hash is only used in one place, so you can write it here directly.
This has as benefit that (guix packages) can do some checks on the hash
at compile time.

[...]

> +      (arguments
> +       `(#:phases (modify-phases %standard-phases
> +                    (add-after 'unpack 'clean-jars
> +                      (lambda _
> +                        (for-each (lambda (jarf)
> +                                    (delete-file jarf)
> +                                    (format #t "Deleted: ~s
> +" jarf))
> +                                  (find-files "." ".*\\.jar$")) #t))

Cleaning the source code of binaries, making sure that the source code
actually consists of source code, seems more something for origin
snippets.  It's not really explicitly mentioned anywhere I think,
but the following from ‘(guix)Snipepts versus Phases’ seems close:

The boundary between using an origin snippet versus a build phase to
modify the sources of a package can be elusive.  Origin snippets are
typically used to remove unwanted files such as bundled libraries,
nonfree sources, or to apply simple substitutions.  [...]

> +                    (replace 'install
> +                      (lambda* (#:key inputs outputs #:allow-other-keys)
> +                        (let* ((out (assoc-ref outputs "out"))
> +                               (pkg+ver (string-append ,name ,rel-ver))

You can refer to the 'version' field of the package here:

  (pkg+ver (string-append ,name ,version))

> +                               (bin (string-append out "/bin"))
> +                               (rhino (string-append bin "/rhino")))
> +                          (mkdir-p bin)
> +                          (install-file (string-append "build/" pkg+ver
> +                                                       "/js.jar")
> +                                        (string-append out "/share/java"))
> +                          (with-output-to-file rhino
> +                            (lambda _
> +                              (format #t "#!~a
> +~a -jar ~a $@
> +"
> +                                      (search-input-file inputs "/bin/bash")

'bash-minimal' is missing from 'inputs'.  Not including it only works
when compiling natively.

> +                                      (which "java")
> +                                      (string-append out "/share/java/js.jar"))))


'format' has a port argument, so you could do

(call-with-output-file rhino
  (lambda (port)
    (format port "#!~a ~a -jar -a $@"
            (search-input-file [...]) [...])))

Also, what's this "$@"?

Greetings,
Maxime.
Frank Pursel Feb. 16, 2022, 6:36 p.m. UTC | #7
Thanks for the careful review.  The $@ was intended to allow the
introduction of additional command line arguments but since it starts a
repl and might be a source of nefariousness I've just removed it.  I did
not understand the bash-minimal comment.  Are you saying that
(search-input-file inputs "/bin/bash") will not work in the way I
intended?  I've changed all the inputs to native-inputs now.

I'll get back to you after I do some more testing.

Thank you for your helpful/thoughtful comments.

Regards,
Frank

On Wed, Feb 16, 2022 at 5:21 PM Maxime Devos <maximedevos@telenet.be> wrote:

> Frank Pursel schreef op di 15-02-2022 om 17:58 [-0800]:
> > +(define-public rhino
> > +  (let* ((rel-ver "1.7.7.2") (rel-git-tag "Rhino1_7_7_2_Release")
> > +         (git-commitv "935942527ff434b205e797df4185518e5369466e")
> > +         (git-short-commit (substring git-commitv 0 6))
> > +         (hash "09i4yr98hs6855fs7fhgmrpiwpr90lhxdv2bvfj97nn4rv1d7wl8"))
>
> This is quite a bit more complicated than necessary ...
>
>  * 'rel-git-tag' is unused.
>  * Conventionally, a let-bound commit string has as name 'commit', not
>    'git-commitv'.  (guix upstream) expects 'commit', not 'git-commitv',
>    and will fail at auto-updating if a different name is used.
>  * (see later)
>
> > +    (package
> > +      (name "rhino")
> > +      (version git-short-commit)
>
> 'git-short-commit' is a (shortened) commit string, not a version
> number.  This needs to be (version "1.7.7.2") instead.
>
> > +      (source (origin
> > +                (method git-fetch)
> > +                (uri (git-reference
> > +                      (url "https://github.com/mozilla/rhino.git")
> > +                      (commit git-short-commit)))
>
> There is no need to shorten the commit string, you can use the full
> "git-commitv" here.
>
> > +                (file-name (git-file-name name git-short-commit))
>
> We have a version number, so you can do (git-file-name name version)
> here.
>
> > +                (sha256
> > +                 (base32
> > +                  hash))))
>
> The hash is only used in one place, so you can write it here directly.
> This has as benefit that (guix packages) can do some checks on the hash
> at compile time.
>
> [...]
>
> > +      (arguments
> > +       `(#:phases (modify-phases %standard-phases
> > +                    (add-after 'unpack 'clean-jars
> > +                      (lambda _
> > +                        (for-each (lambda (jarf)
> > +                                    (delete-file jarf)
> > +                                    (format #t "Deleted: ~s
> > +" jarf))
> > +                                  (find-files "." ".*\\.jar$")) #t))
>
> Cleaning the source code of binaries, making sure that the source code
> actually consists of source code, seems more something for origin
> snippets.  It's not really explicitly mentioned anywhere I think,
> but the following from ‘(guix)Snipepts versus Phases’ seems close:
>
> The boundary between using an origin snippet versus a build phase to
> modify the sources of a package can be elusive.  Origin snippets are
> typically used to remove unwanted files such as bundled libraries,
> nonfree sources, or to apply simple substitutions.  [...]
>
> > +                    (replace 'install
> > +                      (lambda* (#:key inputs outputs #:allow-other-keys)
> > +                        (let* ((out (assoc-ref outputs "out"))
> > +                               (pkg+ver (string-append ,name ,rel-ver))
>
> You can refer to the 'version' field of the package here:
>
>   (pkg+ver (string-append ,name ,version))
>
> > +                               (bin (string-append out "/bin"))
> > +                               (rhino (string-append bin "/rhino")))
> > +                          (mkdir-p bin)
> > +                          (install-file (string-append "build/" pkg+ver
> > +                                                       "/js.jar")
> > +                                        (string-append out
> "/share/java"))
> > +                          (with-output-to-file rhino
> > +                            (lambda _
> > +                              (format #t "#!~a
> > +~a -jar ~a $@
> > +"
> > +                                      (search-input-file inputs
> "/bin/bash")
>
> 'bash-minimal' is missing from 'inputs'.  Not including it only works
> when compiling natively.
>
> > +                                      (which "java")
> > +                                      (string-append out
> "/share/java/js.jar"))))
>
>
> 'format' has a port argument, so you could do
>
> (call-with-output-file rhino
>   (lambda (port)
>     (format port "#!~a ~a -jar -a $@"
>             (search-input-file [...]) [...])))
>
> Also, what's this "$@"?
>
> Greetings,
> Maxime.
>
M Feb. 16, 2022, 6:43 p.m. UTC | #8
Frank Pursel schreef op wo 16-02-2022 om 18:36 [+0000]:
> I did not understand the bash-minimal comment.  Are you saying that
> (search-input-file inputs "/bin/bash") will not work in the way I
> intended

'bash-minimal' (*) is an implicit native-input of ant-build-system.
When compiling natively, inputs and native-inputs are merged together
into 'inputs'.  As such, bash-minimal (and hence "/bin/bash") is
contained in 'inputs' when compiling natively.  So if you compiled
natively (most likely), then using (search-input-file inputs
"/bin/bash") this succeeds.

However, if cross-compiling with "guix build --target=aarch64-linux-
gnu" or the like (**), then the native-inputs and inputs are kept
separate, so 'inputs' would not contain bash, (search-input-file ...)
would fail by raising a &search-error exception and the build would
therefore fail.

This can be resolved by adding the 'bash-minimal' package to 'inputs'.

(*) Actually a variant of 'bash-minimal' but that does not matter here.
(**) This won't work _yet_ because 'ant-build-system' does not support
cross-compilation yet.

Greetings,
Maxime.
Frank Pursel Feb. 28, 2022, 9:45 p.m. UTC | #9
Julien,

I missed the JavaScript in the synopsis, my fault; I did get the one in the
description.

Why the older version?  A couple of reasons.  First, is that I'm trying
to address the problems that have been pointed out with my earlier
patches for a ditaa package.  'ditaa' has a sequence of dependencies
that lead to the version of rhino I've packaged.  I looked at the latest
version too (because that would certainly be a good thing) but newer
releases of rhino have transitioned to the gradle build system.  I have
experience with ant that I can use but none, yet, with gradle.  Plus,
and this may be naive, I thought it might be a good experiment (perhaps
even better for guix) to see if a guix transformation based on this ant
build could build one of the later rhino versions that otherwise would
require gradle.  I may pursue such experiments later after I achieve my
first goal, which is to package ditaa.  I also think there is a risk
that the latest version of rhino will not work with ditaa as the one we
are packaging does.

If I can suceed with rhino and my more recent submission of xalan then I
will have a clean build of batik that will allow ditaa to be built
properly using only guix quality, built-from-source, libraries.  That is
my current small guix ambition.    

Regards,
Frank
Julien Lepiller March 1, 2022, 9:26 p.m. UTC | #10
Thanks for the answer (I didn't spot your message immediately because
you renamed the subject). I suppose this is good for now, especially
since I need a version of rhino for kotlin, which I need for gradle,
which we would need for future versions of rhino :)

Pushed to master as 22525731fdbfeebfc51d17dc6674a92d75383213, thanks!

Le Mon, 28 Feb 2022 13:45:58 -0800,
Frank Pursel <frank.pursel@gmail.com> a écrit :

> Julien,
> 
> I missed the JavaScript in the synopsis, my fault; I did get the one
> in the description.
> 
> Why the older version?  A couple of reasons.  First, is that I'm
> trying to address the problems that have been pointed out with my
> earlier patches for a ditaa package.  'ditaa' has a sequence of
> dependencies that lead to the version of rhino I've packaged.  I
> looked at the latest version too (because that would certainly be a
> good thing) but newer releases of rhino have transitioned to the
> gradle build system.  I have experience with ant that I can use but
> none, yet, with gradle.  Plus, and this may be naive, I thought it
> might be a good experiment (perhaps even better for guix) to see if a
> guix transformation based on this ant build could build one of the
> later rhino versions that otherwise would require gradle.  I may
> pursue such experiments later after I achieve my first goal, which is
> to package ditaa.  I also think there is a risk that the latest
> version of rhino will not work with ditaa as the one we are packaging
> does.
> 
> If I can suceed with rhino and my more recent submission of xalan
> then I will have a clean build of batik that will allow ditaa to be
> built properly using only guix quality, built-from-source, libraries.
>  That is my current small guix ambition.    
> 
> Regards,
> Frank
> 
> 
> 
> 
>
diff mbox series

Patch

diff --git a/gnu/packages/javascript.scm b/gnu/packages/javascript.scm
index c453ac432a..e9db0d2ce6 100644
--- a/gnu/packages/javascript.scm
+++ b/gnu/packages/javascript.scm
@@ -6,6 +6,7 @@ 
 ;;; Copyright © 2018 Nicolas Goaziou <mail@nicolasgoaziou.fr>
 ;;; Copyright © 2021 Pierre Neidhardt <mail@ambrevar.xyz>
 ;;; Copyright © 2021 Maxim Cournoyer <maxim.cournoyer@gmail.com>
+;;; Copyright © 2022 Frank Pursel <frank.pursel@gmail.com>
 ;;;
 ;;; This file is part of GNU Guix.
 ;;;
@@ -31,6 +32,7 @@  (define-module (gnu packages javascript)
   #:use-module (gnu packages readline)
   #:use-module (gnu packages uglifyjs)
   #:use-module (gnu packages web)
+  #:use-module (gnu packages java)
   #:use-module (guix packages)
   #:use-module (guix download)
   #:use-module (guix git-download)
@@ -38,6 +40,7 @@  (define-module (gnu packages javascript)
   #:use-module (guix build-system cmake)
   #:use-module (guix build-system trivial)
   #:use-module (guix build-system minify)
+  #:use-module (guix build-system ant)
   #:use-module (guix utils))
 
 (define-public cjson
@@ -788,3 +791,65 @@  (define-public duktape
 your build, and use the Duktape API to call ECMAScript functions from C code
 and vice versa.")
     (license license:expat)))
+
+(define-public rhino
+  (let* ((rel-ver "1.7.7.2") (rel-git-tag "Rhino1_7_7_2_Release")
+         (git-commitv "935942527ff434b205e797df4185518e5369466e")
+         (git-short-commit (substring git-commitv 0 6))
+         (hash "09i4yr98hs6855fs7fhgmrpiwpr90lhxdv2bvfj97nn4rv1d7wl8"))
+    (package
+      (name "rhino")
+      (version git-short-commit)
+      (source (origin
+                (method git-fetch)
+                (uri (git-reference
+                      (url "https://github.com/mozilla/rhino.git")
+                      (commit git-short-commit)))
+                (file-name (git-file-name name git-short-commit))
+                (sha256
+                 (base32
+                  hash))))
+      (build-system ant-build-system)
+      (inputs (list java-junit java-hamcrest-core
+                    `(,icedtea "jdk")))
+      (arguments
+       `(#:phases (modify-phases %standard-phases
+                    (add-after 'unpack 'clean-jars
+                      (lambda _
+                        (for-each (lambda (jarf)
+                                    (delete-file jarf)
+                                    (format #t "Deleted: ~s
+" jarf))
+                                  (find-files "." ".*\\.jar$")) #t))
+                    (replace 'check
+                      (lambda* (#:key tests? #:allow-other-keys)
+                        (if tests?
+                            (setenv "ANT_OPTS" "-Doffline=true")
+                            (invoke "ant" "junit")) #t))
+                    (replace 'install
+                      (lambda* (#:key inputs outputs #:allow-other-keys)
+                        (let* ((out (assoc-ref outputs "out"))
+                               (pkg+ver (string-append ,name ,rel-ver))
+                               (bin (string-append out "/bin"))
+                               (rhino (string-append bin "/rhino")))
+                          (mkdir-p bin)
+                          (install-file (string-append "build/" pkg+ver
+                                                       "/js.jar")
+                                        (string-append out "/share/java"))
+                          (with-output-to-file rhino
+                            (lambda _
+                              (format #t "#!~a
+~a -jar ~a $@
+"
+                                      (search-input-file inputs "/bin/bash")
+                                      (which "java")
+                                      (string-append out "/share/java/js.jar"))))
+                          (chmod rhino #o755) #t))))))
+      (home-page "https://mozilla.github.io/rhino")
+      (synopsis "Javascript implemented in java")
+      (description
+       "The Rhino engine, created primarily by Norris
+Boyd (also at Netscape) is a JavaScript implementation written in
+Java. Rhino is ECMA-262 Edition 5 compliant.")
+      (license license:mpl2.0))))
+