mirror of https://github.com/sbt/sbt.git
Extract local, remote, and git BuildLoader.Resolver from ResolveUnit
This commit is contained in:
parent
dd51dbb999
commit
942427bfa3
|
|
@ -5,6 +5,7 @@ package sbt
|
||||||
|
|
||||||
import java.io.File
|
import java.io.File
|
||||||
import java.net.URI
|
import java.net.URI
|
||||||
|
import BuildLoader.ResolveInfo
|
||||||
import compiler.{Eval, EvalImports}
|
import compiler.{Eval, EvalImports}
|
||||||
import complete.DefaultParsers.validID
|
import complete.DefaultParsers.validID
|
||||||
import Compiler.Compilers
|
import Compiler.Compilers
|
||||||
|
|
@ -38,78 +39,25 @@ object Build
|
||||||
}
|
}
|
||||||
object RetrieveUnit
|
object RetrieveUnit
|
||||||
{
|
{
|
||||||
def apply(tempDir: File, base: URI): Option[() => File] =
|
def apply(info: ResolveInfo): Option[() => File] =
|
||||||
{
|
{
|
||||||
lazy val tmp = temporary(tempDir, base)
|
info.uri match {
|
||||||
base.getScheme match
|
case Scheme("git") => Resolvers.git(info)
|
||||||
{
|
case Path(path) if path.endsWith(".git") => Resolvers.git(info)
|
||||||
case "git" => gitApply(tmp, base)
|
case Scheme("http") | Scheme("https") | Scheme("ftp") => Resolvers.remote(info)
|
||||||
case _ if isGitPath(base.getPath) => gitApply(tmp, base)
|
case Scheme("file") => Resolvers.local(info)
|
||||||
case "http" | "https" => Some { () => downloadAndExtract(base, tmp); tmp }
|
|
||||||
case "file" =>
|
|
||||||
val f = new File(base)
|
|
||||||
if(f.isDirectory)
|
|
||||||
{
|
|
||||||
val finalDir = if (!f.canWrite) retrieveRODir(f, tmp) else f
|
|
||||||
Some(() => finalDir)
|
|
||||||
}
|
|
||||||
else None
|
|
||||||
case _ => None
|
case _ => None
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
def isGitPath(path: String) = path.endsWith(".git")
|
|
||||||
private[this] def gitApply(tmp: File, base: URI) = Some { () => gitRetrieve(base, tmp); tmp }
|
|
||||||
def retrieveRODir(base: File, tempDir: File): File =
|
|
||||||
{
|
|
||||||
if (!tempDir.exists)
|
|
||||||
{
|
|
||||||
try {
|
|
||||||
IO.copyDirectory(base, tempDir)
|
|
||||||
} catch {
|
|
||||||
case e =>
|
|
||||||
IO.delete(tempDir)
|
|
||||||
throw e
|
|
||||||
}
|
|
||||||
}
|
|
||||||
tempDir
|
|
||||||
}
|
|
||||||
def downloadAndExtract(base: URI, tempDir: File): Unit = if(!tempDir.exists) IO.unzipURL(base.toURL, tempDir)
|
|
||||||
def temporary(tempDir: File, uri: URI): File = new File(tempDir, Hash.halve(hash(uri)))
|
|
||||||
def hash(uri: URI): String = Hash.toHex(Hash(uri.toASCIIString))
|
|
||||||
|
|
||||||
import Process._
|
object Scheme
|
||||||
def gitRetrieve(base: URI, tempDir: File): Unit =
|
|
||||||
if(!tempDir.exists)
|
|
||||||
{
|
{
|
||||||
try {
|
def unapply(uri: URI) = Option(uri.getScheme)
|
||||||
IO.createDirectory(tempDir)
|
|
||||||
gitClone(dropFragment(base), tempDir)
|
|
||||||
Option(base.getFragment) foreach { branch => gitCheckout(tempDir, branch) }
|
|
||||||
} catch {
|
|
||||||
case e => IO.delete(tempDir)
|
|
||||||
throw e
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
def dropFragment(base: URI): URI = if(base.getFragment eq null) base else new URI(base.getScheme, base.getSchemeSpecificPart, null)
|
|
||||||
|
|
||||||
def gitClone(base: URI, tempDir: File): Unit =
|
object Path
|
||||||
git("clone" :: dropFragment(base).toASCIIString :: tempDir.getAbsolutePath :: Nil, tempDir) ;
|
|
||||||
def gitCheckout(tempDir: File, branch: String): Unit =
|
|
||||||
git("checkout" :: "-q" :: branch :: Nil, tempDir)
|
|
||||||
def git(args: List[String], cwd: File): Unit =
|
|
||||||
if(isWindowsShell) run(List("cmd", "/c", "git") ++ args, cwd)
|
|
||||||
else run("git" +: args, cwd)
|
|
||||||
lazy val isWindowsShell = {
|
|
||||||
val ostype = System.getenv("OSTYPE")
|
|
||||||
val isCygwin = ostype != null && ostype.toLowerCase.contains("cygwin")
|
|
||||||
val isWindows = System.getProperty("os.name", "").toLowerCase.contains("windows")
|
|
||||||
isWindows && !isCygwin
|
|
||||||
}
|
|
||||||
def run(command: List[String], cwd: File): Unit =
|
|
||||||
{
|
{
|
||||||
val result = Process(command, cwd) ! ;
|
def unapply(uri: URI) = Option(uri.getPath)
|
||||||
if(result != 0)
|
|
||||||
error("Nonzero exit code (" + result + "): " + command.mkString(" "))
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
object EvaluateConfigurations
|
object EvaluateConfigurations
|
||||||
|
|
|
||||||
|
|
@ -231,7 +231,7 @@ object Load
|
||||||
def load(file: File, s: State, config: LoadBuildConfiguration): PartBuild =
|
def load(file: File, s: State, config: LoadBuildConfiguration): PartBuild =
|
||||||
{
|
{
|
||||||
val fail = (uri: URI) => error("Invalid build URI (no handler available): " + uri)
|
val fail = (uri: URI) => error("Invalid build URI (no handler available): " + uri)
|
||||||
val resolver = (info: BuildLoader.ResolveInfo) => RetrieveUnit(info.staging, info.uri)
|
val resolver = (info: BuildLoader.ResolveInfo) => RetrieveUnit(info)
|
||||||
val build = (info: BuildLoader.BuildInfo) => Some(() => loadUnit(info.uri, info.base, info.state, info.config))
|
val build = (info: BuildLoader.BuildInfo) => Some(() => loadUnit(info.uri, info.base, info.state, info.config))
|
||||||
val components = BuildLoader.components(resolver, build, full = BuildLoader.componentLoader)
|
val components = BuildLoader.components(resolver, build, full = BuildLoader.componentLoader)
|
||||||
val builtinLoader = BuildLoader(components, fail, s, config)
|
val builtinLoader = BuildLoader(components, fail, s, config)
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,105 @@
|
||||||
|
/* 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) => {
|
||||||
|
def retrieveRODir(at: File, into: File) = creates(into) {IO.copyDirectory(at, into)}
|
||||||
|
|
||||||
|
val uri = info.uri
|
||||||
|
val dir = new File(uri)
|
||||||
|
if (dir.isDirectory) {
|
||||||
|
Some {
|
||||||
|
() =>
|
||||||
|
if (dir.canWrite)
|
||||||
|
dir
|
||||||
|
else
|
||||||
|
retrieveRODir(at = dir, into = uniqueSubdirectoryFor(uri, in = info.staging))
|
||||||
|
}
|
||||||
|
} else None
|
||||||
|
}
|
||||||
|
|
||||||
|
val remote: Resolver = (info: ResolveInfo) => {
|
||||||
|
def downloadAndExtract(at: URI, into: File) = creates(into) {IO.unzipURL(at.toURL, into)}
|
||||||
|
|
||||||
|
val uri = info.uri
|
||||||
|
Some {
|
||||||
|
() =>
|
||||||
|
downloadAndExtract(at = uri, into = uniqueSubdirectoryFor(uri, in = info.staging))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
val git: Resolver = (info: ResolveInfo) => {
|
||||||
|
def clone(at: String, into: File)
|
||||||
|
{
|
||||||
|
run(None, "git", "clone", at, into.getAbsolutePath)
|
||||||
|
}
|
||||||
|
|
||||||
|
def checkout(branch: String, in: File)
|
||||||
|
{
|
||||||
|
run(Some(in), "git", "checkout", "-q", branch)
|
||||||
|
}
|
||||||
|
|
||||||
|
def retrieveLocalCopy(at: URI, into: File) =
|
||||||
|
{
|
||||||
|
creates(into) {
|
||||||
|
clone(at.withoutFragment.toASCIIString, into)
|
||||||
|
if (at.hasFragment)
|
||||||
|
checkout(branch = at.getFragment, in = into)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
val uri = info.uri
|
||||||
|
Some {
|
||||||
|
() =>
|
||||||
|
retrieveLocalCopy(at = uri, into = uniqueSubdirectoryFor(uri, in = info.staging))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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(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) =
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
if (!file.exists)
|
||||||
|
f
|
||||||
|
file
|
||||||
|
} catch {
|
||||||
|
case e =>
|
||||||
|
IO.delete(file)
|
||||||
|
throw e
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
def uniqueSubdirectoryFor(uri: URI, in: File) = new File(in, Hash.halfHashString(uri.toASCIIString))
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,23 @@
|
||||||
|
/* sbt -- Simple Build Tool
|
||||||
|
* Copyright 2011 Sanjin Sehic
|
||||||
|
*/
|
||||||
|
|
||||||
|
package sbt
|
||||||
|
|
||||||
|
import java.net.URI
|
||||||
|
|
||||||
|
class RichURI(uri: URI)
|
||||||
|
{
|
||||||
|
def hasFragment = uri.getFragment ne null
|
||||||
|
|
||||||
|
def withoutFragment =
|
||||||
|
if (hasFragment)
|
||||||
|
new URI(uri.getScheme, uri.getSchemeSpecificPart, null)
|
||||||
|
else
|
||||||
|
uri
|
||||||
|
}
|
||||||
|
|
||||||
|
object RichURI
|
||||||
|
{
|
||||||
|
implicit def fromURI(uri: URI) = new RichURI(uri)
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue