Scala で g8 や conscript みたいなコマンドを作る

Scala でちょっとしたコマンドラインツールを作る場合

  • scalaコマンドで実行
  • sbt run
  • assemblyしてjava -jar
  • xsbt-start-script-plugin

とかが考えられるけれど、

  • sbt-launch.jar をランチャにする

という方法もあります。一番シェルコマンドっぽく使えるんじゃないかな。
ちょっとめんどくさいけど、テンプレでも用意してればよし。
conscript, g8, picture-show とかもこれで動いてます。


以下、作り方。

私の今の心境を反映した、onaka_hetta コマンドを作ります。

build.sbt

name := "onaka_hetta"

organization := "com.github.tototoshi"

version := "0.1-SNAPSHOT"

scalaVersion := "2.9.1"

libraryDependencies += "org.scala-sbt" %% "launcher-interface" % "0.11.3" % "provided"

resolvers <+= sbtResolver


ポイントは libraryDependencies です。
organization とかもサボらず書いてください。

xsbti.AppMain を継承したクラスを実装する。

つまりいつもの main とは別にエントリポイントを用意します。

// OnakaHetta.scala
package com.github.tototoshi.onaka_hetta

class OnakaHetta extends xsbti.AppMain {

  def run(config: xsbti.AppConfiguration): Exit =
    new Exit(OnakaHetta.run(config.arguments))

}

class Exit(val code: Int) extends xsbti.Exit


run メソッドの中でメインのロジックを呼び出します。

object OnakaHetta {

  def run(args: Array[String]): Int = {
    println("おなかへった")
    0
  }

}

よくわかんなかったら giter8 でも見てパクればよいのではないかな。
https://github.com/n8han/giter8/blob/master/app/src/main/scala/giter8.scala


できたら publish-local しましょう。

launchconfig を書く

sbtで起動するのに必要です。
sbtがこれを見て、jarを探しにいって、コマンド実行してくれるんですね。たぶん。

// ~/onaka_hetta/launchconfig
[app]
  version: 0.1-SNAPSHOT
  org: com.github.tototoshi
  name: onaka_hetta
  class: com.github.tototoshi.onaka_hetta.OnakaHetta
[scala]
  version: 2.9.1
[repositories]
  local


※追記
これだとコマンドを実行したディレクトリで起動するので project/ ディレクトリができちゃうみたい。うざいので

[boot]
  directory: ディレクトリ

追記で起動ディレクトリを変更。

launch するためのスクリプトを書く。

// ~/bin/onaka_hetta
#!/bin/sh
java -Dfile.encoding=UTF-8 -jar `dirname $0`/sbt-launch-0.11.jar @/Users/t-takahashi/onaka_hetta/launchconfig "$@"

@つきでlaunchconfigを指定します。

実行

 $  onaka_hetta
 おなかへった

感想

おなかへりました。