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?.
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".
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
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();
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
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()
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.
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]
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")
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
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();
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!