使用SBT中的类路径创建脚本

bia*_*bit 10 scala classpath sbt

我想让SBT创建一个文件并为特定阶段编写项目的运行时完整类路径(scala,托管和非托管库,项目类)(在本例中,仅用于compile).

我试图复制我用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>
Run Code Online (Sandbox Code Playgroud)

我怎么能用SBT做到这一点?

Mar*_*rah 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 "$@"
"""
  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
}
Run Code Online (Sandbox Code Playgroud)

这可以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 ...
  )
}
Run Code Online (Sandbox Code Playgroud)