2011-09-16 57 views
10

我想讓SBT創建一個文件併爲特定的階段編寫項目的運行時完整類路徑(scala,managed和unmanaged libs,項目類)(在這種情況下,僅適用於compile) 。用SBT的類路徑創建腳本​​

我想複製我的東西與Maven一樣,使用maven-antrun-plugin

<build> 
    <plugins> 
    <plugin> 
     <groupId>org.apache.maven.plugins</groupId> 
     <artifactId>maven-antrun-plugin</artifactId> 
     <version>1.6</version> 
     <executions> 
     <execution> 
      <id>generate-runner</id> 
      <phase>package</phase> 
      <configuration> 
      <target> 
       <property name="runtime_classpath" refid="maven.runtime.classpath" /> 
       <property name="runtime_entrypoint" value="com.biasedbit.webserver.Bootstrap" /> 

       <echo file="../../bin/run-server.sh" append="false">#!/bin/sh 
java -classpath ${runtime_classpath} ${runtime_entrypoint} $$* 
       </echo> 
      </target> 
      </configuration> 
      <goals> 
      <goal>run</goal> 
      </goals> 
     </execution> 
     </executions> 
    </plugin> 
    </plugins> 
</build> 

我怎樣才能做到這一點與SBT?

回答

11

David的答案中的基本原理是正確的。有一些小的方法可以改進。 Java啓動器可以直接使用,因爲Scala庫包含在類路徑中。如果只有一個定義,sbt可以自動檢測主類。 sbt也有一些方法可以使文件更容易處理,例如sbt.IO中的實用方法。

TaskKey[File]("mkrun") <<= (baseDirectory, fullClasspath in Runtime, mainClass in Runtime) map { (base, cp, main) => 
    val template = """#!/bin/sh 
java -classpath "%s" %s "[email protected]" 
""" 
    val mainStr = main getOrElse error("No main class specified") 
    val contents = template.format(cp.files.absString, mainStr) 
    val out = base/"../../bin/run-server.sh" 
    IO.write(out, contents) 
    out.setExecutable(true) 
    out 
} 

這可以直接進入您的build.sbt。另外,在project/Build.scala分別定義鍵,把它:

import sbt._ 
import Keys._ 

object MyBuild extends Build { 
    val mkrun = TaskKey[File]("mkrun") 
    lazy val proj = Project("demo", file(".")) settings(
    mkrun <<= ... same argument as above ... 
) 
} 
3

您可以創建一個任務來創建一個文件來啓動應用程序。 @Kipton巴羅斯在How do I run an sbt main class from the shell as normal command-line program?登載:

val MkUnixlauncher = config("mkunixlauncher") extend(Compile) 
    val mkunixlauncher = TaskKey[Unit]("mkunixlauncher") 
    val mkunixlauncherTask = mkunixlauncher <<= (target, fullClasspath in Runtime) map { (target, cp) => 
    def writeFile(file: File, str: String) { 
     val writer = new PrintWriter(file) 
     writer.println(str) 
     writer.close() 
    } 
    val cpString = cp.map(_.data).mkString(System.getProperty("path.separator")) 
    val runtime_entrypoint = "com.biasedbit.webserver.Bootstrap" 
    val launchString = """ 
CLASSPATH="%s" 
scala -usejavacp -Djava.class.path="${CLASSPATH}" %s "[email protected]" 
""".format(cpString, entrypoint) 
    val targetFile = (target/"run-server.sh").asFile 
    writeFile(targetFile, launchString) 
    targetFile.setExecutable(true) 
    } 

這將創建一個名爲具有類路徑設置正確運行應用程序的目標目錄run-server.sh文件。將mkunixlauncherTask添加到Build.scala(或build.sbt)中的生成設置中,然後可以通過「mkunixlauncher」命令創建該腳本。

調整味道。

2

剛剛發現SBT啓動腳本插件:https://github.com/typesafehub/xsbt-start-script-plugin

這個插件可以讓你生成一個腳本目標/啓動一個 項目。該腳本將運行「就地」項目(無需首先構建軟件包 )。

目標/啓動腳本與sbt運行類似,但不依賴於 SBT。 sbt run不推薦用於生產用途,因爲SBT本身在內存中保留 。目標/開始旨在運行 生產中的應用程序。

該插件添加了一個生成目標/開始的任務啓動腳本。它 也添加了一個階段任務,別名到開始腳本任務。