2013-09-03 23 views
16

プラグイン拡張オブジェクトで収集された情報に従って、依存関係をproject.dependenciesに追加するプラグインを作成しようとしています。しかし、それは不可能と思われる。Gradleカスタムプラグイン:拡張オブジェクトから依存関係を追加する

実際、拡張オブジェクトのデータは新しいタスクまたはproject.afterEvaluateクロージャでのみ使用できますが、それらの場所に追加された依存関係は無視されます。


次のコードは、afterEvaluateに依存関係を追加しようとしますが、依存性が無視されます。依存性注入の作品次のコードで

apply plugin: MyPlugin 

myplugin { 
    version '1.0' 
} 

class MyPlugin implements Plugin<Project> { 
    void apply(Project project) { 
    project.extensions.create('myplugin', MyPluginExtension) 

    project.afterEvaluate { 
     def version = project.myplugin.version 
     project.dependencies.add("compile", "org.foo:bar:$version") // --> ignored 
    } 
    } 
} 

class MyPluginExtension { 
    def version 
} 

を私はへのアクセスを持っていません拡張オブジェクト:

apply plugin: MyPlugin 

myplugin { 
    version '1.0' 
} 

class MyPlugin implements Plugin<Project> { 
    void apply(Project project) { 
    project.extensions.create('myplugin', MyPluginExtension)  

    def version = project.myplugin.version // == null 
    project.dependencies.add("compile", "org.foo:bar:$version") // --> fail because $version is null 

    } 
} 

class MyPluginExtension { 
    def version 
} 

解決策はありますか?それはまだ、関連するかどう

+1

あなたは一つの方法または別では、拡張子にアクセス延期する必要があります。 'project.afterEvaluate'での依存関係の追加がうまくいかない理由は私には分かりません。プラグインを使用するコードに問題がある可能性があります。 –

+0

ありがとう、私はコードを簡略化するために簡略化しました。ここでコード全体(https://github.com/tbruyelle/ResetUnreadSms/blob/aa-plugin/build.gradle)を見つけることができます。アノテーションからJavaクラスを生成するライブラリ用のアンドロイドプラグインです。プラグインは拡張オブジェクトなしでうまく動作しますが、質問で説明したように、拡張オブジェクトからのデータを依存関係に注入したい場合は失敗します。 – tbruyelle

+0

cc @PeterNiederwieserあなたが私の答えによって通知されていない場合に備えて... – tbruyelle

答えて

1

は分からないのですが、あなたは明示的doFirstでJavaクラスパスに、コンパイルの設定を追加することでこの問題を回避することができます

variant.javaCompile.doFirst { 
    variant.javaCompile.classpath += project.configurations.myconfiguration 
} 
13

更新:私は私の元以来、これを理解するために管理しました回答。これは、依存関係を追加してリスナーを削除して、後で解決手順に追加しようとしないように、DependencyResolutionListenerを追加する方法です。 。

これは遅くはなく、最新のGradleで落下誰(2.6にもある:

compileDeps = project.getConfigurations().getByName("compile").getDependencies() 
project.getGradle().addListener(new DependencyResolutionListener() { 
    @Override 
    void beforeResolve(ResolvableDependencies resolvableDependencies) { 
     compileDeps.add(project.getDependencies().create("org.foo:bar:$version")) 
     project.getGradle().removeListener(this) 
    } 

    @Override 
    void afterResolve(ResolvableDependencies resolvableDependencies) {} 
}) 

私はこのhere

オリジナル回答を使用して、プラグインの作業例を持っています書き込み時)には、DependencyResolutionListenerを追加して、依存関係が解決される前に依存関係を追加することができます。

project.getGradle().addListener(new DependencyResolutionListener() { 
    @Override 
    void beforeResolve(ResolvableDependencies resolvableDependencies) { 
     depsToAdd.each { dep -> 
      compileConfig.getDependencies() 
       .add(project.getDependencies().create(dep)) 
     } 
    } 

    @Override 
    void afterResolve(ResolvableDependencies resolvableDependencies) { 

    } 
}) 

しかし、この記事の執筆時点で、Android Studio IDEでこれを動作させるにはいくつかの問題がありました。問題は私の質問で追跡されますhere

3

私はもともとこのソリューションをSaadのDependencyResolutionListenerアプローチを使用して実装しました。ただし、リスナー自体はonly when something iterates over the configuration associated with the dependencyと呼ばれます。

project.configurations.compile.each { 
    ... 
} 

しかしcompileがあるので、これは、当然のこととして起こるものです:あなたが動的compileに依存関係を追加したい場合たとえば、あなたは何かが後でのような何かをすることを確認する必要がありますJavaプラグインを使用するプロジェクトの既知の設定。しかし、カスタム構成を使用している場合(私の場合)、リスナー・アプローチは、明示的にカスタム構成を反復しない限り機能しません。

私はこれを行うためのより良い方法を見つけることができ、afterEvaluateの中にOPが元々必要としていました。私はここでカスタム設定を使用していますが、私はどちらかそれがcompileのために働かない理由が表示されない:もちろん

project.afterEvaluate { 
    def version = project.myPlugin.version 
    project.configurations.myConfig.dependencies.add(
     project.dependencies.add("myConfig", "org.foo:bar:$version") 
    ) 
} 

を、いくつかの点で何かがまだそれらの依存関係を反復処理する必要があります実際に解決される。

0

これを行う最も簡単な方法:

project.dependencies { 
    delegate.compile("com.android.support:appcompat-v7:25.0.1") 
} 
関連する問題