Создайте script с помощью 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>

Как я могу сделать это с помощью SBT?

Ответ 1

Основы правильны в ответе Дэвида. Есть несколько способов улучшить его. Панель запуска 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 ...
  )
}

Ответ 2

Вы можете создать задачу для создания файла для запуска приложения. @Kipton Barros опубликовал это в Как запустить основной класс sbt из оболочки в качестве обычной командной строки?:

  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" создать script.

Настройтесь по вкусу.

Ответ 3

Только что открыл плагин sbt start script: https://github.com/typesafehub/xsbt-start-script-plugin:

Этот плагин позволяет вам сгенерировать script цель/старт для проект. script будет запускать проект "на месте" (без необходимости сначала создайте пакет).

Цель/старт script аналогичен запуску sbt, но он не полагается на SBT. sbt run не рекомендуется для использования в производстве, поскольку он сохраняет SBT сам по себе. target/start предназначен для запуска приложения в производство.

Плагин добавляет задачу start- script, которая генерирует target/start. Это также добавляет сценическую задачу, сглаженную к задаче start-script.