1. sbtを使用したコマンドラインアプリケーションの作成

sbtを使用したコマンドラインアプリケーションの作成 

sbtには、コマンドラインアプリケーションの作成に使用できるいくつかのコンポーネントがあります。ここでは、ランチャーコマンドシステムの2つを主なものとして説明します。

ランチャーのページで説明されているように、起動されたアプリケーションはxsbti.AppMainインターフェースを実装し、ユーザーがランチャーに渡してアプリケーションを実行するための簡単な構成ファイルを定義します。コマンドシステムを使用するには、アプリケーションはStateインスタンスを設定します。このインスタンスは、コマンド実装と実行する初期コマンドを提供します。以下に最小限のhello worldの例を示します。

Hello Worldの例 

この例では、3つのファイルがあります

  1. build.sbt
  2. Main.scala
  3. hello.build.properties

この例を試すには

  1. 最初の2つのファイルを新しいディレクトリに配置します
  2. sbtのシェルで、そのディレクトリでpublishLocalを実行します
  3. アプリケーションを実行するには、sbt @path/to/hello.build.propertiesを実行します。

sbt自体と同様に、コマンドラインからコマンドを指定したり(バッチモード)、プロンプトで実行したり(インタラクティブモード)できます。

ビルド定義: build.sbt 

build.sbtファイルは、標準設定である名前、バージョン、組織を定義する必要があります。sbtコマンドシステムを使用するには、commandモジュールへの依存関係が必要です。タスクシステムを使用するには、task-systemモジュールへの依存関係も追加します。

organization := "org.example"

name := "hello"

version := "0.1-SNAPSHOT"

libraryDependencies += "org.scala-sbt" % "command" % "0.12.0"

アプリケーション: Main.scala 

アプリケーション自体は、xsbti.AppMainを実装することで定義されます。基本的な手順は次のとおりです。

  1. コマンド定義を提供します。これらは、ユーザーが実行できるコマンドです。
  2. 初期コマンドを定義します。これらは、最初に実行されるようにスケジュールされたコマンドです。たとえば、アプリケーションは通常、コマンドラインで指定されたもの(sbtがバッチモードと呼ぶもの)を追加し、コマンドが定義されていない場合は、「shell」コマンドを実行してインタラクティブモードに入ります。
  3. ロギングを設定します。例のデフォルト設定では、ユーザーの操作ごとにログファイルをローテーションし、簡潔なロギングをコンソールに、詳細なロギングをログファイルに送信します。
package org.example

   import sbt._
   import java.io.{File, PrintWriter}

final class Main extends xsbti.AppMain
{
   /** Defines the entry point for the application.
   * The call to `initialState` sets up the application.
   * The call to runLogged starts command processing. */
   def run(configuration: xsbti.AppConfiguration): xsbti.MainResult =
      MainLoop.runLogged( initialState(configuration) )

   /** Sets up the application by constructing an initial State instance with the supported commands
   * and initial commands to run.  See the State API documentation for details. */
   def initialState(configuration: xsbti.AppConfiguration): State =
   {
      val commandDefinitions = hello +: BasicCommands.allBasicCommands
      val commandsToRun = Hello +: "iflast shell" +: configuration.arguments.map(_.trim)
      State( configuration, commandDefinitions, Set.empty, None, commandsToRun, State.newHistory,
         AttributeMap.empty, initialGlobalLogging, State.Continue )
   }

   // defines an example command.  see the Commands page for details.
   val Hello = "hello"
   val hello = Command.command(Hello) { s =>
      s.log.info("Hello!")
      s
   }

   /** Configures logging to log to a temporary backing file as well as to the console. 
   * An application would need to do more here to customize the logging level and
   * provide access to the backing file (like sbt's last command and logLevel setting).*/
   def initialGlobalLogging: GlobalLogging =
      GlobalLogging.initial(MainLogging.globalDefault _, File.createTempFile("hello", "log"))
}

ランチャー構成ファイル: hello.build.properties 

ランチャーは、アプリケーションを取得して実行するために構成ファイルが必要です。hello.build.properties

[scala]
  version: 2.9.1

[app]
  org: org.example
  name: hello
  version: 0.1-SNAPSHOT
  class: org.example.Main
  components: xsbti
  cross-versioned: true

[repositories]
  local
  maven-central
  typesafe-ivy-releases: https://repo.typesafe.com/typesafe/ivy-releases/, [organization]/[module]/[revision]/[type]s/[artifact](-[classifier]).[ext]