SkinnyFrameworkのIntelliJ向け設定


概要

SkinnyFrameworkでは標準でIntelliJのプロジェクト化コマンド(skinny idea)が用意されていますが、実際にIntelliJでビルドしたりテストを実行するには幾つかの設定をしておく必要があります。
以下では、その設定内容をまとめます。

最初にポイントをまとめると以下の通りです。

  1. IntelliJのプロジェクト管理ファイルをgitの管理外にする
  2. sbtビルド設定にIntelliJの管理除外ファイル/モジュールを明記
  3. ScalaTestのデフォルト設定に環境変数を設定する

git管理外設定

.gitignoreファイルで用意されるIntelliJ用設定をコメントインします

.gitignore
 .scala_dependencies

 # IntelliJ IDEA settings
-#.idea
-#*.iml
+.idea
+*.iml

 # building
 target

sbtビルド設定

初期のままだと全プロジェクトと全ファイルがIntelliJの管理下になりますが、それだと不要なものが多くてファイル検索などでノイズになってしまいます。
そのため、sbt-ideaプラグイン設定のideaExcludeFoldersで管理除外ディレクトリを、ideaIgnoreModuleで管理除外モジュールを指定します。

project/Build.scala
@@ -7,6 +7,7 @@ import com.earldouglas.xsbtwebplugin.PluginKeys._
 import com.earldouglas.xsbtwebplugin.WebPlugin._
 import ScalateKeys._
 import scala.language.postfixOps
+import org.sbtidea.SbtIdeaPlugin._

 object SkinnyAppBuild extends Build {

@@ -58,7 +59,12 @@ lazy val baseSettings = 
     incOptions := incOptions.value.withNameHashing(true),
     logBuffered in Test := false,
     javaOptions in Test ++= Seq("-Dskinny.env=test"),
-    scalacOptions ++= Seq("-unchecked", "-deprecation", "-feature")
+    scalacOptions ++= Seq("-unchecked", "-deprecation", "-feature"),
+
+    ideaExcludeFolders := Seq(
+      ".idea", ".idea_modules",
+      "db", "target", "task/target", "build", "standalone-build"
+    )
   )

   lazy val scalatePrecompileSettings = baseSettings ++ scalateSettings ++ Seq(
@@ -90,7 +96,8 @@
   )
   lazy val precompileDev = Project(id = "precompileDev", base = file("."),
     settings = devBaseSettings ++ scalatePrecompileSettings ++ Seq(
-      target := baseDirectory.value / "target" / "precompile-dev"
+      target := baseDirectory.value / "target" / "precompile-dev",
+      ideaIgnoreModule := true
     )
   )

@@ -118,13 +125,15 @@
   )
   lazy val build = Project(id = "build", base = file("build"),
     settings = packagingBaseSettings ++ Seq(
-      name := appName
+      name := appName,
+      ideaIgnoreModule := true
     )
   )
   lazy val standaloneBuild = Project(id = "standalone-build", base = file("standalone-build"),
     settings = packagingBaseSettings ++ Seq(
       name := appName + "-standalone",
-      libraryDependencies += "org.skinny-framework" %% "skinny-standalone" % skinnyVersion
+      libraryDependencies += "org.skinny-framework" %% "skinny-standalone" % skinnyVersion,
+      ideaIgnoreModule := true
     ) ++ jettyOrbitHack
   )

特にprecompileDevを管理外にしておかないとビルド時に以下のようなエラーが発生してしまいます。

Error:scalac: Output path /Users/dev/skinny1.1.1/project/target/idea-test-classes is shared between: Module 'dev-build' tests, Module 'precompileDev-build' tests
Output path /Users/dev/skinny1.1.1/project/target/idea-classes is shared between: Module 'dev-build' production, Module 'precompileDev-build' production
Please configure separate output paths to proceed with the compilation.
TIP: you can use Project Artifacts to combine compiled classes if needed.

devとprecompileDevが同じディレクトリに対するプロジェクトであるため、それぞれのプロジェクトのビルドプロジェクト(dev-buildとprecompileDev-build)のターゲットディレクトリが同じになってしまうのが問題のようです。

ScalaTestのデフォルト設定

IntelliJ内でのテスト実行は、skinnyコマンドやsbtコマンドでの実行とは別物なのでBuild.scalaの設定が効きません。
そのため、javaOptionsで設定しているskinny.env環境変数を別途設定する必要があります。

設定する場所は、メニューの[Run]-[Edit Configurations...]で開く以下のダイアログです。
左側のツリーから[Defaults]-[Scala Test]を選び、[VM parameters]に"-Dskinny.env=test"を記述します。

ちなみに、この設定は.idea/workspace.xmlファイル内の以下箇所に記録されています。
もし、skinny ideaコマンドを再実行するときに.ideaフォルダを消した場合は再度設定が必要です。

idea/workspace.xml
    <configuration default="true" type="ScalaTestRunConfiguration" factoryName="ScalaTest">
      <module name="" />
      <setting name="path" value="" />
      <setting name="package" value="" />
      <setting name="vmparams" value="-Dskinny.env=test" />
      <setting name="params" value="" />
      <setting name="workingDirectory" value="file://$PROJECT_DIR$" />
      <setting name="searchForTest" value="Across module dependencies" />
      <setting name="testName" value="" />
      <setting name="testKind" value="Class" />
      <setting name="showProgressMessages" value="true" />
      <method />
    </configuration>