mirror of https://github.com/sbt/sbt.git
Can specify in launcher configuration extra paths to go on the application classpath:
[app] ... resources: conf, resources
This commit is contained in:
parent
239e9198c7
commit
3b28156f84
|
|
@ -60,7 +60,8 @@ class ConfigurationParser extends NotNull
|
|||
val (b, m) = id(map, name, default.toString)
|
||||
(toBoolean(b), m)
|
||||
}
|
||||
def toFile(path: String): File = new File(path.replace('/', File.separatorChar))// if the path is relative, it will be resolve by Launch later
|
||||
def toFiles(paths: List[String]): List[File] = paths.map(toFile)
|
||||
def toFile(path: String): File = new File(path.replace('/', File.separatorChar))// if the path is relative, it will be resolved by Launch later
|
||||
def file(map: LabelMap, name: String, default: File): (File, LabelMap) =
|
||||
(getOrNone(map, name).map(toFile).getOrElse(default), map - name)
|
||||
|
||||
|
|
@ -82,7 +83,7 @@ class ConfigurationParser extends NotNull
|
|||
{
|
||||
case (Nil, newM) => (Search.none, newM)
|
||||
case (tpe :: Nil, newM) => (Search(tpe, List(defaultPath)), newM)
|
||||
case (tpe :: paths, newM) => (Search(tpe, paths.map(toFile)), newM)
|
||||
case (tpe :: paths, newM) => (Search(tpe, toFiles(paths)), newM)
|
||||
}
|
||||
|
||||
def getApplication(m: LabelMap): Application =
|
||||
|
|
@ -93,8 +94,10 @@ class ConfigurationParser extends NotNull
|
|||
val (main, m4) = id(m3, "class", "xsbt.Main")
|
||||
val (components, m5) = ids(m4, "components", List("default"))
|
||||
val (crossVersioned, m6) = id(m5, "cross-versioned", "true")
|
||||
check(m6, "label")
|
||||
new Application(org, name, rev, main, components, toBoolean(crossVersioned))
|
||||
val (resources, m7) = ids(m6, "resources", Nil)
|
||||
check(m7, "label")
|
||||
val classpathExtra = toFiles(resources).toArray[File]
|
||||
new Application(org, name, rev, main, components, toBoolean(crossVersioned), classpathExtra)
|
||||
}
|
||||
def getRepositories(m: LabelMap): List[Repository] =
|
||||
{
|
||||
|
|
|
|||
|
|
@ -96,6 +96,7 @@ class Launch(val bootDirectory: File, repositories: List[Repository]) extends xs
|
|||
def target = UpdateScala
|
||||
def failLabel = "Scala " + version
|
||||
def lockFile = updateLockFile
|
||||
def extraClasspath = Array[File]()
|
||||
|
||||
def app(id: xsbti.ApplicationID): xsbti.AppProvider = new AppProvider(id)
|
||||
|
||||
|
|
@ -110,7 +111,8 @@ class Launch(val bootDirectory: File, repositories: List[Repository]) extends xs
|
|||
def target = new UpdateApp(Application(id))
|
||||
def failLabel = id.name + " " + id.version
|
||||
def lockFile = updateLockFile
|
||||
def mainClasspath = classpath
|
||||
def mainClasspath = classpath ++ extraClasspath
|
||||
def extraClasspath = id.classpathExtra
|
||||
|
||||
lazy val mainClass: Class[T] forSome { type T <: xsbti.AppMain } =
|
||||
{
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ final case class LaunchConfiguration(scalaVersion: Version, app: Application, re
|
|||
def withApp(app: Application) = LaunchConfiguration(scalaVersion, app, repositories, boot, logging, appProperties)
|
||||
def withAppVersion(newAppVersion: String) = LaunchConfiguration(scalaVersion, app.withVersion(new Version.Explicit(newAppVersion)), repositories, boot, logging, appProperties)
|
||||
def withVersions(newScalaVersion: String, newAppVersion: String) = LaunchConfiguration(new Version.Explicit(newScalaVersion), app.withVersion(new Version.Explicit(newAppVersion)), repositories, boot, logging, appProperties)
|
||||
def map(f: File => File) = LaunchConfiguration(scalaVersion, app, repositories, boot.map(f), logging, appProperties)
|
||||
def map(f: File => File) = LaunchConfiguration(scalaVersion, app.map(f), repositories, boot.map(f), logging, appProperties)
|
||||
}
|
||||
|
||||
sealed trait Version extends NotNull
|
||||
|
|
@ -32,20 +32,21 @@ object Version
|
|||
def get(v: Version) = v match { case e: Version.Explicit => e.value; case _ => throw new BootException("Unresolved version: " + v) }
|
||||
}
|
||||
|
||||
final case class Application(groupID: String, name: String, version: Version, main: String, components: List[String], crossVersioned: Boolean) extends NotNull
|
||||
final case class Application(groupID: String, name: String, version: Version, main: String, components: List[String], crossVersioned: Boolean, classpathExtra: Array[File]) extends NotNull
|
||||
{
|
||||
def getVersion = Version.get(version)
|
||||
def withVersion(newVersion: Version) = Application(groupID, name, newVersion, main, components, crossVersioned)
|
||||
def toID = AppID(groupID, name, getVersion, main, toArray(components), crossVersioned)
|
||||
def withVersion(newVersion: Version) = Application(groupID, name, newVersion, main, components, crossVersioned, classpathExtra)
|
||||
def toID = AppID(groupID, name, getVersion, main, toArray(components), crossVersioned, classpathExtra)
|
||||
def map(f: File => File) = Application(groupID, name, version, main, components, crossVersioned, classpathExtra.map(f))
|
||||
}
|
||||
final case class AppID(groupID: String, name: String, version: String, mainClass: String, mainComponents: Array[String], crossVersioned: Boolean) extends xsbti.ApplicationID
|
||||
final case class AppID(groupID: String, name: String, version: String, mainClass: String, mainComponents: Array[String], crossVersioned: Boolean, classpathExtra: Array[File]) extends xsbti.ApplicationID
|
||||
|
||||
object Application
|
||||
{
|
||||
def apply(id: xsbti.ApplicationID): Application =
|
||||
{
|
||||
import id._
|
||||
Application(groupID, name, new Version.Explicit(version), mainClass, mainComponents.toList, crossVersioned)
|
||||
Application(groupID, name, new Version.Explicit(version), mainClass, mainComponents.toList, crossVersioned, classpathExtra)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@ trait Provider extends NotNull
|
|||
def configuration: UpdateConfiguration
|
||||
def baseDirectories: List[File]
|
||||
def testLoadClasses: List[String]
|
||||
def extraClasspath: Array[File]
|
||||
def target: UpdateTarget
|
||||
def failLabel: String
|
||||
def parentLoader: ClassLoader
|
||||
|
|
@ -46,8 +47,8 @@ trait Provider extends NotNull
|
|||
}
|
||||
def createLoader =
|
||||
{
|
||||
val jars = classpath
|
||||
(jars, new URLClassLoader(jars.map(_.toURI.toURL), parentLoader) )
|
||||
val fullClasspath = classpath ++ extraClasspath
|
||||
(fullClasspath, new URLClassLoader(Provider.toURLs(fullClasspath), parentLoader) )
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -66,4 +67,5 @@ object Provider
|
|||
def classMissing(c: String) = try { Class.forName(c, false, loader); false } catch { case e: ClassNotFoundException => true }
|
||||
classes.toList.filter(classMissing)
|
||||
}
|
||||
def toURLs(files: Array[File]): Array[URL] = files.map(_.toURI.toURL)
|
||||
}
|
||||
|
|
@ -1,5 +1,7 @@
|
|||
package xsbti;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
public interface ApplicationID
|
||||
{
|
||||
public String groupID();
|
||||
|
|
@ -9,4 +11,7 @@ public interface ApplicationID
|
|||
public String mainClass();
|
||||
public String[] mainComponents();
|
||||
public boolean crossVersioned();
|
||||
|
||||
/** Files to add to the application classpath. */
|
||||
public File[] classpathExtra();
|
||||
}
|
||||
|
|
@ -16,6 +16,8 @@ object ScalaProviderTest extends Specification
|
|||
"ClassLoader for Scala 2.7.3" in { checkScalaLoader("2.7.3") }
|
||||
"ClassLoader for Scala 2.7.4" in { checkScalaLoader("2.7.4") }
|
||||
"ClassLoader for Scala 2.7.5" in { checkScalaLoader("2.7.5") }
|
||||
"ClassLoader for Scala 2.7.6" in { checkScalaLoader("2.7.6") }
|
||||
"ClassLoader for Scala 2.7.7" in { checkScalaLoader("2.7.7") }
|
||||
}
|
||||
|
||||
"Launch" should {
|
||||
|
|
@ -26,16 +28,29 @@ object ScalaProviderTest extends Specification
|
|||
"Successfully load an application from local repository and run it with correct sbt version" in {
|
||||
checkLoad(List(AppVersion), "xsbt.boot.test.AppVersionTest").asInstanceOf[Exit].code must be(0)
|
||||
}
|
||||
"Add extra resources to the classpath" in {
|
||||
checkLoad(testResources, "xsbt.boot.test.ExtraTest", createExtra).asInstanceOf[Exit].code must be(0)
|
||||
}
|
||||
}
|
||||
|
||||
private def checkLoad(arguments: List[String], mainClassName: String): MainResult =
|
||||
def checkLoad(arguments: List[String], mainClassName: String): MainResult =
|
||||
checkLoad(arguments, mainClassName, _ => Array[File]())
|
||||
def checkLoad(arguments: List[String], mainClassName: String, extra: File => Array[File]): MainResult =
|
||||
FileUtilities.withTemporaryDirectory { currentDirectory =>
|
||||
withLauncher { launcher =>
|
||||
Launch.run(launcher)(
|
||||
new RunConfiguration(mapScalaVersion(LaunchTest.getScalaVersion), LaunchTest.testApp(mainClassName).toID, currentDirectory, arguments)
|
||||
new RunConfiguration(mapScalaVersion(LaunchTest.getScalaVersion), LaunchTest.testApp(mainClassName, extra(currentDirectory)).toID, currentDirectory, arguments)
|
||||
)
|
||||
}
|
||||
}
|
||||
private def testResources = List("test-resourceA", "a/b/test-resourceB", "sub/test-resource")
|
||||
private def createExtra(currentDirectory: File) =
|
||||
{
|
||||
val resourceDirectory = new File(currentDirectory, "resources")
|
||||
FileUtilities.createDirectory(resourceDirectory)
|
||||
testResources.foreach(resource => FileUtilities.touch(new File(resourceDirectory, resource.replace('/', File.separatorChar))))
|
||||
Array(resourceDirectory)
|
||||
}
|
||||
private def checkScalaLoader(version: String): Unit = withLauncher( checkLauncher(version, scalaVersionMap(version)) )
|
||||
private def checkLauncher(version: String, versionValue: String)(launcher: Launcher): Unit =
|
||||
{
|
||||
|
|
@ -49,7 +64,8 @@ object ScalaProviderTest extends Specification
|
|||
}
|
||||
object LaunchTest
|
||||
{
|
||||
def testApp(main: String) = Application("org.scala-tools.sbt", "launch-test", new Version.Explicit(AppVersion), main, Nil, false)
|
||||
def testApp(main: String): Application = testApp(main, Array[File]())
|
||||
def testApp(main: String, extra: Array[File]): Application = Application("org.scala-tools.sbt", "launch-test", new Version.Explicit(AppVersion), main, Nil, false, extra)
|
||||
import Repository.Predefined._
|
||||
def testRepositories = List(Local, ScalaToolsReleases, ScalaToolsSnapshots).map(Repository.Predefined.apply)
|
||||
def withLauncher[T](f: xsbti.Launcher => T): T =
|
||||
|
|
@ -59,7 +75,7 @@ object LaunchTest
|
|||
|
||||
def mapScalaVersion(versionNumber: String) = scalaVersionMap.find(_._2 == versionNumber).getOrElse {
|
||||
error("Scala version number " + versionNumber + " from library.properties has no mapping")}._1
|
||||
val scalaVersionMap = Map( ("2.7.2", "2.7.2") ) ++ List("2.7.3", "2.7.4", "2.7.5").map(v => (v, v + ".final"))
|
||||
val scalaVersionMap = Map( ("2.7.2", "2.7.2") ) ++ List("2.7.3", "2.7.4", "2.7.5", "2.7.6", "2.7.7").map(v => (v, v + ".final"))
|
||||
def getScalaVersion: String = getScalaVersion(getClass.getClassLoader)
|
||||
def getScalaVersion(loader: ClassLoader): String =
|
||||
{
|
||||
|
|
@ -71,6 +87,7 @@ object LaunchTest
|
|||
lazy val AppVersion =
|
||||
{
|
||||
val properties = new java.util.Properties
|
||||
println(getClass.getResource("/xsbt.version.properties"))
|
||||
val propertiesStream = getClass.getResourceAsStream("/xsbt.version.properties")
|
||||
try { properties.load(propertiesStream) } finally { propertiesStream.close() }
|
||||
"test-" + properties.getProperty("version")
|
||||
|
|
@ -99,4 +116,15 @@ package test
|
|||
throw new MainException("app version was " + configuration.provider.id.version + ", expected: " + expected)
|
||||
}
|
||||
}
|
||||
class ExtraTest extends AppMain
|
||||
{
|
||||
def run(configuration: xsbti.AppConfiguration) =
|
||||
{
|
||||
configuration.arguments.foreach { arg =>
|
||||
if(getClass.getClassLoader.getResource(arg) eq null)
|
||||
throw new MainException("Could not find '" + arg + "'")
|
||||
}
|
||||
new Exit(0)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -81,7 +81,7 @@ class XSbt(info: ProjectInfo) extends ParentProject(info)
|
|||
override def packageAction = packageTask(packageTestPaths, outputPath / (testID + "-" + projectID.revision +".jar"), packageOptions).dependsOn(rawTestCompile)
|
||||
override def deliverProjectDependencies = Nil
|
||||
def testID = "launch-test"
|
||||
override def testClasspath = super.testClasspath +++ interfaceSub.compileClasspath
|
||||
override def testClasspath = super.testClasspath +++ interfaceSub.compileClasspath +++ interfaceSub.mainResourcesPath
|
||||
lazy val rawTestCompile = super.testCompileAction dependsOn(interfaceSub.compile)
|
||||
override def testCompileAction = publishLocal dependsOn(rawTestCompile, interfaceSub.publishLocal)
|
||||
}
|
||||
|
|
@ -131,7 +131,9 @@ class XSbt(info: ProjectInfo) extends ParentProject(info)
|
|||
val formatter = new java.text.SimpleDateFormat("yyyyMMdd'T'HHmmss")
|
||||
formatter.setTimeZone(TimeZone.getTimeZone("GMT"))
|
||||
val timestamp = formatter.format(new Date)
|
||||
FileUtilities.write(versionPropertiesPath.asFile, "version=" + version + "\ntimestamp=" + timestamp, log)
|
||||
val content = "version=" + version + "\ntimestamp=" + timestamp
|
||||
log.info("Writing version information to " + versionPropertiesPath + " :\n" + content)
|
||||
FileUtilities.write(versionPropertiesPath.asFile, content, log)
|
||||
}
|
||||
|
||||
override def watchPaths = super.watchPaths +++ apiDefinitionPaths --- sources(generatedBasePath)
|
||||
|
|
|
|||
Loading…
Reference in New Issue