Skip to content
This repository
Fetching contributors…

Cannot retrieve contributors at this time

file 127 lines (122 sloc) 4.844 kb
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127
/* sbt -- Simple Build Tool
* Copyright 2009, 2010 Mark Harrah
*/
package xsbt.boot

import Pre._
import java.io.{File, FileInputStream, InputStreamReader}
import java.net.{MalformedURLException, URI, URL}
import java.util.regex.Pattern
import scala.collection.immutable.List
import annotation.tailrec

object Configuration
{
final val SysPropPrefix = "-D"
def parse(file: URL, baseDirectory: File) = Using( new InputStreamReader(file.openStream, "utf8") )( (new ConfigurationParser).apply )
@tailrec def find(args: List[String], baseDirectory: File): (URL, List[String]) =
args match
{
case head :: tail if head.startsWith("@") => (directConfiguration(head.substring(1), baseDirectory), tail)
case head :: tail if head.startsWith(SysPropPrefix) =>
setProperty(head stripPrefix SysPropPrefix)
find(tail, baseDirectory)
case _ =>
val propertyConfigured = System.getProperty("sbt.boot.properties")
val url = if(propertyConfigured == null) configurationOnClasspath else configurationFromFile(propertyConfigured, baseDirectory)
(url , args)
}
def setProperty(head: String)
{
val keyValue = head.split("=",2)
if(keyValue.length != 2)
System.err.println("Warning: invalid system property '" + head + "'")
else
System.setProperty(keyValue(0), keyValue(1))
}
def configurationOnClasspath: URL =
{
val paths = resourcePaths(guessSbtVersion)
paths.iterator.map(getClass.getResource).find(neNull) getOrElse
( multiPartError("Could not finder sbt launch configuration. Searched classpath for:", paths))
}
def directConfiguration(path: String, baseDirectory: File): URL =
{
try { new URL(path) }
catch { case _: MalformedURLException => configurationFromFile(path, baseDirectory) }
}
def configurationFromFile(path: String, baseDirectory: File): URL =
{
def resolve(against: URI): Option[URL] =
{
val resolved = against.resolve(path)
val exists = try { (new File(resolved)).exists } catch { case _: IllegalArgumentException => false }
if(exists) Some(resolved.toURL) else None
}
val against = resolveAgainst(baseDirectory)
// use Iterators so that resolution occurs lazily, for performance
val resolving = against.iterator.flatMap(e => resolve(e).toList.iterator)
if(!resolving.hasNext) multiPartError("Could not find configuration file '" + path + "'. Searched:", against)
resolving.next()
}
def multiPartError[T](firstLine: String, lines: List[T]) = error( (firstLine :: lines).mkString("\n\t") )

def UnspecifiedVersionPart = "Unspecified"
def DefaultVersionPart = "Default"
def DefaultBuildProperties = "project/build.properties"
def SbtVersionProperty = "sbt.version"
val ConfigurationName = "sbt.boot.properties"
val JarBasePath = "/sbt/"
def userConfigurationPath = "/" + ConfigurationName
def defaultConfigurationPath = JarBasePath + ConfigurationName
val baseResourcePaths: List[String] = userConfigurationPath :: defaultConfigurationPath :: Nil
def resourcePaths(sbtVersion: Option[String]): List[String] =
versionParts(sbtVersion) flatMap { part =>
baseResourcePaths map { base =>
base + part
}
}
def fallbackParts: List[String] = "" :: Nil
def versionParts(version: Option[String]): List[String] =
version match {
case None => UnspecifiedVersionPart :: fallbackParts
case Some(v) => versionParts(v)
}
def versionParts(version: String): List[String] =
{
val pattern = Pattern.compile("""(\d+)\.(\d+)\.(\d+)(-.*)?""")
val m = pattern.matcher(version)
if(m.matches())
subPartsIndices map {_.map(m.group).filter(neNull).mkString(".") }
else
DefaultVersionPart :: fallbackParts
}
private[this] def subPartsIndices =
(1 :: 2 :: Nil) ::
(1 :: 2 :: 3 :: Nil) ::
(1 :: 2 :: 3 :: 4 :: Nil) ::
(Nil) ::
Nil
// the location of project/build.properties and the name of the property within that file
// that configures the sbt version is configured in sbt.boot.properties.
// We have to hard code them here in order to use them to determine the location of sbt.boot.properties itself
def guessSbtVersion: Option[String] =
{
val props = ResolveValues.readProperties(new File(DefaultBuildProperties))
Option(props.getProperty(SbtVersionProperty))
}

def resolveAgainst(baseDirectory: File): List[URI] = (baseDirectory toURI) :: (new File(System.getProperty("user.home")) toURI) ::
toDirectory(classLocation(getClass).toURI) :: Nil

def classLocation(cl: Class[_]): URL =
{
val codeSource = cl.getProtectionDomain.getCodeSource
if(codeSource == null) error("No class location for " + cl)
else codeSource.getLocation
}
def toDirectory(uri: URI): URI =
try
{
val file = new File(uri)
val newFile = if(file.isFile) file.getParentFile else file
newFile.toURI
}
catch { case _: Exception => uri }
private[this] def neNull: AnyRef => Boolean = _ ne null
}
Something went wrong with that request. Please try again.