How to parse closure in ConfigSlurper

Background. I am working on a gradle script and want to embed some default configuration using ConfigSlurper. I can already analyze configurations from files, but I can not get the built-in configuration to work.

What I want to do is something like this:

myScript = { some { random { stuff = "You can access" } } } groovy.lang.Script script = new groovy.lang.Script() { @Override Object run() { theScript.call() } } ConfigSlurper slurper = new ConfigSlurper() slurper.setBinding(["theScript": myScript]) ConfigObject parse = slurper.parse(script) assert parse.some.random.stuff == "You can access" 

This does not work. It says:

 Caught: groovy.lang.MissingMethodException: No signature of method: scriptStuff.some() is applicable for argument types: (scriptStuff$_run_closure1_closure2) values: [ scriptStuff$_run_closure1_closure2@2aca5165 ] Possible solutions: dump(), use([Ljava.lang.Object;), sleep(long), wait(), run(), run() groovy.lang.MissingMethodException: No signature of method: scriptStuff.some() is applicable for argument types: (scriptStuff$_run_closure1_closure2) values: [ scriptStuff$_run_closure1_closure2@2aca5165 ] Possible solutions: dump(), use([Ljava.lang.Object;), sleep(long), wait(), run(), run() at scriptStuff$_run_closure1.doCall(scriptStuff.groovy:2) at scriptStuff$_run_closure1.doCall(scriptStuff.groovy) at scriptStuff$1.run(scriptStuff.groovy:12) at scriptStuff.run(scriptStuff.groovy:18) at com.intellij.rt.execution.application.AppMain.main(AppMain.java:120) 

(scriptStuff refers to a file; I run a nested script from: scriptStuff.groovy)

So I'm not sure if this is in the right direction. Actually, it would be better if you could just close the lid directly in Slurper. But Slurper only accepts a Script, script, and String file. Another direction is to convert clusure to String. Is it possible?

Any solution would be nice.

Update Just wanted to sort out my use case a bit. I am creating a plugin for my gradle scripts. As a user, I want to write something like this:

 projectConfiguration { //this one is easy to parse with ConfigSlurper confFile = "some/path/to/configuration.groovy" //this is difficult to parse inlineConf = { some { inlined { configuration = "Cool!" } } } } 

So, although I could parse it using a string notation, the notation above looks a lot like slicker and looks more like the rest of the gradle script. On the other hand, I am not opposed to the clojure parsing code appearing ugly. This is only the user inside the plugin. It is important that the side facing the user is clean.

+6
source share
2 answers

Set the delegate to Closure in the script using the DELEGATE_FIRST solution DELEGATE_FIRST :

 class ClosureScript extends Script { Closure closure def run() { closure.resolveStrategy = Closure.DELEGATE_FIRST closure.delegate = this closure.call() } } script = new ClosureScript(closure: myScript) 

See Creating a Groovy ConfigObject from Closure .

+3
source

You can use ConfigSlurper to parse a string as follows:

 def myScript = ''' some { random { stuff = "You can access" } } ''' def config = new ConfigSlurper().parse(myScript) assert config.some.random.stuff == "You can access" 

If you really want to pass Script, then you must extend Script, because it is an abstract class. For instance:

 class MyConfiguration extends Script { public Object run() { some { random { stuff = "You can access" } } } } def config = new ConfigSlurper().parse(new MyConfiguration()) assert config.some.random.stuff=="You can access" 
+1
source

All Articles