Gradleのコンフィギュレーションを調べる

Gradleで非標準のSourceSetsを使うで(自分には)わかったことだが、最も良く使用するcompileというコンフィギュレーションはmainというソースセットのためのものであり、mainのソースをコンパイルするのに必要な依存を主に定義するものである(それに加えて、testソースセット用のものもある)。

main, test以外のソースセットに対しては、別のコンフィギュレーションを作成しなければならない。別のものを作成した場合、main,test用のコンフィギュレーションを継承することもできる。

Gradleのマニュアル・書籍のわかりにくさ

このあたりが、Gradleのマニュアルや書籍を読んだときに非常にわかりにくい点である。main, testのソースセットに言及せずに、compile, runtime等のコンフィギュレーションを説明し、別の箇所で「他のソースセットも作れます」と説明するので、それらの関係が全くわからなくなるのだ。

物事は何でもそうなのだが、まず大局。一般論から説明しなければならない。その上で、個別のケースについて「省略できます」としなければならないのにも関わらず、説明が逆になっているのである。まず省略された方から説明しようとするため、訳のわからないものになってしまう。

例えば、マニュアルの第8章 依存関係管理の基本を読んで見ると、このページ内を検索しても、「main」というソースセットの名称も無いし、「ソースセット」「SourceSet」という言葉すら出てこない。「依存関係の宣言」では、何が依存するものを宣言するのかさえ示されていない。

第51章 依存関係の管理も全く同じだ。ここでも「ソースセット」「SourceSet」等の言葉は一切出てこない。

23.5. 依存関係の管理では、一応ソースセットと同じページで説明されてはいるが、ソースセットとコンフィギュレーションの関係が曖昧にしか示されていない。「利用するタスク」としてのcompileJava、compileTestJavaを介在してしか結びつきが見られない。ここから「mainソースセットの依存を定義するためのコンフィギュレーションとして主にcompileがある」ことを発見することは難しい。

すべてのコンフィギュレーションと関係を一覧する

そこで、存在するすべてのコンフィギュレーション、ソースセットの関係、コンフィギュレーションどうしの関係を一覧するにはどうすれば良いのだろうか?とりあえず以下を行ってみる。

apply plugin: 'java'

sourceSets {
  foobar {
    java {
      srcDir 'src'
    }
    resources {
      srcDir 'src'
    }
    java.outputDir = file('sbin')
    output.resourcesDir = file('sbin')
  }
}

task showConfigurations()  { doLast {
  configurations.getAll().each{ 
    println it.getName()
    it.getExtendsFrom().forEach {
      println "  " + it.getName()
    }
  }
}}

結果は以下

apiElements
  runtime
archives
compile
compileClasspath
  compileOnly
  implementation
compileOnly
default
  runtimeElements
foobarCompile
foobarCompileClasspath
  foobarCompileOnly
  foobarImplementation
foobarCompileOnly
foobarImplementation
  foobarCompile
foobarRuntime
  foobarCompile
foobarRuntimeClasspath
  foobarRuntimeOnly
  foobarRuntime
  foobarImplementation
foobarRuntimeOnly
implementation
  compile
runtime
  compile
runtimeClasspath
  runtimeOnly
  runtime
  implementation
runtimeElements
  implementation
  runtimeOnly
  runtime
runtimeOnly
testCompile
  compile
testCompileClasspath
  testCompileOnly
  testImplementation
testCompileOnly
testImplementation
  testCompile
  implementation
testRuntime
  testCompile
  runtime
testRuntimeClasspath
  testRuntimeOnly
  testRuntime
  testImplementation
testRuntimeOnly
  runtimeOnly

foobarソースセットを定義しただけで、一連のfoobar*コンフィギュレーションが作成されており、それはcompileやtestCompileとの関わりは無い。また、testCompileはcompileを継承しており、testRuntimeはtestCompileとruntimeを継承していることがわかる。

※他のコンフィギュレーションは何に使われるのか、私にはわからない。また、ここでは、ソースセットとの関連が示されていないのだが、それを取得する方法はわからなかった。

継承してみる

試しに、foobarCompileをcompileから継承させてみる。

apply plugin: 'java'

sourceSets {
  foobar {
    java {
      srcDir 'src'
    }
    resources {
      srcDir 'src'
    }
    java.outputDir = file('sbin')
    output.resourcesDir = file('sbin')
  }
}

/* 追加 */
configurations {
  foobarCompile.extendsFrom compile
}

task showConfigurations()  { doLast {
  configurations.getAll().each{ 
    println it.getName()
    it.getExtendsFrom().forEach {
      println "  " + it.getName()
    }
  }
}}

たしかにcompileを継承している

foobarCompile
  compile
foobarCompileClasspath
  foobarCompileOnly
  foobarImplementation
foobarCompileOnly
foobarImplementation
  foobarCompile
foobarRuntime
  foobarCompile
foobarRuntimeClasspath
  foobarRuntimeOnly
  foobarRuntime
  foobarImplementation
foobarRuntimeOnly