How to parse a Closure into ConfigSlurper
groovy
Solution
Set the delegate on your `Closure` to the script with a `DELEGATE_FIRST` resolve strategy:
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 a Closure.
Problem
Background. I'm working on a gradle script and want to inline some default configuration using the ConfigSlurper. I'm already able to parse configurations from files, but can't seem to get the inlined 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 doesn't 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 the file i run the pasted script from: scriptStuff.groovy) So i'm not sure this in the correct direction. Actually it would be nicer if you could just pass the closure directly to the Slurper. But the Slurper only takes Script, script file, and String. Another direction would be to convert the clusure to a String. Is this possible? Any solution would be nice. Update Just wanted to elaborate a bit on my use case. I am creating a plugin to 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 even though i could have parsed it using a string notation, then the notation above looks a lot slicker, and more like the rest of the gradle script. On the other hand i don't mind the code parsing the clojure beeing ugly. It's only user inside the plugin. The important ting is that the user facing part is clean.