groovysh - Groovy 类 repl shell

1. Groovy:Groovy Shell

Groovy Shell,又称 `groovysh`,是一个命令行应用程序,可以轻松评估 Groovy 表达式、定义类和运行简单的实验。

1.1. 功能

  • 无需 `go` 命令即可执行缓冲区。

  • 得益于 JLine2,提供丰富的跨平台编辑行编辑、历史记录和自动补全功能。

  • ANSI 颜色(提示、异常跟踪等)。

  • 简单而强大的命令系统,提供在线帮助、用户别名支持等。

  • 用户配置文件支持

1.2. 命令行选项和参数

Shell 支持多种选项来控制详细程度、ANSI 颜色和其他功能。

./bin/groovysh --help

Usage: groovysh [options] [...]
The Groovy Shell, aka groovysh, is a command-line application which allows easy
access to evaluate Groovy expressions, define classes and run simple
experiments.
  -C, --color[=<FLAG>]    Enable or disable use of ANSI colors
      -cp, -classpath, --classpath
                          Specify where to find the class files - must be first
                            argument
  -d, --debug             Enable debug output
  -D, --define=<name=value>
                          Define a system property
  -e, --evaluate=<CODE>   Evaluate the code first when starting interactive session
  -h, --help              Display this help message
  -pa, --parameters       Generate metadata for reflection on method parameter names
                            (jdk8+ only)
  -pr, --enable-preview   Enable preview Java features (jdk12+ only)
  -q, --quiet             Suppress superfluous output
  -T, --terminal=<TYPE>   Specify the terminal TYPE to use
  -v, --verbose           Enable verbose output
  -V, --version           Display the version

1.3. 表达式求值

1.3.1. 简单表达式

println "Hello"

1.3.2. 求值结果

当找到完整表达式时,它将被编译和求值。求值结果存储在 _ 变量中。

1.3.3. 多行表达式

多行/复杂表达式(如闭包或类定义)可以跨多行定义。当 Shell 检测到它有完整表达式时,它将编译并求值。

定义类
class Foo {
    def bar() {
        println "baz"
    }
}
使用类
foo = new Foo()
foo.bar()

1.3.4. 变量

Shell 变量全部是无类型的(即没有 `def` 或其他类型信息)。

这将设置一个 Shell 变量

foo = "bar"

但是,这将评估一个局部变量,并且不会保存到 Shell 的环境中

def foo = "bar"

通过激活 解释器模式 可以更改此行为。

1.3.5. 函数

函数可以在 Shell 中定义,并保存以供以后使用。

定义函数很容易

groovy:000> def hello(name) {
groovy:001> println("Hello $name")
groovy:002> }

然后使用它就像人们期望的那样

hello("Jason")

在内部,Shell 创建一个闭包来封装函数,然后将闭包绑定到一个变量。因此,变量和函数共享相同的命名空间。

1.4. 命令

Shell 有许多不同的命令,它们提供对 Shell 环境的丰富访问。

命令都有一个名称和一个快捷方式(例如 `\h`)。命令还可能有一些预定义的系统别名。用户也可以创建自己的别名。

1.4.1. 已识别的命令

`help`

显示命令列表(和别名)或特定命令的帮助文本。

命令列表

groovy:000> :help

For information about Groovy, visit:
    https://groovy-lang.cn

Available commands:
  :help      (:h ) Display this help message
  ?          (:? ) Alias to: :help
  :exit      (:x ) Exit the shell
  :quit      (:q ) Alias to: :exit
  import     (:i ) Import a class into the namespace
  :display   (:d ) Display the current buffer
  :clear     (:c ) Clear the buffer and reset the prompt counter
  :show      (:S ) Show variables, classes or imports
  :inspect   (:n ) Inspect a variable or the last result with the GUI object browser
  :purge     (:p ) Purge variables, classes, imports or preferences
  :edit      (:e ) Edit the current buffer
  :load      (:l ) Load a file or URL into the buffer
  .          (:. ) Alias to: :load
  :save      (:s ) Save the current buffer to a file
  :record    (:r ) Record the current session to a file
  :history   (:H ) Display, manage and recall edit-line history
  :alias     (:a ) Create an alias
  :set       (:= ) Set (or list) preferences
  :grab      (:g ) Add a dependency to the shell environment
  :register  (:rc) Register a new command with the shell
  :doc       (:D ) Open a browser window displaying the doc for the argument

For help on a specific command type:
    :help <command>

命令帮助

在交互式 shell 中,您可以请求任何命令的帮助,以获取有关其语法或功能的更多详细信息。以下是您请求 `help` 命令帮助时发生的情况示例

groovy:000> :help :help

usage: :help [<command>]

Display the list of commands or the help text for <command>.
`exit`

退出 shell。

这是退出 shell 的唯一方法。好吧,您仍然可以按 `CTRL-C`,但 shell 会抱怨 JVM 异常关闭。

`import`

添加自定义导入,该导入将包含在所有 shell 评估中。

此命令可以随时给出以添加新的导入。

`grab`

从互联网源或缓存获取依赖项(Maven、Ivy 等),并将其添加到 Groovy Shell 环境中。

groovy:000> :grab 'com.google.guava:guava:19.0'
groovy:000> import com.google.common.collect.BiMap
===> com.google.common.collect.BiMap

此命令可以随时给出以添加新的依赖项。

`display`

显示当前缓冲区的内容。

这只显示不完整表达式的缓冲区。一旦表达式完成,缓冲区就会重置。提示也会更新以显示当前缓冲区的大小。

示例

groovy:000> class Foo {
groovy:001> def bar
groovy:002> def baz() {
groovy:003> :display
 001> class Foo {
 002> def bar
 003> def baz() {
`clear`

清除当前缓冲区,将提示计数器重置为 000。可用于从编译错误中恢复。

`show`

显示变量、类或首选项或导入。

显示变量

groovy:000> :show variables
Variables:
  _ = true

显示类

显示导入

显示首选项

显示所有

`inspect`

打开 GUI 对象浏览器以检查变量或上次评估的结果。

`purge`

从 shell 中清除对象。

清除变量

清除类

清除导入

清除首选项

清除所有

`edit`

在外部编辑器中编辑当前缓冲区。

目前仅适用于已设置 `EDITOR` 环境变量或已配置 `editor` 首选项的 UNIX 系统。

`load`

将一个或多个文件(或 URL)加载到缓冲区中。

`save`

将缓冲区内容保存到文件。

`record`

将当前会话记录到文件。

开始记录

停止记录

记录状态

`history`

显示、管理和调用编辑行历史记录。

显示历史记录

调用历史记录

刷新历史记录

清除历史记录

`alias`

创建别名。

`doc`

打开浏览器,显示所提供类的文档。

例如,我们可以获取 `java.util.List` 的 Javadoc 和 GDK 增强文档(显示在 JDK17 上运行)

groovy:000> :doc java.util.List
https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/util/List.html
https://docs.groovy-lang.cn/4.0.27/html/groovy-jdk/java/util/List.html

这将打印找到的文档 URL 并打开两个窗口(或选项卡,取决于您的浏览器)

  • 一个用于 JDK 文档

  • 一个用于 GDK 文档

默认情况下,对于 Java 类,假定为 `java.base` 模块。您可以为其他情况指定可选模块(显示在 JDK17 上运行)

groovy:000> :doc java.scripting javax.script.ScriptContext
https://docs.oracle.com/en/java/javase/17/docs/api/java.scripting/javax/script/ScriptContext.html

为了向后兼容,如果在搜索 Java 类时未指定模块,并且在 `java.base` 模块中未找到该类,则会额外尝试在 JDK8(预模块)Javadoc 中查找该类的文档

groovy:000> :doc javax.script.ScriptContext
https://docs.oracle.com/javase/8/docs/api/javax/script/ScriptContext.html

获取 `groovy.ant.AntBuilder` 和 `groovy.xml.XmlSlurper` 的 Groovydoc

groovy:000> :doc groovy.ant.AntBuilder
https://docs.groovy-lang.cn/4.0.27/html/gapi/groovy/ant/AntBuilder.html
groovy:000> :doc groovy.xml.XmlSlurper
https://docs.groovy-lang.cn/4.0.27/html/gapi/groovy/xml/XmlSlurper.html

获取 `groovy.lang.Closure` 和 `groovy.sql.GroovyResultSet` 的 Groovydoc 和 GDK 增强文档

groovy:000> :doc groovy.lang.Closure
https://docs.groovy-lang.cn/4.0.27/html/gapi/groovy/lang/Closure.html
https://docs.groovy-lang.cn/4.0.27/html/groovy-jdk/groovy/lang/Closure.html
groovy:000> :doc groovy.sql.GroovyResultSet
https://docs.groovy-lang.cn/4.0.27/html/gapi/groovy/sql/GroovyResultSet.html
https://docs.groovy-lang.cn/4.0.27/html/groovy-jdk/groovy/sql/GroovyResultSet.html

还提供了原始数组和数组的数组的 GDK 增强文档

groovy:000> :doc int[]
https://docs.groovy-lang.cn/4.0.27/html/groovy-jdk/primitives-and-primitive-arrays/int%5B%5D.html
groovy:000> :doc double[][]
https://docs.groovy-lang.cn/4.0.27/html/groovy-jdk/primitives-and-primitive-arrays/double%5B%5D%5B%5D.html
在不希望打开浏览器的情况下(例如在 CI 服务器上),可以通过将 `groovysh.disableDocCommand` 系统属性设置为 `true` 来禁用此命令。
`set`

设置或列出首选项。

1.5. 首选项

`groovysh` 行为的某些方面可以通过设置首选项来定制。首选项使用 `set` 命令或 `:=` 快捷方式设置。

1.5.1. 已识别的首选项

`interpreterMode`

允许使用类型化变量(即 `def` 或其他类型信息)

groovy:000> def x = 3
===> 3
groovy:000> x
===> 3

它对于将教程等代码复制粘贴到正在运行的会话中特别有用。

`verbosity`

设置 shell 的详细级别。预期为以下之一:

  • DEBUG

  • VERBOSE

  • INFO

  • QUIET

默认值为 `INFO`。

如果此首选项设置为无效值,则将使用先前的设置,如果没有,则删除该首选项并使用默认值。

`colors`

设置 shell 颜色的使用。

默认值为 `true`。

`show-last-result`

执行后显示上次结果。

默认值为 `true`。

`sanitize-stack-trace`

清理(修剪/过滤)堆栈跟踪。

默认值为 `true`。

`editor`

配置 `edit` 命令使用的编辑器。

默认值为系统环境变量 `EDITOR` 的值。

要在 macOS 上使用默认文本编辑器 TextEdit,请配置:set editor /Applications/TextEdit.app/Contents/MacOS/TextEdit

1.5.2. 设置首选项

groovy:000> :set verbosity DEBUG

1.5.3. 列出首选项

要列出当前设置的首选项(及其值)

groovy:000> :show preferences

限制:目前无法列出所有已知/可用要设置的首选项。

1.5.4. 清除首选项(即重置为默认值)

groovy:000> :purge preferences

1.6. 用户配置文件脚本和状态

1.6.1. 配置文件脚本

`$HOME/.groovy/groovysh.profile`

如果此脚本存在,则在 shell 启动时加载。

`$HOME/.groovy/groovysh.rc`

如果此脚本存在,则在 shell 进入交互模式时加载。

1.6.2. 状态

`$HOME/.groovy/groovysh.history`

编辑行历史记录存储在此文件中。

1.7. 自定义命令

`register` 命令允许您在 shell 中注册自定义命令。例如,编写以下内容将注册 `Stats` 命令

groovy:000> :register Stats

其中 `Stats` 类是扩展 `org.apache.groovy.groovysh.CommandSupport` 类的类。例如

import org.apache.groovy.groovysh.CommandSupport
import org.apache.groovy.groovysh.Groovysh

class Stats extends CommandSupport {
    protected Stats(final Groovysh shell) {
        super(shell, 'stats', 'T')
    }

    public Object execute(List args) {
        println "Free memory: ${Runtime.runtime.freeMemory()}"
    }

}

然后可以使用以下命令调用

groovy:000> :stats
stats
Free memory: 139474880
groovy:000>

请注意,命令类必须在 classpath 上找到:您不能在 shell 中定义新命令。

1.8. 故障排除

报告您遇到的任何问题。请务必用 `Groovysh` 组件标记 JIRA 问题。

1.8.1. 平台问题

加载 JLine DLL 时出现问题

在 Windows 上,JLine2(用于花哨的 shell 输入/历史记录/自动补全功能)使用一个微小的 DLL 文件来欺骗邪恶的 Windows 伪 shell(`CMD.EXE` 或 `COMMAND.COM`),使其向 Java 提供无缓冲输入。在某些罕见情况下,这可能无法加载或初始化。

一种解决方案是禁用花哨功能并使用不支持的终端实例。您可以使用 `--terminal` 标志在命令行上执行此操作,并将其设置为以下之一:

  • none

  • false

  • off

  • jline.UnsupportedTerminal

groovysh --terminal=none
Windows 上 Cygwin 的问题

有些人在使用 cygwin 运行 groovysh 时遇到问题。如果您遇到问题,以下内容可能会有所帮助

stty -icanon min 1 -echo
groovysh --terminal=unix
stty icanon echo

2. GMavenPlus Maven 插件

GMavenPlus 是一个 Maven 插件,其目标支持启动绑定到 Maven 项目的 Groovy Shell 或 Groovy Console。

3. Gradle Groovysh 插件

Gradle Groovysh Plugin 是一个 Gradle 插件,它提供 Gradle 任务以启动绑定到 Gradle 项目的 Groovy Shell。