6

バックグラウンド。私は 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(), 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 は、貼り付けたスクリプトを実行するファイルを指します: scriptStuff.groovy)

したがって、これが正しい方向かどうかはわかりません。実際には、クロージャを Slurper に直接渡すことができればもっと良いでしょう。しかし、Slurper はスクリプト、スクリプト ファイル、および文字列しか受け取りません。もう 1 つの方向は、clsure を 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 スクリプトに似ています。一方、クロージュアを解析するコードが醜いことは気にしません。プラグイン内の唯一のユーザーです。重要なことは、ユーザーに面する部分がきれいであることです。

4

2 に答える 2

3

解決戦略Closureを使用してスクリプトにデリゲートを設定します。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)

Closure からの Groovy ConfigObject の作成 を参照してください。

于 2013-03-14T20:32:09.967 に答える
1

ConfigSlurper を使用して、次のように文字列を解析できます。

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

本当にスクリプトを渡したい場合は、スクリプトが抽象クラスであるため、スクリプトを拡張する必要があります。例えば:

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"
于 2013-03-14T15:13:09.023 に答える