如何像普通命令行程序一样从 shell 运行 sbt 主类?

发布于 2024-11-30 09:10:21 字数 626 浏览 1 评论 0原文

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

我知道我可以这样做:

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

但这(1)需要永远启动,因为它启动 sbt,(2)导致所有 stdout 和 stderr 转到 stdout,并且(3)导致所有输出都用记录器 [info] 或[错误]。

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

到目前为止,我已经拼凑了自己的脚本来构建类路径,您还可以执行其他一些操作,例如 修改您的项目文件以使 sbt 打印原始类路径,但我觉得必须有更好的方法。

How can I run an sbt app from the shell, so that I can run my app as a normal command-line program (as if run directly via scala but without having to set up an enormous classpath)?

I know I can do:

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

But this (1) takes forever to start because it starts sbt, (2) causes all stdout and stderr to go to stdout, and (3) causes all output to be decorated with a logger [info] or [error].

I looked at https://github.com/harrah/xsbt/wiki/Launcher but it seems too heavyweight, since it downloads dependencies and sets up a new environment and whatnot. I just want to run this app within my existing development environment.

Thus far I've cobbled together my own script to build up a classpath, and you can also do some other things like modify your project file to get sbt to print the raw classpath, but I feel like there must be a better way.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

两相知 2024-12-07 09:10:21

这是我在 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 的类路径,以便于创建嵌入式解释器。)

Here's what I have in my SBT (version 0.10) project definition,

  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

The mklauncher task creates a script target/scala-sbt that executes scala with the project classpath already set. It would be nice to have mklauncher executed automatically whenever the classpath changes, but I haven't looked into doing this yet.

(I use the Java classpath, rather than Scala's, for ease of creating embedded interpreters.)

风柔一江水 2024-12-07 09:10:21

start-script SBT 插件现在位于:

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

它需要几个步骤来设置和生成无法在 OS X 上运行的脚本,但这可以如果您在该平台上,很容易修复(见下文)。

设置

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

    a) brew install coreutils

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

    函数readlink() { gradlink "$@"; }

    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 添加启动脚本支持:

    导入com.typesafe.sbt.SbtStartScript

    seq(SbtStartScript.startScriptForClassesSettings: _*)

注意中间的空行语句(SBT 构建文件的必要条件)。

生成启动脚本

然后,每当您想要创建一个脚本来启动您的应用程序(例如 sbt run-main ,但没有 sbt )时,请执行:

$ sbt start-script

Run

target/start mypackage.MyMainClass

The start-script SBT plugin is now at:

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

It requires a few steps to set up and generates scripts that do not work on OS X, but that can be easily fixed if you're on that platform (see below).

Setup

  1. Install greadlink (OS X only):

    a) brew install coreutils

    b) map readlink to the new function (greadlink) by adding these lines to ~/.bashrc:

    function readlink() { greadlink "$@"; }

    export -f readlink`

  2. Add start-script plugin to ~/.sbt/plugins/build.sbt:

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

  3. Add start-script task to current project:

    $ sbt add-start-script-tasks # execute from directory where build.sbt resides

  4. Add start-script support to current build.sbt:

    import com.typesafe.sbt.SbtStartScript

    seq(SbtStartScript.startScriptForClassesSettings: _*)

Note the blank line in between statements (de rigueur for SBT build files).

Generate Start Script

Then, whenever you want to create a script to start your app like sbt run-main, but without sbt, execute:

$ sbt start-script

Run

target/start mypackage.MyMainClass
寄居者 2024-12-07 09:10:21

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

我认为您可能需要的是 sbt-onejar 插件SBT Native Packager 插件

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

SBT Native Packager< /strong> 的“目标是能够将使用 SBT 构建的 Scala 软件捆绑到本机打包系统,例如 deb、rpm、homebrew、msi。”

Time flies by and a lot have changed since the other answers. It's currently SBT 0.13.6 time.

I think what you may need is the sbt-onejar plugin or the SBT Native Packager plugin.

sbt-onejar "is a simple-build-tool plugin for building a single executable JAR containing all your code and dependencies as nested JARs."

SBT Native Packager's "goal is to be able to bundle up Scala software built with SBT for native packaging systems, like deb, rpm, homebrew, msi."

梦醒灬来后我 2024-12-07 09:10:21

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

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

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

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

Just discovered the sbt start script plugin: https://github.com/typesafehub/xsbt-start-script-plugin:

This plugin allows you to generate a script target/start for a
project. The script will run the project "in-place" (without having to
build a package first).

The target/start script is similar to sbt run but it doesn't rely on
SBT. sbt run is not recommended for production use because it keeps
SBT itself in-memory. target/start is intended to run an app in
production.

The plugin adds a task start-script which generates target/start. It
also adds a stage task, aliased to the start-script task.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文