mirror of https://github.com/sbt/sbt.git
154 lines
3.3 KiB
Scala
154 lines
3.3 KiB
Scala
/* sbt -- Simple Build Tool
|
|
* Copyright 2011 Sanjin Sehic
|
|
*/
|
|
|
|
package sbt
|
|
|
|
import java.io.File
|
|
import java.net.URI
|
|
|
|
import BuildLoader.ResolveInfo
|
|
import RichURI.fromURI
|
|
|
|
object Resolvers
|
|
{
|
|
type Resolver = BuildLoader.Resolver
|
|
|
|
val local: Resolver = (info: ResolveInfo) => {
|
|
val uri = info.uri
|
|
val from = new File(uri)
|
|
val to = uniqueSubdirectoryFor(uri, in = info.staging)
|
|
|
|
if (from.isDirectory) Some {() => if(from.canWrite) from else creates(to) {IO.copyDirectory(from, to)}}
|
|
else None
|
|
}
|
|
|
|
val remote: Resolver = (info: ResolveInfo) => {
|
|
val url = info.uri.toURL
|
|
val to = uniqueSubdirectoryFor(info.uri, in = info.staging)
|
|
|
|
Some {() => creates(to) {IO.unzipURL(url, to)}}
|
|
}
|
|
|
|
val subversion: Resolver = (info: ResolveInfo) => {
|
|
def normalized(uri: URI) = uri.copy(scheme = "svn")
|
|
|
|
val uri = info.uri.withoutMarkerScheme
|
|
val localCopy = uniqueSubdirectoryFor(normalized(uri), in = info.staging)
|
|
val from = uri.withoutFragment.toASCIIString
|
|
val to = localCopy.getAbsolutePath
|
|
|
|
if (uri.hasFragment) {
|
|
val revision = uri.getFragment
|
|
Some {
|
|
() => creates(localCopy) {
|
|
run("svn", "checkout", "-q", "-r", revision, from, to)
|
|
}
|
|
}
|
|
} else
|
|
Some {
|
|
() => creates(localCopy) {
|
|
run("svn", "checkout", "-q", from, to)
|
|
}
|
|
}
|
|
}
|
|
|
|
val mercurial: Resolver = new DistributedVCS
|
|
{
|
|
override val scheme = "hg"
|
|
|
|
override def clone(from: String, to: File)
|
|
{
|
|
run("hg", "clone", "-q", from, to.getAbsolutePath)
|
|
}
|
|
|
|
override def checkout(branch: String, in: File)
|
|
{
|
|
run(Some(in), "hg", "checkout", "-q", branch)
|
|
}
|
|
}.toResolver
|
|
|
|
val git: Resolver = new DistributedVCS
|
|
{
|
|
override val scheme = "git"
|
|
|
|
override def clone(from: String, to: File)
|
|
{
|
|
run("git", "clone", from, to.getAbsolutePath)
|
|
}
|
|
|
|
override def checkout(branch: String, in: File)
|
|
{
|
|
run(Some(in), "git", "checkout", "-q", branch)
|
|
}
|
|
}.toResolver
|
|
|
|
abstract class DistributedVCS
|
|
{
|
|
val scheme: String
|
|
|
|
def clone(from: String, to: File)
|
|
|
|
def checkout(branch: String, in: File)
|
|
|
|
def toResolver: Resolver = (info: ResolveInfo) => {
|
|
val uri = info.uri.withoutMarkerScheme
|
|
val localCopy = uniqueSubdirectoryFor(normalized(uri), in = info.staging)
|
|
val from = uri.withoutFragment.toASCIIString
|
|
|
|
if (uri.hasFragment) {
|
|
val branch = uri.getFragment
|
|
Some {
|
|
() => creates(localCopy) {
|
|
clone(from, to = localCopy)
|
|
checkout(branch, in = localCopy)
|
|
}
|
|
}
|
|
} else Some {() => creates(localCopy) {clone(from, to = localCopy)}}
|
|
}
|
|
|
|
private def normalized(uri: URI) = uri.copy(scheme = scheme)
|
|
}
|
|
|
|
private lazy val onWindows = {
|
|
val os = System.getenv("OSTYPE")
|
|
val isCygwin = (os != null) && os.toLowerCase.contains("cygwin")
|
|
val isWindows = System.getProperty("os.name", "").toLowerCase.contains("windows")
|
|
isWindows && !isCygwin
|
|
}
|
|
|
|
def run(command: String*)
|
|
{
|
|
run(None, command: _*)
|
|
}
|
|
|
|
def run(cwd: Option[File], command: String*)
|
|
{
|
|
val result = Process(
|
|
if (onWindows) "cmd" +: "/c" +: command
|
|
else command,
|
|
cwd
|
|
) !;
|
|
if (result != 0)
|
|
error("Nonzero exit code (" + result + "): " + command.mkString(" "))
|
|
}
|
|
|
|
def creates(file: File)(f: => Unit) =
|
|
{
|
|
if (!file.exists)
|
|
try {
|
|
f
|
|
} catch {
|
|
case e =>
|
|
IO.delete(file)
|
|
throw e
|
|
}
|
|
file
|
|
}
|
|
|
|
def uniqueSubdirectoryFor(uri: URI, in: File) = {
|
|
in.mkdirs()
|
|
new File(in, Hash.halfHashString(uri.normalize.toASCIIString))
|
|
}
|
|
}
|