久々にパソコンの前に座ったので、リハビリ代わりに先月にリリースされたGradle2.10のリリースノート意訳というか、中途半端に翻訳した。分量が多かったので訳してないところがありますが、引き続き入院してるので、翻訳の続きはありません。
オリジナル(英文)はこちら
新機能と変更
ネイティブコンパイルのパフォーマンス改善
Gradleはインクリメンタルビルドする場合に、すべての入力値、入力ファイル、出力ファイルを必要としている。それによってGradleは入出力ファイルの変更がない場合にタスクをスキップできる。
ネイティブコンパイル系のタスクの場合、ディレクトリー構造も考慮しているため、インクルードされるディレクトリーが多い場合や、ルートディレクトリーがインクルードされている場合にパフォーマンス上の問題が発生した。UP-TO-DATEチェックを速くするために、以下の変更をおこなった。
- インクルードディレクトリーも入力値として扱う
- 実際に参照されるヘッダーファイルだけを入力情報として扱う
我々のベンチマークでは非常に大きなプロジェクトのインクリメンタルビルドにおいて多大な改善がみられた。
C++および関連言語では、Gradleはソースファイルをパースしてインクルードされるヘッダーファイルを特定する。Gradleがヘッダーファイルの特定ができない場合は、古いメカニズムを採用する。つまり、マクロによって#include
句を定義することは、新しい仕組みを利用できなくなるため、推奨されない。
テストキット依存性の改善
gradleTestKit()
を使ってGradleテストキットをテスト時ランタイムクラスパスに組み込むことができる。以前のバージョンではテストキットがGradleのコアに依存しているため、コアクラスもテスト実行時のクラスパスに組み込んでしまっていた。そのため、テストキットにより追加される実行時ライブラリーとユーザーが利用する依存ライブラリーとの間でバージョンのコンフリクトが発生してしまっていた。
Gradleテストキットは実行時クラスパスの汚染を避けるために、テストキットが依存するGradleのコアクラスおよび依存ライブラリーをオールインワンjarの形で利用するように修正する。
buildScript
依存性を図示する新しいタスク
buildEnvironment
タスクによって、buildscript
ブロックで宣言された依存性を表示できるようにした。これによって、ビルド時のビルドのデバッグなどがよりやりやすくなる。
チェックスタイルレポートのHTML出力
チェックスタイルタスクがXMLに加えてHTMLの形式でもレポートを出力するように変更した。このHTMLレポートはデフォルトで利用できる。
eclipseプロジェクトにてTooling APIがソースレベルで開示されるように修正
tooling APIがJavaソースレベルでAPIを開示するようにして、eclipseプロジェクトでjavaSourceSettings
プロパティから参照できる。Buildshipなどで煩わしかった設定が簡素化される。
Javaソフトウェアモデルにおける依存性管理機能
今回のリリースでJavaソフトウェアモデルに依存性管理の機能が追加された。
コンポーネントレベルでの依存性管理
ソースで依存性を表現するよりもコンポーネントを用いた方がやりやすい。
plugins { id 'jvm-component' } model { components { main(JvmLibrarySpec) { dependencies { library "core" } } core(JvmLibrarySpec) { } } }
外部依存性管理
ソフトウェアモデルでの外部依存性管理も利用可能になった。
apply plugin: 'jvm-component' repositories { jcenter() } model { components { main (JvmLibrarySpec) { dependencies { // 外部依存性はmoduleでもgroupでも始められる group 'com.acme' module 'artifact' version '1.0' module 'artifact' group 'com.acme' version '1.0' // ショートハンドスタイルも利用可能 module 'com.acme:artifact:1.42' } } } }
ソフトウェアモデルにおけるDSLの改善
モデル空間のDSLを修正した。
ネストしたルール
ModelMap
の生成や設定ではネストしたルールを利用できる。
model { components { myLib { … } test { // `myLib`を入力値として利用する。 // このコードが実行されると`test`が完全に定義されて、model 以外からは変更できなくなる。 targetPlatform = $.components.myLib.targetPlatform } } }
tasks
はModelMap
であるため、タスクは他のタスクを使って定義することができるようになった。
model { tasks { jar { … } dist(Zip) { // `jar`タスクを入力として利用する // この定義はモデル空間で定義されて、model 以外からは変更できない def jar = $.tasks.jar from jar.output into "someDir" } } }
このようなModelMap
のメソッドを利用した定義も可能である。
model { components { all { // すべてのcomponentに適用される定義 } withType(JvmLibrarySpec) { // JvmLibrarySpec型のコンポーネントに適用される定義 } } }
@Managed
が付与された型のオブジェクトに対するプロパティの設定
@Managed
が付与された型のオブジェクトが保持するプロパティはネストしたクロージャーで定義することができるようになった
model { components { myLib { sources { // `myLib.sources`に対する定義 } binaries { // `myLib.binaries`に対する定義 } } } }
@Managed
が付与された型のオブジェクト、あるいはModelMap<T>
のインスタンス、あるいはModelSet<T>
のインスタンス、これらのプロパティにてこの変更が利用できる。ネストされたクロージャーではネストしたルールを定義できないこと、および更にクロージャーがネストした場合にすぐに実行されてしまう(実行を遅らせることができない)ことの二点に注意が必要である。この点については次のGradleのリリースで改善される予定である。
より詳しくはモデルDSLを参考。
スカラー型のプロパティがより簡単になった
モデルDSLにて自動的にスカラー型の自動的な規約がサポートされた。具体的にはString
をスカラー型の値として利用できるように。
enum FailType { FAIL_BUILD, WARNING } @Managed interface CoverageConfiguration { double getMinClassCoverage() void setMinClassCoverage(double minCoverage) double getMinPackageCoverage() void setMinPackageCoverage(double minCoverage) FailType getFailType() void setFailType(FailType failType) File getReportTemplateDir() void setReportTemplateDir(File file) } model { coverage { minClassCoverage = '0.7' // `String`で`double`の値を設定可能 minPackageCoverage = 1L // `long`で`double`の値を設定可能 failType = 'WARNING' // `String`を`Enum`の代わりに利用可能 templateReportDir = 'src/templates/coverage' // `File`オブジェクトをプロジェクトからの相対パスで作成可能 } }
ソフトウェアモデルでのプラグイン開発のサポート
今回のリリースにはプラグイン開発者がソフトウェアモデルを拡張することを可能としている。
LanguageSourceSet
モデルへのサポート
今回のリリースでモデル空間の任意の箇所にソースセット(LanguageSourceSet
のサブタイプ)を追加可能にしている。@Managed
モデル型のプロパティとして、あるいはModelMap<T>
やModelSet<T>
の値(T
の型)として、あるいはモデル要素のトップレベル要素としてLanguageSourceSet
型を追加可能になった。
バイナリーおよびコンポーネント型
BinarySpec
型もしくはComponentSpec
型を継承した型を、メソッドの実装なしに、@Managed
アノテーションを付与することで作成することができるようになった。同様にLibrarySpec
型とApplicationSpec
型も拡張できるようになっている。
@Managed interface SampleLibrarySpec extends LibrarySpec { String getPublicData() void setPublicData(String publicData) } class RegisterComponentRules extends RuleSource { @ComponentType void register(ComponentTypeBuilder<SampleLibrarySpec> builder) { } } apply plugin: RegisterComponentRules model { components { sampleLib(SampleLibrarySpec) { publicData = "public" } } }
バイナリー型、コンポーネント型用内部モデル
@Managed interface MyJarBinarySpecInternal extends JarBinarySpec { String getInternal() void setInternal(String internal) } class CustomPlugin extends RuleSource { @BinaryType public void register(BinaryTypeBuilder<JarBinarySpec> builder) { builder.internalView(MyJarBinarySpecInternal) } @Mutate void mutateInternal(ModelMap<MyJarBinarySpecInternal> binaries) { // ... } } apply plugin: "jvm-component" model { components { myComponent(JvmLibrarySpec) { binaries.withType(MyJarBinarySpecInternal) { binary -> binary.internal = "..." } } } }
// This won't work: model { binaries.withType(MyJarBinarySpecInternal) { // ... } }
管理対象外のバイナリー型およびコンポーネント型のデフォルト実装
デフォルト実装をバイナリー型およびコンポーネント型に与えることが可能になった。
interface MyBaseBinarySpec extends BinarySpec {} class MyBaseBinarySpecImpl extends BaseBinarySpec implements MyBaseBinarySpec {} class BasePlugin extends RuleSource { @ComponentType public void registerMyBaseBinarySpec(ComponentTypeBuilder<MyBaseBinarySpec> builder) { builder.defaultImplementation(MyBaseBinarySpecImpl.class); } } @Managed interface MyCustomBinarySpec extends BaseBinarySpec { // Add some further managed properties } class CustomPlugin extends RuleSource { @ComponentType public void registerMyCustomBinarySpec(ComponentTypeBuilder<MyCustomBinarySpec> builder) { // No default implementation required } }
管理対象外のバイナリー型、コンポーネント型用内部モデル
/** * Documented public type exposed by the plugin */ interface MyBinarySpec extends BinarySpec { // Functionality exposed to the public } // Undocumented internal type used by the plugin itself only interface MyBinarySpecInternal extends MyBinarySpec { String getInternalData(); void setInternalData(String internalData); } class MyBinarySpecImpl implements MyBinarySpecInternal { private String internalData; String getInternalData() { return internalData; } void setInternalData(String internalData) { this.internalData = internalData; } } class MyBinarySpecPlugin extends RuleSource { @BinaryType public void registerMyBinarySpec(BinaryTypeBuilder<MyBinarySpec> builder) { builder.defaultImplementation(MyBinarySpecImpl.class); builder.internalView(MyBinarySpecInternal.class); } }
修正されたイシュー
- (GRADLE-3027)https://issues.gradle.org/browse/GRADLE-3027 - Gradleがivyのコードの挙動によりハングアップしてしまう
- (GRADLE-3330)https://issues.gradle.org/browse/GRADLE-3330 - 複数のコンフィギュレーション解決に失敗する
- (GRADLE-3354)https://issues.gradle.org/browse/GRADLE-3354 - WIndowsでコンティニュアスビルドするとディレクトリーに対してもロックファイルを作ってしまう
- (GRADLE-3357)https://issues.gradle.org/browse/GRADLE-3357 - ネイティブビルドでヘッダーファイルが変更されたのにビルドされない
- (GRADLE-3362)https://issues.gradle.org/browse/GRADLE-3362 - アーカイブ名が使われている場合、アーティファクトが生成されない
- (GRADLE-3365)https://issues.gradle.org/browse/GRADLE-3365 - Playプラグインでネストされたディレクトリーが反映されない
- (GRADLE-3366)https://issues.gradle.org/browse/GRADLE-3366 - プロジェクトの依存性定義でexcludeがある場合に、依存性の情報がpomにうまく反映されない
- (GRADLE-3367)https://issues.gradle.org/browse/GRADLE-3367 - Gradleが --parallelとともに起動されるとハングアップしてしまうことがある
- (GRADLE-3368)https://issues.gradle.org/browse/GRADLE-3368 -
CachingPatternSpecFactory
がメモリーを使いまくる - (GRADLE-3373)https://issues.gradle.org/browse/GRADLE-3373 - モデルDSLでクロージャーの後に
$.path
が使えない
問題が発生する可能性のある修正
テストキットの実行時クラスパス
コンパイルに用いるヘッダーファイル
DSLのモデル空間の変更
ソフトウェアモデルの修正
Javaソフトウェアモデルの修正
ネイティブモデルの修正
既知の問題
- (GRADLE-3390)https://issues.gradle.org/browse/GRADLE-3390 - モジュールの置き換えがメタデータに反映されない
- (GRADLE-3383)https://issues.gradle.org/browse/GRADLE-3383 - ヘッダーファイルの検出に関する不具合
- (GRADLE-3369)https://issues.gradle.org/browse/GRADLE-3369 -
FileTreeElement
のメソッドgetSize
とgetLastModified
の挙動が一貫性がない