Создайте 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.