groovysh - 類似 Groovy repl 的指令殼層

1. Groovy : Groovy Shell

Groovy Shell,又稱 groovysh,是一個命令列應用程式,可以輕鬆地評估 Groovy 表達式、定義類別和執行簡單的實驗。

1.1. 功能

  • 不需要 go 指令來執行緩衝區。

  • 豐富的跨平台編輯線編輯、歷史記錄和完成,感謝 JLine2

  • ANSI 顏色(提示、例外追蹤等)。

  • 簡單但強大的指令系統,具備線上說明、使用者別名支援等。

  • 使用者設定檔支援

1.2. 指令列選項和引數

此殼層支援多個選項,用於控制詳細程度、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. 多行表達式

多行/複雜表達式(如封閉或類別定義)可以在多行中定義。當殼層偵測到它有完整的表達式時,它會編譯並評估它。

定義類別
class Foo {
    def bar() {
        println "baz"
    }
}
使用類別
foo = new Foo()
foo.bar()

1.3.4. 變數

殼層變數全部都是未輸入的(即沒有 def 或其他類型資訊)。

設定殼層變數

foo = "bar"

但是,這會評估局部變數,不會儲存到殼層的環境中

def foo = "bar"

可以透過啟用 解釋器模式 來變更此行為。

1.3.5. 函式

可以在殼層中定義函式,並會儲存起來供以後使用。

定義函式很簡單

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

然後使用它就像預期的那樣

hello("Jason")

在內部,殼層會建立一個封閉來封裝函式,然後將封閉繫結到變數。因此,變數和函式共用同一個命名空間。

1.4. 指令

殼層有許多不同的指令,提供豐富的存取權限來存取殼層的環境。

指令都有名稱捷徑(類似於 \h)。指令也可能有一些預先定義的系統別名。使用者也可以建立自己的別名。

1.4.1. 已識別的指令

help

顯示命令(和別名)清單或特定命令的說明文字。

命令清單

groovy:000> :help

For information about Groovy, visit:
    https://groovy.dev.org.tw

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

清除偏好設定

清除全部

edit

在外部編輯器中編輯目前的緩衝區。

目前僅適用於已設定 EDITOR 環境變數或已設定 editor 偏好設定的 UNIX 系統。

load

將一個或多個檔案(或網址)載入緩衝區。

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.org/4.0.12/html/groovy-jdk/java/util/List.html

這會列印找到的說明文件網址,並開啟兩個視窗(或標籤,視瀏覽器而定)

  • 一個是 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.org/4.0.12/html/gapi/groovy/ant/AntBuilder.html
groovy:000> :doc groovy.xml.XmlSlurper
https://docs.groovy-lang.org/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.org/4.0.12/html/gapi/groovy/lang/Closure.html
https://docs.groovy-lang.org/4.0.12/html/groovy-jdk/groovy/lang/Closure.html
groovy:000> :doc groovy.sql.GroovyResultSet
https://docs.groovy-lang.org/4.0.12/html/gapi/groovy/sql/GroovyResultSet.html
https://docs.groovy-lang.org/4.0.12/html/groovy-jdk/groovy/sql/GroovyResultSet.html

原始陣列和陣列陣列的 GDK 增強功能也有說明文件

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

請注意,指令類別必須在 classpath 中找到:您無法在 shell 中定義新的指令。

1.8. 疑難排解

回報 您遇到的任何問題。請務必使用 Groovysh 元件標記 JIRA 問題。

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 Plugin

Gradle Groovysh Plugin 是一個 Gradle 外掛,提供 gradle 任務來啟動與 Gradle 專案連結的 Groovy Shell。