背景
当我处理CLJS-3079时,我注意到{{script/aot_core}}中有一些Windows对bash/sh脚本的支持。这让我想到我应该在我的Windows系统上验证我的bash/sh脚本更改。
在CLJS-1797中为{{script/aot_core}}添加了Windows支持,以支持在Git Bash下运行。Git Bash是Git for Windows的一部分(链接: https://gitforwindows.org/ 文本:Git for Windows)。
在用Git Bash进行测试的过程中,我发现支持仅限于{{script/aot_core}},在其他脚本中缺乏支持。我在(链接: https://clojurians.slack.com/messages/C07UQ678E 文本:Slack #cls-dev)上询问是否有兴趣提高Windows上bash/sh脚本的支持,并得到了肯定答复,因此出现了这个JIRA问题。
实际行为
一些sh/bash脚本目前在Git Bash下的Windows上失败。
期望行为
在Git Bash下的Windows上完善对sh/bash脚本的支持。
相关
CLJS-3075 - 修改重叠 - 需要对支持graaljs在Windows上进行调整。
Windows环境
Windows 10 Home v1903 64位,内存6gb。
|工具|安装方式|
| :-- | :-- | :-- |
|Git for Windows v2.21.0|手动下载并从 https://gitforwindows.org/ 安装|
这为我们提供了Git Bash,我在其中进行了所有的bash/sh测试|
|java|{{scoop add bucket java}}|
{{scoop install corretto8}}|
|JavaScript引擎|通过(链接: https://github.com/GoogleChromeLabs/jsvu 文本:jsvu)安装|
|maven|{{scoop install maven}}|
|leiningen|{{scoop install leiningen}}|
|node|{{scoop install nodejs}}|
|google chrome web浏览器|手动下载并安装,并将其设置为默认浏览器|
|clj|根据 https://github.com/clojure/tools.deps.alpha/wiki/clj-on-Windows#install| 进行安装|
范围
在{{script/}}下有几个Windows PowerShell脚本。这项工作仅适用于bash/sh脚本。我不会触摸ps1脚本。
另请参阅:以下观察部分。
分析
classpath格式
大多数脚本失败是由于Windows、Linux/macOS之间java类路径格式差异造成的。
默认编码
一些测试失败是因为在Git Bash下Windows上运行的默认java文件.encoding不是utf-8。(注意,我在对Docker ubuntu镜像进行测试时也发现了这一点。)
工具
unzip在Windows上的行为略有不同
script/test-cli
这里也有更多的失败,但都是由于linux/macos与Windows之间的细微差别,以及上述因素造成的
1. 命令行参数中嵌入的双引号需要在Windows上转义|
1. 测试结果需要考虑Windows上的换行符差异|
1. 在JavaScript中需要对Windows路径进行转义(JavaScript会消费反斜杠)
1. graaljs {{js}} 在Windows上是通过 {{js.cmd}} 来使用的
方法
classpath格式
使用包含在Git Bash中的cygpath解决classpath格式问题。在专门的脚本中这样做,并调用需要它的其他脚本。
默认编码
需要在必要时显式指定utf-8编码。
工具
unzip工具需要使用 } 进行深匹配文件(我们之前使用 )。这适用于Unix/MacOS。
script/test-cli.
解决分析期间发现的的问题。除bash脚本和test-cli实用代码外,我们还需要触及graaljs和nashorn clj repl主代码。
实施说明
- Java classpath转换支持包含在新的 {{bin/classpath_conv}} 中。我原本想要将其放在 {{script}} 下,但 {{bin/cljsc}} 使用了它,因此我认为更好的做法是在 {{bin}} 下放置。
- 只有一个测试需要更改:{{src/test/cljs_cli/cljs_cli/test}} {{eval-test}} 使用 {{nil}} 作为命令行参数通过,这被转换为空字符串,这在Windows上不起作用。我假设测试实际上想要传递nil,因此已经将参数更改为 {{"nil"}}。其他测试保持不变。
- 我添加了 {{script/verify-scripts}} 来运行所有脚本。强制所有调用的脚本跟踪命令(set -x),并以便于与其他补丁/版本比较的方式进行输出。示例用法在附件 {{verify.sh}} 中。
- 我在 {{bin/cljsc}} 中显式地将 {{file.encoding}} 设置为 {{UTF-8}}。我认为这是合适的,但我确信有人会让我知道如果不是。
- {{script/closure-library-release/closure-library-release.sh}} - 更新github url为使用 https: 代替 git: 以减少开发者的设置负担。
- {{script/test-compile}} 需要进行微调才能与这个问题无关地工作。它指定了一个过时的closure jar位置。
- 所有脚本都已切换为从
#\!/bin/sh
到 #\!/usr/bin/env bash
,以便我和其他维护者可以放心地使用bash功能。这也允许我的自定义验证脚本强制echo-tracing命令,这有助于验证。
测试说明
已解决环境问题
- {{script/benchmark}} 在Windows上的Nashorn中失败
{{OutOfMemoryError: Java heap space}}
在
{{;; primitive array reduce 1000000 many ops}}
将我的Windows VM上的RAM从4Gb增加到6Gb解决了这个问题。
- {{script/benchmark}} 在Linux上的Nashorn中失败
{{OutOfMemoryError: GC overhead limit exceeded}}
在
{{;;; vector equality}}
将Docker->Preferences->Advanced->Memory 从2Gb增加到6Gb解决了这个问题。
跨操作系统测试
在macOS开发盒子上进行了测试。Windows测试通过ssh到Windows 10 VM进行。在基于ubuntu的容器({{Dockerfile}} 附件)中进行Linux测试。
脚本测试和生成的日志在 cljs-3098...zip 文件中附件。这些脚本针对我的设置,但包括用于Linux的Dockerfile。入口点是 {{verify.sh}}。在以下变体中进行了测试
- macos 未更改
- linux 未更改
- macos 修改过
- linux 修改过
- windows 修改过
我运行了未更改的变体,以比较与修改过的版本的结果。
特别注意验证在不同操作系统上classpath保持一致。
注意,由于我使用的Linux版本中 file.encoding 不是一个utf-8,因此linux-unpatched 中存在一些失败。这个补丁在 {{cljsc}} 中明确指定了utf-8,从而解决这个问题。
预存在的问题
在macOS上运行时发现的预存在问题(这个问题范围之外)
1. {{script/browser-repl}} 在浏览器中cljs-logo破损 - 注意
{{java -cp target/cljs.jar cljs.main -re browser}}
可以很好地显示 cljs-logo。
1. {{script/compile}} 编译失败。脚本已过时?保留原样。
1. {{script/test-simple}} 存在一个错误,将在CLJS-3075中修复。测试时跳过。
1. {{ast-ref/buildref.sh}} - 不确定这是什么,在macOS上未能成功运行。保留原样。