10
13

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

そのAnt→Gradle移行、もうちょい工数積んだ方がいいですよ

Posted at

ビルドスクリプトがAntで書かれたレガシーなプロジェクトをGradle移行しようとして工数が見積もりより大幅に膨らんだ話。

  • Ant 1.8.2
  • Gradle 2.9

GradleのAnt互換な作りは素晴らしい

Gradle ドキュメントが詳しいが、GradleはAntとの親和性が非常に高い。

例えば既存のAntビルドスクリプトがこんな感じであったとき

build.xml
<project>
    <target name="compile">
      <javac srcdir="src" destdir="classes" includeantruntime="false"/>
    </target>
</project>

Gradleのビルドスクリプトにただ一行、

build.gradle
ant.importBuild 'build.xml'

と書いてあげれば、GradleタスクとしてAntターゲットを取り込むことができる。
取り込んであげたタスクは、普通にGradleタスクとして実行が可能。

Shell
$ ant compile
Buildfile: /path/to/build.xml

compile:

BUILD SUCCESSFUL
Total time: 0 seconds

$ gradle compile
:compile

BUILD SUCCESSFUL

痒いところにも手が届く

もしもGradle側の既存タスクと名前が被ってしまう場合も心配無用。Antターゲットの名前を変更してインポートできます。

build.gradle
ant.importBuild('build.xml') {
  antTaskName -> "ant.${antTaskName}".toString()
}
Shell
$ gradle ant.compile
:ant.compile

BUILD SUCCESSFUL

cf. http://mrhaki.blogspot.jp/2014/12/gradle-goodness-rename-ant-task-names.html

この辺でGradle大好き人間一丁あがり。

これなら簡単に移行できるねーって言ってたら

スクリプトをGradleに書き換える作業は後でやるとして、ひとまずGradleからAntを呼び出す形なら簡単だねと言ってました。当初は。

ant.importBuildを駆使して実際にスクリプトを書いてみたところ、以下の問題が。

  • basedirが無視される
  • プロパティの継承で仕様が異なる

basedirが無視される

GradleスクリプトをAntスクリプトと別の場所に置く要件があった場合、つまりAntのbasedirと、GradleのprojectDirが異なる場合、
スクリプトが意図通りに動きません。

ありがちなんですが、既存プロジェクトは複数のAntスクリプトをバッチファイルやシェルスクリプトでこねくり回してビルドしてました。
はじめは単純だったんでしょうけど、時を経るごとにAnt同士やスクリプトどうしの依存関係がぐちゃぐちゃに。

そのためかbasedirの指定が必須な作りになっており、そのままインポートできない、と。

似たことで困っている人はいて、曰くUnresolvedなバグとのこと。

プロパティの継承で仕様が異なる

仕方ないのでbasedir必須な既存のスクリプトを書き換えて、Gradleからでもインポートできるように変更しました。でもそこで章題の問題が顕在化。

Antは変数の上書きはせず、先勝ちことで知られています。
また、あるAntスクリプト内でantタスクを使い、別のAntスクリプトを呼び出す場合、プロパティを引き継ぐか否かをinheritAll属性で制御できます。

既存のプロジェクトには、以下のケースが混在していました。

  1. バッチファイルから、プロパティを-D指定してAntスクリプトを呼びだす
  2. Antスクリプトから複数のAntスクリプトを呼びだす(inheritAll="true")
  3. Antスクリプトから複数のAntスクリプトを呼びだす(inheritAll="false")

Gradleスクリプトで単純にant.importBuildをすると、2.のケースになってしまいます。

結局この問題も、既存のAntスクリプトに手を加えずに解決することはできませんでした。

そして

どうにか既存の資産を使おうと試行錯誤しましたが、全部Gradleスクリプトに書き換えた方がスッキリするという結論に。

既存のビルドスクリプトがぐちゃぐちゃしているなら、ant.importBuildを使わずに全部Gradleスクリプトで書き換える前提で見積もりましょう。

10
13
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
10
13

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?