Загрузить скрипт из Groovy скрипт - PullRequest
34 голосов
/ 25 января 2012

File1.groovy

def method() {
   println "test"
}

File2.groovy

method()

Я хочу загрузить / включить функции / методы из File1.groovy во время выполнения, равно как Ruby/ Грабли нагрузки.Они находятся в двух разных каталогах.

Ответы [ 6 ]

29 голосов
/ 25 января 2012

Если вы не возражаете против кода в файле file2, находящемся в блоке with, вы можете сделать:

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

Другой возможный метод - изменить file1.groovy на:

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

А затем в file2.groovy вы можете использовать mixin для добавления методов из file1

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

method()
16 голосов
/ 25 января 2012

Вы можете оценить любое выражение или скрипт в Groovy, используя GroovyShell .

File2.groovy

GroovyShell shell = new GroovyShell()
def script = shell.parse(new File('/path/file1.groovy'))
script.method()
13 голосов
/ 25 января 2012

Будет проще, если file1.groovy - фактический класс class File1 {...}.

Учитывая это, еще один способ сделать это - загрузить файл в GroovyClassLoader:

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

File1.method() 

File1.newInstance().anotherMethod()
7 голосов
/ 25 августа 2016

Я опоздал на это, но.Вот как мы добились того, о чем вы просили.Итак, у меня есть file1.gsh, например, так:

File1:

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;

И в другом файле эти функции могут быть доступны путем создания экземпляра в первую очередь.Так в файле2.

Файл2:

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

somename.Sometask(param1, param2, param3)
3 голосов
/ 27 ноября 2013

Вот что я использую.

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. Я не пробовал нестатические методы.

1 голос
/ 17 сентября 2018

Ответ @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.groovy или вызывающих абонентов в File2.groovy(за исключением необходимости вводить вызов функции loadScript).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...