2011-09-16 14 views
10

Me gustaría que SBT creara un archivo y escribiera el classpath completo del tiempo de ejecución del proyecto (scala, libretas administradas y no administradas, clases de proyectos) para una etapa particular (en este caso, solo para compile) .Crear secuencia de comandos con classpath desde SBT

Estoy tratando de replicar algo que hice con Maven, utilizando el 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> 

¿Cómo puedo hacer esto con SBT?

Respuesta

11

Los fundamentos son correctos en la respuesta de David. Hay algunas formas pequeñas en que se puede mejorar. El iniciador de Java se puede usar directamente porque la biblioteca de Scala está incluida en el classpath. sbt puede autodetectar la clase principal si solo hay una definida. sbt también tiene algunos métodos que pueden facilitar el trabajo con archivos, como los métodos de utilidad en 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 
} 

Esto puede ir en su build.sbt directamente. Por otra parte, definir la clave por separado y ponerlo en 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 ... 
) 
} 
3

Puede crear una tarea para crear un archivo para iniciar la aplicación. @Kipton Barros ha publicado esto en How do I run an sbt main class from the shell as normal command-line program?:

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) 
    } 

Esto crea un archivo llamado run-server.sh en su directorio objetivo que tiene la ruta de clase configurar adecuadamente para ejecutar la aplicación. Agregue mkunixlauncherTask a sus ajustes de construcción en Build.scala (o build.sbt) y luego puede dar el comando "mkunixlauncher" para crear el script.

Ajuste al gusto.

2

Acaba de ser descubierto el plugin SBT script de inicio: https://github.com/typesafehub/xsbt-start-script-plugin:

Este plugin le permite generar un objetivo script/comienzo para un proyecto . La secuencia de comandos ejecutará el proyecto "in situ" (sin tener que crear primero un paquete).

El script de inicio/destino es similar a sbt pero no se basa en SBT. sbt run no se recomienda para uso en producción porque mantiene SBT en sí en la memoria. target/start está destinado a ejecutar una aplicación en la producción .

El complemento agrega una tarea start-script que genera target/start. Es también agrega una tarea de etapa, alias a la tarea de inicio de secuencia de comandos.

Cuestiones relacionadas