web-dev-qa-db-fra.com

Y compris un script groovy dans un autre groovy

J'ai lu comment importer simplement un fichier groovy dans un autre script groovy

Je veux définir des fonctions communes dans un fichier groovy et appeler ces fonctions à partir d'autres fichiers groovy. 

Je comprends que ce serait utiliser Groovy comme un langage de script, c’est-à-dire que je n’ai pas besoin de classes/d’objets. J'essaie quelque chose comme dsl qui peut être fait en groovy. Toutes les variables seront affirmées à partir de Java et je veux exécuter un script groovy dans un shell. 

Est-ce possible ? Quelqu'un peut-il donner un exemple?.

78
Kannan Ekanath
evaluate(new File("../tools/Tools.groovy"))

Mettez cela en haut de votre script. Cela apportera le contenu d'un fichier groovy (il suffit de remplacer le nom du fichier entre les guillemets par votre script groovy).

Je fais cela avec une classe étonnamment appelée "Tools.groovy".

95
jmq

A partir de Groovy 2.2, il est possible de déclarer une classe de script de base avec la nouvelle annotation de transformation @BaseScript AST.

Exemple:

fichier MainScript.groovy :

abstract class MainScript extends Script {
    def meaningOfLife = 42
}

fichier test.groovy :

import groovy.transform.BaseScript
@BaseScript MainScript mainScript

println "$meaningOfLife" //works as expected
43
emesx

Une autre façon de faire est de définir les fonctions dans une classe groovy, d’analyser et d’ajouter le fichier au chemin de classe à l’exécution:

File sourceFile = new File("path_to_file.groovy");
Class groovyClass = new GroovyClassLoader(getClass().getClassLoader()).parseClass(sourceFile);
GroovyObject myObject = (GroovyObject) groovyClass.newInstance();
31
grahamparks

Je pense que le meilleur choix est d'organiser les utilitaires sous la forme de classes groovy, de les ajouter à classpath et de laisser le script principal s'y référer via le mot-clé import.

Exemple:

scripts/DbUtils.groovy

class DbUtils{
    def save(something){...}
}

scripts/script1.groovy:

import DbUtils
def dbUtils = new DbUtils()
def something = 'foobar'
dbUtils.save(something)

script en cours d'exécution:

cd scripts
groovy -cp . script1.groovy
29
snowindy

La façon dont je fais cela est avec GroovyShell.

GroovyShell Shell = new GroovyShell()
def Util = Shell.parse(new File('Util.groovy'))
def data = Util.fetchData()
6
Mike_Dave

Groovy n'a pas de mot-clé d'import, comme les langages de script classiques, qui effectue une inclusion littérale du contenu d'un autre fichier (auquel on fait allusion ici: Groovy fournit-il un mécanisme d'inclusion? ). 
En raison de sa nature orientée objet/classe, vous devez "jouer à des jeux" pour faire en sorte que cela fonctionne. Une possibilité consiste à rendre toutes vos fonctions utilitaires statiques (puisque vous avez dit qu'elles n'utilisent pas d'objets), puis à effectuer une importation statique dans le contexte de votre shell en cours d'exécution. Ensuite, vous pouvez appeler ces méthodes comme "fonctions globales". 
Une autre possibilité consisterait à utiliser un objet Binding ( http://groovy.codehaus.org/api/groovy/lang/Binding.html ) tout en créant votre shell et en liant toutes les fonctions souhaitées aux méthodes (l'inconvénient ici, il faudrait énumérer toutes les méthodes de la liaison, mais vous pourriez peut-être utiliser la réflexion). Une autre solution consisterait à remplacer methodMissing(...) dans l'objet délégué attribué à votre shell, ce qui vous permet d'effectuer une répartition dynamique en utilisant une carte ou la méthode de votre choix. 

Plusieurs de ces méthodes sont illustrées ici: http://www.nextinstruction.com/blog/2012/01/08/creating-dsls-with-groovy/ . Faites-moi savoir si vous voulez voir un exemple d'une technique particulière.

6
omnisis

Pourquoi ne pas traiter le script externe comme une classe Java? Basé sur cet article: https://www.jmdawson.net/blog/2014/08/18/using-functions-from-one-groovy-script-in-another/

getThing.groovy Le script externe

def getThingList() {
    return ["thing","thin2","thing3"]
}

printThing.groovy Le script principal

thing = new getThing()  // new the class which represents the external script
println thing.getThingList()

Résultat

$ groovy printThing.groovy
[thing, thin2, thing3]
5
askalee

Voici un exemple complet d'inclusion d'un script dans un autre.
Il suffit d’exécuter le fichier Testmain.groovy
Commentaires explicatifs inclus parce que je suis gentil comme ça;]

Testutils.groovy

// This is the 'include file'
// Testmain.groovy will load it as an implicit class
// Each method in here will become a method on the implicit class

def myUtilityMethod(String msg) {
    println "myUtilityMethod running with: ${msg}"
}

Testmain.groovy

// Run this file

// evaluate implicitly creates a class based on the filename specified
evaluate(new File("./Testutils.groovy"))
// Safer to use 'def' here as Groovy seems fussy about whether the filename (and therefore implicit class name) has a capital first letter
def tu = new Testutils()
tu.myUtilityMethod("hello world")
3
davidfrancis

Groovy peut importer d'autres classes groovy exactement comme Java. Assurez-vous simplement que l'extension du fichier de bibliothèque est .groovy. 

    $ cat lib/Lib.groovy
    package lib
    class Lib {
       static saySomething() { println 'something' }
       def sum(a,b) { a+b }
    }

    $ cat app.gvy
    import lib.Lib
    Lib.saySomething();
    println new Lib().sum(37,5)

    $ groovy app
    something
    42
0
miles zarathustra

Pour les retardataires, il semble que groovy supporte maintenant la commande :load file-path qui redirige simplement les entrées à partir du fichier donné. Il est donc désormais simple d’inclure des scripts de bibliothèque.

Cela fonctionne comme entrée dans le groovysh & comme ligne dans un fichier chargé:
groovy:000> :load file1.groovy

file1.groovy peut contenir:
:load path/to/another/file invoke_fn_from_file();

0
Jack Punt

Une combinaison des réponses @grahamparks et @snowindy avec quelques modifications est ce qui a fonctionné pour mes scripts Groovy exécutés sur Tomcat:

Utils.groovy

class Utils {
    def doSth() {...}
}

MyScript.groovy:

/* import Utils --> This import does not work. The class is not even defined at this time */
Class groovyClass = new GroovyClassLoader(getClass().getClassLoader()).parseClass(new File("full_path_to/Utils.groovy")); // Otherwise it assumes current dir is $CATALINA_HOME
def foo = groovyClass.newInstance(); // 'def' solves compile time errors!!
foo.doSth(); // Actually works!
0
Sergio Muriel