web-dev-qa-db-fra.com

Charger le script à partir du script groovy

File1.groovy

def method() {
   println "test"
}

File2.groovy

method()

Je veux charger/inclure les fonctions/méthodes de File1.groovy pendant l'exécution, égal à la charge de rubys/rake. Ils se trouvent dans deux répertoires différents.

35
ptomasroos

Si le code dans file2 ne vous dérange pas d'être dans un bloc with, vous pouvez faire:

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

Une autre méthode possible serait de modifier file1.groovy à:

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

Et puis dans file2.groovy vous pouvez utiliser mixin pour ajouter les méthodes de file1

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

method()
29
tim_yates

Vous pouvez évaluer n'importe quelle expression ou script dans Groovy en utilisant GroovyShell .

File2.groovy

GroovyShell Shell = new GroovyShell()
def script = Shell.parse(new File('/path/file1.groovy'))
script.method()
16
Arturo Herrero

Ce sera plus simple si file1.groovy est une classe réelle class File1 {...}.

Étant donné que, une autre façon de le faire est de charger le fichier dans le GroovyClassLoader:

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

File1.method() 

File1.newInstance().anotherMethod()
13
clmarquart

Je suis en retard, mais. C'est ainsi que nous avons réalisé ce que vous demandiez. Donc, j'ai un fichier1.gsh comme ceci:

Fichier1:

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;

Et dans l'autre fichier, ces fonctions sont accessibles en instanciant d'abord. Donc dans file2.

Fichier2:

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

somename.Sometask(param1, param2, param3)
8
OK999

Voici ce que j'utilise.

1: écrire any_path_to_the_script.groovy en tant que classe

2: Dans le script appelant, utilisez:

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

Cela fonctionne dans la console de script Jenkins Groovy. Je n'ai pas essayé de méthodes non statiques.

3
filamoon

La réponse de @tim_yates qui utilise metaClass.mixin aurait dû fonctionner sans avoir à modifier file1.groovy (c'est-à-dire mixin avec l'objet script), mais malheureusement il y a un bogue dans metaClass.mixin qui provoque une erreur SO dans ce scénario (voir GROOVY-4214 sur ce problème spécifique). Cependant, j'ai contourné le bogue à l'aide de ce qui suit sélectif 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()

La solution ci-dessus fonctionne sans qu'aucune modification ne soit nécessaire pour File1.groovy ou les appelants dans File2.groovy (sauf pour la nécessité d'introduire un appel à la fonction loadScript).

1
haridsv