sbt で CrossVersion が正しく設定されてない場合に警告を出す

sbt 0.12.x から導入された binary version について tototshiの日記
use CrossVersion.full for unstable Scala by default: sbt/sbt/pull/600

「"Binary Version" という概念は、 2.10.0のMilestoneやRCの間はsbt0.12.x において毎回設定しなければならない項目が増えてしまっただけで、使えない」わけです。

それで、
~/.sbt/build.sbt に ( sbt-extras を使ってる人は、 ~/.sbt/0.12.1/build.sbt などに )

onLoadMessage <<= (crossVersion,scalaVersion,onLoadMessage){ (crossV,scalaV,currentMessage) =>
  if(crossV.isInstanceOf[CrossVersion.Binary] && !CrossVersion.isStable(scalaV))
    println("ここで `crossVersion := CrossVersion.full` とか設定しろって警告だす。もしくはエラー投げてしまう")
  currentMessage
}

と書いておいたほうがいいのではないかなーとふと思いついた。( もっと良い書き方あったら教えて下さい )
sbtには


ホームディレクトリ/.sbt/build.sbt


に設定を書いておけば、グローバルにすべてのプロジェクトに適用できるという機能があるので。


「警告を出すだけ」にしたのは、そのグローバルなbuild.sbtの中で`crossVersion := CrossVersion.full`などと設定してしまうと、
「自分の環境ではCrossVersion.fullなのに、他の人の環境ではCrossVersion.binaryになる」
という状態になり、かえって混乱のもとになるのでやらないほうがいい、という理由。*1

onLoadMessage は、上記の例では実際使ってないのでそのまま元の値返してるだけなので、実は(SettingKeyの型ならば*2 )なんでもいい。


あと、最初に貼った sbt/sbt/pull/600 で議論されてますが

CrossVersion.isStable

の関数自体の実装が 「"-"を含んでいるかどうか?」となっていて。
https://github.com/sbt/sbt/blob/v0.12.1/ivy/CrossVersion.scala#L70
「2.10.0-1とかでたらどーするの?この実装だと2.10.0-1が、Stableじゃないって認識されるよね?」
っていう問題もあります

*1: CrossVersionに限らず、グローバルなbuild.sbtでは、そういうトラブルを避けるためにビルドの本質的な設定に関わるSettingを変えない方がいい。IDEのpluginの依存を追加するなどだけにとどめるべきだと思う

*2:SettingKeyでなくTaskKeyでは、プロジェクトロード時に評価されずに、メッセージが表示されないのでという理由