it-swarm.com.de

Einfügen eines groovigen Skripts in ein anderes Groovy

Ich habe gelesen wie man einfach eine groovige Datei in ein anderes grooviges Skript importiert

Ich möchte allgemeine Funktionen in einer groovigen Datei definieren und diese Funktionen aus anderen groovigen Dateien aufrufen. 

Ich verstehe, dass dies Groovy wie eine Skriptsprache verwenden würde, d. H. Ich brauche keine Klassen/Objekte. Ich versuche zu etwas wie dsl, das in groovy gemacht werden kann. Alle Variablen werden von Java übernommen und ich möchte ein grooviges Skript in einer Shell ausführen. 

Ist das überhaupt möglich? Kann jemand ein Beispiel geben.

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

Setzen Sie das ganz oben in Ihr Skript. Dadurch wird der Inhalt einer groovigen Datei eingefügt (ersetzen Sie einfach den Dateinamen zwischen den Anführungszeichen durch Ihr grooviges Skript).

Ich mache dies mit einer Klasse, die überraschenderweise "Tools.groovy" genannt wird.

95
jmq

Ab Groovy 2.2 ist es möglich, eine Basisskriptklasse mit der neuen Annotation @BaseScript AST zu deklarieren.

Beispiel:

Datei MainScript.groovy :

abstract class MainScript extends Script {
    def meaningOfLife = 42
}

Datei test.groovy :

import groovy.transform.BaseScript
@BaseScript MainScript mainScript

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

Eine andere Möglichkeit besteht darin, die Funktionen in einer groovigen Klasse zu definieren und die Datei zur Laufzeit zu analysieren und dem Klassenpfad hinzuzufügen:

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

Ich denke, dass die beste Wahl darin besteht, Hilfsprogramme in Form grooviger Klassen zu organisieren, sie zu classpath hinzuzufügen und das Hauptskript über das import-Schlüsselwort referenzieren zu lassen.

Beispiel:

skripte/DbUtils.groovy

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

scripts/script1.groovy:

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

laufendes Skript:

cd scripts
groovy -cp . script1.groovy
29
snowindy

Ich mache das mit GroovyShell.

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

Groovy hat kein Import-Schlüsselwort wie typische Skriptsprachen, die den Inhalt einer anderen Datei wörtlich einbeziehen (hier angesprochen: Bietet Groovy einen Include-Mechanismus? ). 
Aufgrund seines objekt-/klassenorientierten Charakters müssen Sie "Spiele spielen", damit solche Dinge funktionieren. Eine Möglichkeit besteht darin, alle Funktionen Ihres Dienstprogramms als statisch zu definieren (da Sie sagten, dass sie keine Objekte verwenden) und anschließend im Kontext Ihrer ausführenden Shell einen statischen Import durchzuführen. Dann können Sie diese Methoden wie "globale Funktionen" aufrufen. 
Eine andere Möglichkeit wäre, ein Binding-Objekt ( http://groovy.codehaus.org/api/groovy/lang/Binding.html ) zu verwenden, während Sie Ihre Shell erstellen und alle gewünschten Funktionen an die Methoden binden (der Nachteil) Hier müssten Sie alle Methoden in der Bindung auflisten, aber Sie könnten vielleicht Reflektion verwenden. Eine andere Lösung wäre, methodMissing(...) in dem Delegate-Objekt zu überschreiben, das Ihrer Shell zugewiesen ist. Dies ermöglicht Ihnen im Wesentlichen das dynamische Dispatching mithilfe einer Karte oder einer beliebigen Methode, die Sie möchten. 

Einige dieser Methoden werden hier demonstriert: http://www.nextinstruction.com/blog/2012/01/08/creating-dsls-with-groovy/ . Lassen Sie mich wissen, wenn Sie ein Beispiel für eine bestimmte Technik sehen möchten.

6
omnisis

Wie wäre es, das externe Skript als Java-Klasse zu behandeln? Basierend auf diesem Artikel: https://www.jmdawson.net/blog/2014/08/18/using-functions-von-one-groovy-script-in-another/

getThing.groovy Das externe Skript

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

printThing.groovy Das Hauptskript

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

Ergebnis

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

Hier ist ein vollständiges Beispiel für das Einfügen eines Skripts in ein anderes.
Führen Sie einfach die Testmain.groovy-Datei aus
Erklärende Kommentare enthalten, weil ich so nett bin;]

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 kann andere Groovy-Klassen genau wie Java importieren. Stellen Sie nur sicher, dass die Erweiterung der Bibliotheksdatei .groovy ist. 

    $ 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

Für Neuankömmlinge scheint es so zu sein, dass Groovy jetzt den :load file-path-Befehl unterstützt, der die Eingabe einfach aus der angegebenen Datei umleitet. Daher ist es jetzt trivial, Bibliothekskripte einzubinden.

Es funktioniert als Eingabe für die Groovysh & als Zeile in einer geladenen Datei:
groovy:000> :load file1.groovy

file1.groovy kann enthalten:
:load path/to/another/file invoke_fn_from_file();

0
Jack Punt

Eine Kombination aus @ grahamparks- und @snowindy-Antworten mit einigen Modifikationen funktionierte für meine auf Tomcat laufenden Groovy-Skripts:

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