如何从shell运行sbt主类作为普通的命令行程序?

时间:2011-08-20 22:06:08

标签: scala classpath sbt

如何从shell运行sbt应用程序,以便我可以将我的应用程序作为正常的命令行程序运行(就像直接通过scala运行,但无需设置庞大的类路径)?

我知道我能做到:

echo hello | sbt 'run-main com.foo.MyMain3 arg1 arg2' > out.txt

但是这个(1)需要永远启动因为它启动sbt,(2)导致所有stdout和stderr转到stdout,并且(3)导致所有输出都用logger [info]或[error]进行修饰

我看了https://github.com/harrah/xsbt/wiki/Launcher,但它看起来太重了,因为它下载了依赖项并设置了一个新环境等等。我只想在现有的开发环境中运行这个应用程序。

到目前为止,我已经拼凑了我自己的脚本来构建一个类路径,你还可以做一些其他的事情,比如modify your project file to get sbt to print the raw classpath,但我觉得必须有更好的方法。

4 个答案:

答案 0 :(得分:17)

这是我在SBT(版本0.10)项目定义中的内容,

  val Mklauncher = config("mklauncher") extend(Compile)
  val mklauncher = TaskKey[Unit]("mklauncher")
  val mklauncherTask = mklauncher <<= (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(":")
    val launchString = """
CLASSPATH="%s"
scala -usejavacp -Djava.class.path="${CLASSPATH}" "$@"
""".format(cpString)
    val targetFile = (target / "scala-sbt").asFile
    writeFile(targetFile, launchString)
    targetFile.setExecutable(true)
  }

  ... // remember to add mklauncherTask to Project Settings

mklauncher任务创建一个脚本target/scala-sbt,该脚本在已设置项目类路径的情况下执行scala。每当类路径发生变化时自动执行mklauncher会很高兴,但我还没有考虑这样做。

(我使用Java类路径,而不是Scala,以便于创建嵌入式解释器。)

答案 1 :(得分:9)

start-script SBT plugin现在位于:

https://github.com/sbt/sbt-start-script

设置和生成不适用于OS X的脚本需要几个步骤,但如果您在该平台上,则可以轻松修复(见下文)。

设置

  1. 安装greadlink(仅限OS X):

    a)brew install coreutils

    b)通过将这些行添加到〜/ .bashrc来将readlink映射到新函数( g readlink):

    function readlink(){greadlink“$ @”; }

    export -f readlink`

  2. 将启动脚本插件添加到〜/ .sbt / plugins / build.sbt:

    addSbtPlugin(“com.typesafe.sbt”%“sbt-start-script”%“0.8.0”)

  3. 将启动脚本任务添加到当前项目:

    $ sbt add-start-script-tasks#从build.sbt所在的目录执行

  4. 为当前build.sbt添加启动脚本支持:

    import com.typesafe.sbt.SbtStartScript

    seq(SbtStartScript.startScriptForClassesSettings:_ *)

  5. 注意语句之间的空白行(对于SBT构建文件而言是必需的)。

    生成开始脚本

    然后,每当你想创建一个脚本来启动你的应用程序,如sbt run-main,但没有sbt,执行:

    $ sbt start-script
    

    运行

    target/start mypackage.MyMainClass
    

答案 2 :(得分:9)

自其他答案以来,时间过得很快,而且发生了很多变化。目前是SBT 0.13.6时间。

我认为您可能需要的是the sbt-onejar pluginthe SBT Native Packager plugin

sbt-onejar “是一个简单的构建工具插件,用于构建包含所有代码和依赖项作为嵌套JAR的单个可执行JAR。”

SBT Native Packager “目标是能够捆绑使用SBT构建的Scala软件,用于本机打包系统,如deb,rpm,homebrew,msi。”

答案 3 :(得分:2)

刚刚发现了sbt启动脚本插件:https://github.com/typesafehub/xsbt-start-script-plugin

  

此插件允许您为a生成脚本目标/开始   项目。该脚本将“就地”运行项目(无需)   首先构建一个包。)

     

目标/启动脚本类似于sbt run,但它不依赖于   SBT。 sbt run不建议用于生产用途,因为它保留   SBT本身就在内存中。 target / start旨在运行应用程序   生产

     

该插件添加了一个生成目标/开始的任务启动脚本。它   还添加了一个阶段任务,别名为启动脚本任务。