読者です 読者をやめる 読者になる 読者になる

一角獣は夜に啼く

ただの日記です。

思ってることとか考えたこととか適当に書きます。 まじめな話は 「ひだまりソケットは壊れない」 に書いています。

UTF-8 の build.gradle を使う Windows ユーザーにこれ以上悲しい思いをさせたくない!!

プログラミング

上の記事の一番下で書いたのだけど、Gradle のビルドファイルはシステムのデフォルトエンコーディングで読み込まれるようになっている。 なので、UTF-8 で書かれた build.gradle を Windows (日本語環境の場合デフォルトファイルエンコーディングShift_JIS の亜種) で使うと悲しいことになる。

Gradle は JVM 上で動いているので、システムのデフォルトファイルエンコーディングは 「-Dfile.encoding」 オプションで変更できたりする *1 し、冒頭に書いた記事中でも 「-Dfile.encoding=UTF-8」 を使って対応できる、というようなことを書いた。

書いてから気づいたのだけど、「-Dfile.encoding=UTF-8」 でデフォルトファイルエンコーディングを変更すると、System.outSystem.err からコンソール出力される際のエンコーディングUTF-8 になってしまう。 なので、ビルドファイルの読み込み時はよくても、実行時の出力が (コンソール上で見ると) 結局文字化けしてしまう。 悲しい。 悲しすぎる。

それと同じ問題は Gradle のフォーラムにも書かれているのだけど、そこでは 「コンソールのエンコーディングを変更する」 という糞みたいな方法が使われて、それで話題が終わっていた。 悲しい。

これ以上悲しい思いをしないために / させないために

ビルドファイルの文字エンコーディングを指定できるようにするのがいいのかなぁ、と思ったりしてる。 どうやって指定できるようにするのがいいのか悩んだりしたけど、ビルドファイルのファイル名を指定できるのと同じようにビルドファイルのエンコーディングも指定できるようにするのが良さそうな気がした。

で、とりあえず Gradle に変更を加えてみた。

次のコマンドを実行してビルドできる。

git clone --branch feature/build_file_encoding/proposal https://github.com/nobuoka/gradle.git
cd gradle
./gradlew --daemon build -x test -x integTest

ビルドしたら build/distributions/gradle-1.11-201XXXXXXXXXXX+0000-bin.zip というようなファイル名の ZIP ができるはずなので、それを展開したら、ビルドファイルの文字エンコーディングを指定できる Gradle コマンドを使用できる。

使い方

settings.gradle に次のように書くことで、プロジェクトのビルドファイルのエンコーディングを指定できる。

rootProject.buildFileEncoding = "UTF-8"

これで良さそう?

思いついたことを実装してみただけで、これでいいのかどうか (他にいい方法があるんじゃないか) わかんないので、文字エンコーディングの指定方法について見識のある人がいたら意見してもらいたい気分。

まあでも悪くない気もするのでこれで Gradle のコミュニティに提案してみるのがいいかなー。

さらに追記: 結局ビルドスクリプトUTF-8 固定になりました

上のように提案したけど 「ビルドスクリプトUTF-8 固定の方がよいだろう」 的な話になって、結局 Gradle 2.0 でビルドスクリプトUTF-8 とみなされるように変更された。

Gradle now assumes that all Gradle scripts are encoded using UTF-8. Previously, Gradle assumed the system encoding. This change affects all build scripts, settings scripts and init scripts.

Gradle 2.0 Release Notes

まだ Android Gradle plugin の方が Gradle 2.0 に対応してないはずなので Android アプリのビルドは試してないけれど、普通のビルドスクリプトUTF-8 で書いて Windows 上で実行させたところ、ちゃんと UTF-8 として解釈してくれてたので Android アプリのビルドでもちゃんと使えるだろうと思われる。

大変めでたい。

*1:これって JVM の仕様で決まってるわけではなくて、JVM の実装次第? よくわかってない。