2017-04-07 18 views
2

私はマルチプロジェクトを持っており、最後のサブプロジェクトをビルドした後、すべてのjarを処理したいと思います。ルートディレクトリに./gradlew installを呼び出す際にルートプロジェクトでパス 'build'のタスクが見つかりません

task install(dependsOn: 'build', type: Copy) { 
    doLast { 
     println "exec install task" 
    } 
} 

、私はこのエラーに直面しています: は、したがって、私は、ルート・プロジェクトでタスクを作成した

FAILURE: Build failed with an exception. 

* What went wrong: 
Could not determine the dependencies of task ':install'. 
> Task with path 'build' not found in root project 'foo'. 

しかし、./gradlew tasksを呼び出すと、私はこれらのタスクを示しています。

:tasks 

------------------------------------------------------------ 
All tasks runnable from root project 
------------------------------------------------------------ 

Build tasks 
----------- 
assemble - Assembles the outputs of this project. 
build - Assembles and tests this project. 
... 

どのようにして目的の機能を達成できますか?

答えて

2

あなたのルートプロジェクトはビルドを構成していると仮定しますが、ビルドアクションはそれ自体では定義しません。 buildタスクは多くの場合、言語プラグイン(ほとんどの場合apply plugin: 'java'経由)で定義されますが、ルートプロジェクトでそれらを使用していない場合はbuildタスクはありません。

あなたが使用するヘルプタスクtasksの説明、says

Displays the tasks runnable from root project 'projectReports' (some of the displayed tasks may belong to subprojects).

ヘルプタスクは、コマンドラインを介してタスクの起動と同じロジックをfollowes。あなたはタスク名を提供することができ、任意のサブプロジェクト内の名前を持つタスクが実行されます(つまり、gradle buildが機能する)。

ただし、dependsOn依存関係を定義すると、指定された文字列は単一のタスクのタスクパスとして評価されます。各タスク名はプロジェクトで一度しか使用できないため、名前はルートプロジェクト内のタスクで一意ですが、サブプロジェクトが考慮される場合は多くのタスクが見つかります。そのため、サブプロジェクトのタスクを識別するために構文:<projectName>:<taskName>を使用することができます。

ここでは、具体的な問題に直面します。installタスクが1つのサブプロジェクトのbuildタスクに依存する必要がある場合は、dependsOn ':<mySubproject>:build'を使用できます。しかし、私はあなたがinstallタスクは、各サブプロジェクトbuildタスクに依存するとしますので、私はこのアプローチを提案したいと思います:

task install(type: Copy) { 
    dependsOn subprojects*.tasks*.findByName('build').minus(null) 
    doLast { 
     println "exec install task" 
    } 
} 

この方法では、各登録サブプロジェクトのために、findByName('build')が呼び出され、その結果(見つかったがタスクまたはnull)がリストに入れられ、タスク依存リストとして使用されます。私は、.minus(null)部分を追加して、nullのエントリをリストから削除します。なぜなら、Gradleが依存関係コレクション内のそのようなエントリをどのように処理するかわからないからです。それぞれのサブプロジェクトがbuildタスクを提供していることが確かであれば、getByName('build')も使用できます。

EDIT: OPは手動ですべてのサブプロジェクトを反復処理よりも良いこの場合に合って、必要に応じて、再帰的getTasksByName方法を見つけた:

dependsOn getTasksByName('build', true) 
+0

がご説明いただき、誠にありがとうございます。私はできるだけ早くそれを試してみましょう。 'dependsOn subprojects * .findByName( 'build').minus(null)'は 'install'を1回だけ呼び出すでしょうか?サブプロジェクトA、B、Cがある場合、 'install'はすべてのサブプロジェクトの最後のビルドが終了した後に一度だけ実行されます。 – user3105453

+0

はい、すべてのタスクは1回だけ実行されます。1つが複数の他のタスクに依存する場合、これらのタスクがすべて完了した後に実行されます。あなたが100%確実であれば、サブプロジェクトCの 'build'タスクは__always__が最後のものになります。' dependsOn ':projectC:build''を使うことができますが、それぞれのタスクに依存することをお勧めします。 Gradleに依存ツリーをそれ自身で把握させる。 3つのプロジェクトでは、 'dependsOn ':projectA:build'、 ':projectB:build'、 ':projectC:build''を介して、依存関係を手動で定義することもできます。 –

+1

あなたのソリューションを試してみた。残念なことに 'findByName'は動作しませんでしたが、このコード行は私が期待している通りです:' dependsOn subprojects * .getTasksByName( "build"、true) 'お気軽にソリューションをアップデートしてください。私はそれをそのまま受け入れることができます。どうもありがとうございました。 – user3105453

関連する問題