加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 大数据 > 正文

groovy – 如何将Closure解析为ConfigSlurper

发布时间:2020-12-14 16:29:33 所属栏目:大数据 来源:网络整理
导读:背景.我正在使用gradle脚本,并希望使用ConfigSlurper内联一些默认配置.我已经能够从文件中解析配置,但似乎无法使内联配置工作. 我想做的是这样的: myScript = { some { random { stuff = "You can access" } }}groovy.lang.Script script = new groovy.lang
背景.我正在使用gradle脚本,并希望使用ConfigSlurper内联一些默认配置.我已经能够从文件中解析配置,但似乎无法使内联配置工作.

我想做的是这样的:

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"

这不起作用.它说

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(),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指的是我运行粘贴脚本的文件:scriptStuff.groovy)

所以我不确定这是正确的方向.实际上如果你可以直接将封闭物传递给Slurper会更好.
但是Slurper只接受脚本,脚本文件和字符串.
另一个方向是将clusure转换为String.这可能吗?

任何解决方案都会很好.

更新
只是想详细说明一下我的用例.
我正在为我的gradle脚本创建一个插件.作为一个用户我想写这样的东西:

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!"
         }
      }
   }
}

因此,即使我可以使用字符串表示法对其进行解析,但上面的符号看起来更加流畅,而且更像是gradle脚本的其余部分.
另一方面,我不介意解析clojure的代码丑陋.它只是插件中的用户.重要的是面向零件的用户是干净的.

解决方法

使用DELEGATE_FIRST解析策略将Closure上的委托设置为脚本:

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

见Creating a Groovy ConfigObject from a Closure.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读