簡體   English   中英

從Groovy腳本加載腳本

[英]Load script from groovy script

File1.groovy

def method() {
   println "test"
}

File2.groovy

method()

我想在運行時從File1.groovy加載/包含函數/方法,這等於rubys / rake的加載。 它們位於兩個不同的目錄中。

如果您不介意file2中的代碼位於with塊中,則可以執行以下操作:

new GroovyShell().parse( new File( 'file1.groovy' ) ).with {
  method()
}

另一種可能的方法是將file1.groovy更改為:

class File1 {
  def method() {
    println "test"
  }
}

然后在file2.groovy您可以使用mixinfile1添加方法

def script = new GroovyScriptEngine( '.' ).with {
  loadScriptByName( 'file1.groovy' )
} 
this.metaClass.mixin script

method()

您可以使用GroovyShell評估Groovy中的任何表達式或腳本。

File2.groovy

GroovyShell shell = new GroovyShell()
def script = shell.parse(new File('/path/file1.groovy'))
script.method()

如果file1.groovy是實際的類class File1 {...}這將是最簡單的。

鑒於此,另一種方法是將文件加載到GroovyClassLoader

this.class.classLoader.parseClass("src/File1.groovy")

File1.method() 

File1.newInstance().anotherMethod()

但是我遲到了。 這就是我們一直在實現您的要求的方式。 所以,我有一個file1.gsh像這樣:

文件1:

println("this is a test script")

def Sometask(param1, param2, param3)
{
    retry(3){
        try{
            ///some code that uses the param
        }
        catch (error){
            println("Exception throw, will retry...")
            sleep 30
            errorHandler.call(error)
        }
    }
}

return this;

在另一個文件中,可以通過首先實例化來訪問這些功能。 因此在file2中。

文件2:

def somename
somename = load 'path/to/file1.groovy'
 //the you can call the function in file1 as

somename.Sometask(param1, param2, param3)

這是我正在使用的。

1:將any_path_to_the_script.groovy為類

2:在調用腳本中,使用:

def myClass = this.class.classLoader.parseClass(new File("any_path_to_the_script.groovy"))
myClass.staticMethod()

它在Jenkins Groovy腳本控制台中工作。 我還沒有嘗試過非靜態方法。

@tim_yates使用metaClass.mixin的答案應該可以工作,而無需對file1.groovy任何更改(即,將mixin與腳本對象一起使用),但是不幸的是, metaClass.mixin存在一個錯誤,在這種情況下會導致SO錯誤(有關此特定問題,請參閱GROOVY-4214 )。 但是,我使用以下選擇性 mixin解決了該錯誤:

def loadScript(def scriptFile) {
   def script = new GroovyShell().parse(new File(scriptFile))
   script.metaClass.methods.each {
       if (it.declaringClass.getTheClass() == script.class && ! it.name.contains('$') && it.name != 'main' && it.name != 'run') {
           this.metaClass."$it.name" = script.&"$it.name"
       }
   }
}

loadScript('File1.groovy')
method()

上面的解決方案無需對File1.groovyFile1.groovy的調用者進行任何更改File2.groovy (除了需要引入對loadScript函數的調用之外)。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM