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

显示变量、类或偏好设置或导入。

show variables

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

show classes

show imports

show preferences

show all

inspect

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

purge

从 shell 中清除对象。

purge variables

purge classes

purge imports

purge preferences

purge all

edit

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

目前仅适用于已设置 EDITOR 环境变量或已配置 editor 偏好设置的 UNIX 系统。

load

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

save

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

record

将当前会话记录到文件。

record start

record stop

record status

history

显示、管理和回忆编辑行历史记录。

history show

history recall

history flush

history clear

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.12/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.AntBuildergroovy.xml.XmlSlurper 的 Groovydoc

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

要获取 groovy.lang.Closuregroovy.sql.GroovyResultSet 的 Groovydoc 和 GDK 增强文档

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

原始数组和数组数组的 GDK 增强功能也有文档

groovy:000> :doc int[]
https://docs.groovy-lang.cn/4.0.12/html/groovy-jdk/primitives-and-primitive-arrays/int%5B%5D.html
groovy:000> :doc double[][]
https://docs.groovy-lang.cn/4.0.12/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>

请注意,命令类必须在类路径中找到:您不能从 shell 中定义新的命令。

1.8. 故障排除

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

1.8.1. 平台问题

加载 JLine DLL 问题

在 Windows 上,JLine2(用于花哨的 shell 输入/历史记录/完成功能)使用一个微型 DLL 文件来欺骗邪恶的 Windows 伪 shell(CMD.EXECOMMAND.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 插件 是一个 Gradle 插件,它提供 gradle 任务来启动绑定到 Gradle 项目的 Groovy Shell。