2012年4月7日土曜日

Eclipse + Scala + sbt + Specs2 な環境を試してみた

水、木とJavaOneに行かれた皆様、どうでしたか?
ええ、私は会社にいましたよ…

http://togetter.com/li/283845 とか見て、とても楽しそうで羨ましい…って指咥えて仕事してました。

まあ指咥えてってのは嘘ですし、仕事し…



というわけで私も唐突にScala触ってみました。

その時のメモ

私の環境
Mac OSX 10.7.3
Eclipse 3.7.2
Scala IDE for Eclipse 2.0.0
sbt 0.11.2

まあ殆どこちらのブログ参考にしたんですけどね
http://blog.weblade.in/archives/1905

まずはEclipseを用意します
http://www.eclipse.org/downloads/

次にScala IDE for Eclipse というプラグインを入れます
http://scala-ide.org/
一応 For 2.9.x の安定版のリンクを選びました

続いてEclipse.iniを編集します。
http://www.assembla.com/wiki/show/scala-ide/Setup とか参考にして適当に
とりあえずヒープサイズだけでっかくしておけばいいと思います。たぶん。

Macの場合
Eclipse.app/Contents/MacOS/eclipse.ini
のはず

sbt(simple build tool)入れます。
homebrewで入れました
$ brew install sbt
多分今なら0.11.2が入ります

brewでインストールしたsbtを見ると
#!/bin/sh
# /usr/local/Cellar/sbt/0.11.2/bin/sbt
test -f ~/.sbtconfig && . ~/.sbtconfig
exec java -Xmx512M ${SBT_OPTS} -jar /usr/local/Cellar/sbt/0.11.2/libexec/sbt-launch.jar "$@"
とあるので
https://gist.github.com/1139288 を参考にSBT_OPTSを環境変数にでも追加すればいい気がします

export SBT_OPTS="-Dfile.encoding=UTF8 -Xmx1536M -Xss1M -XX:+CMSClassUnloadingEnabled -XX:MaxPermSize=256m"
特にエンコードは指定しておかないと、macのターミナルでsbt testとか実行した時に日本語表示が化けて悲しい事になりました。


さてここまでやったらあとはbuild.sbtを作成するのですが、eclipseプロジェクトを作っては消し…ってのを結構やるので
とりあえず最低限のプロジェクトが作れるようなshスクリプトでも作ってみました。
本当にいいのかどうかは正直sbtどころかmavenだってマトモに使ったことないのでさっぱりですけど。
内容は件名のようにSpecs2が使えればいいんじゃね?的な最低限のやつです。


※なおgiter8という素晴らしいものがあります。自分でスクリプト書いている場合じゃねえぜ!


#!/bin/sh
mkdir $1
cat << _EOS_ >> $1/build.sbt
name := "$1"
version := "1.0"
scalaVersion := "2.9.2"
libraryDependencies ++= Seq(
"org.specs2" %% "specs2" % "latest.integration" % "test",
"org.specs2" %% "specs2-scalaz-core" % "latest.integration" % "test",
"junit" % "junit" % "latest.integration" % "test",
"org.hamcrest" % "hamcrest-all" % "latest.integration" % "test",
"org.pegdown" % "pegdown" % "latest.integration" % "test"
)
// Read here for optional dependencies:
// http://etorreborre.github.com/specs2/guide/org.specs2.guide.Runners.html#Dependencies
testOptions in Test += Tests.Argument("junitxml", "html", "console")
resolvers ++= Seq(
"snapshots" at "http://oss.sonatype.org/content/repositories/snapshots"
)
_EOS_
cd $1
sbt update
mkdir project/plugins
cat << _EOS_ >> project/plugins/build.sbt
resolvers += Classpaths.typesafeResolver
addSbtPlugin("com.typesafe.sbteclipse" % "sbteclipse-plugin" % "latest.integration")
resolvers += "Sonatype snapshots" at "http://oss.sonatype.org/content/repositories/snapshots/"
addSbtPlugin("com.github.mpeltonen" % "sbt-idea" % "1.2.0-SNAPSHOT")
_EOS_
sbt update
sbt eclipse
# ideaの場合 なぜかsrcディレクトリ以下が作られないので
#sbt gen-idea
#mkdir -p src/main/java
#mkdir -p src/main/scala
#mkdir -p src/test/java
#mkdir -p src/test/scala
cat << _EOS_ >> .hgignore
syntax: regexp
^.idea/
^.idea_modules/
^out/
^target/
.*/target/
.*\.class$
_EOS_


上記スクリプト(hogeと仮定)をテキトーに保存して実行権限与えたとしてあとは

$ cd てきとーな場所
$ hoge hello-scala

とかやれば、eclipseのプロジェクトがhello-scala というディレクトリの下に作られます。
追加したいライブラリ等があるのなら、hello-scala/build.sbt の libraryDependencies に追加した後 hello-scala直下で

$ sbt reload update eclipse

でOK


出来上がったプロジェクトをEclipseでImportします。

するとこんな感じ?



さて、肝心のSpecs2ですが選定した理由は、「会社でRailsだしRspecだしなんとなく…」というだけです。
あとで見たらScalaTestでもSpec的なやつあったしw
これでなければならないということもなければ、むしろ組み合わせて使うことも可能なようです。
http://etorreborre.github.com/specs2/guide/org.specs2.guide.SpecStructure.html#ScalaCheck+values

Eclipse上で実行するときの注意点は以下のように対象クラスにJUnitRunnerを付け忘れないことだけみたいです。
http://scala-ide.org/docs/user/testingframeworks.html
import org.specs2.mutable._
import org.specs2.runner.JUnitRunner // 忘れないこと
import org.junit.runner.RunWith // 忘れないこと

@RunWith(classOf[JUnitRunner]) // 忘れないこと
class HelloSpecs2 extends Specification {

あとはフツーに走らせてやれば動きます。

もちろん sbt test で動かしてもテストは動きます。素晴らしい。(当たり前か)


おまけ

build.sbtに以下記述を追加するとSpecs実行結果がJUnit形式のxmlが出力されます
http://etorreborre.github.com/specs2/guide/org.specs2.guide.Runners.html#Simple+build+tool
testOptions in Test += Tests.Argument("junitxml")
// 贅沢にも全部出すのなら
testOptions in Test += Tests.Argument("junitxml", "html", "console")

出力先はxmlは target/test-reports 以下に
htmlは target/specs2-reports 以下 のようです。

なおhtml出力の場合は
"org.pegdown" % "pegdown" % "1.0.2"
みたいな感じでpegdownというものを依存関係に足さないと怒られます。

xmlを出力すればJenkinsさんとかもウマウマできますし便利ですね。


scala ide で設定できるformatterはscalariformというのを使っているようです。
http://mdr.github.com/scalariform/
で、sbtscalariform なんてものがあります。
https://github.com/typesafehub/sbtscalariform

入れるとコンパイル時にフォーマットしてくれるっぽいですね。素敵。
Eclipseを使わなくてもフォーマットはみんな統一できる、というかビルドサーバ(が、あればだけど)が勝手に整形してくれる
みたいなことができるんですよね、きっと。


さて、あとは使う人間のscala力を高めればいいのかな(白目