Merge pull request #29 from alexarchambault/develop

Last developments
This commit is contained in:
Alexandre Archambault 2015-06-18 19:23:08 +02:00
commit e23281af2c
5 changed files with 53 additions and 48 deletions

View File

@ -10,18 +10,28 @@ import scalaz.concurrent.Task
import scala.scalajs.js
import js.Dynamic.{global => g}
import scala.scalajs.js.timers._
object Remote {
def encodeURIComponent(s: String): String =
g.encodeURIComponent(s).asInstanceOf[String]
lazy val jsonpAvailable = js.isUndefined(g.jsonp)
lazy val jsonpAvailable = !js.isUndefined(g.jsonp)
def proxiedJsonp(url: String)(implicit executionContext: ExecutionContext): Future[String] =
if (url.contains("{")) Future.successful("") // jsonp callback never gets executed in this case (empty response)
else {
/** Available if we're running on node, and package xhr2 is installed */
lazy val xhr = g.require("xhr2")
def xhrReq() =
js.Dynamic.newInstance(xhr)().asInstanceOf[XMLHttpRequest]
// FIXME url is put between quotes in the YQL query, which could sometimes require some extra encoding
def fetchTimeout(target: String, p: Promise[_]) =
setTimeout(5000) {
if (!p.isCompleted) {
p.failure(new Exception(s"Timeout when fetching $target"))
}
}
def proxiedJsonp(url: String)(implicit executionContext: ExecutionContext): Future[String] = {
val url0 =
"https://query.yahooapis.com/v1/public/yql?q=select%20*%20from%20xml%20where%20url%3D%22" +
encodeURIComponent(url) +
@ -29,9 +39,7 @@ object Remote {
val p = Promise[String]()
// FIXME Promise may not be always completed in case of failure
g.jsonp(url0, (res: js.Dynamic) => {
g.jsonp(url0, (res: js.Dynamic) => if (!p.isCompleted) {
val success = !js.isUndefined(res) && !js.isUndefined(res.results)
if (success)
p.success(res.results.asInstanceOf[js.Array[String]].mkString("\n"))
@ -39,27 +47,26 @@ object Remote {
p.failure(new Exception(s"Fetching $url ($url0)"))
})
fetchTimeout(s"$url ($url0)", p)
p.future
}
def get(url: String)(implicit executionContext: ExecutionContext): Future[Either[String, Xml.Node]] =
if (jsonpAvailable) {
// Assume we're running on node, and that node package xhr2 is installed
val xhr = g.require("xhr2")
val p = Promise[Either[String, Xml.Node]]()
val req = js.Dynamic.newInstance(xhr)().asInstanceOf[XMLHttpRequest]
val f = { _: Event =>
p.success(compatibility.xmlParse(req.responseText))
}
req.onload = f
req.open("GET", url)
req.send()
p.future
} else {
if (jsonpAvailable)
proxiedJsonp(url).map(compatibility.xmlParse)
else {
val p = Promise[Either[String, Xml.Node]]()
val xhrReq0 = xhrReq()
val f = { _: Event =>
p.success(compatibility.xmlParse(xhrReq0.responseText))
}
xhrReq0.onload = f
xhrReq0.open("GET", url)
xhrReq0.send()
fetchTimeout(url, p)
p.future
}
}
@ -76,18 +83,19 @@ case class Remote(base: String, logger: Option[Logger] = None) extends Repositor
version: String,
cachePolicy: CachePolicy): EitherT[Task, String, Project] = {
val relPath =
val relPath = {
module.organization.split('.').toSeq ++ Seq(
module.name,
version,
s"${module.name}-$version.pom"
)
} .map(Remote.encodeURIComponent)
val url = base + relPath.mkString("/")
EitherT(Task{ implicit ec =>
logger.foreach(_.fetching(url))
Remote.get(url).map{ eitherXml =>
Remote.get(url).recover{case e: Exception => Left(e.getMessage)}.map{ eitherXml =>
logger.foreach(_.fetched(url))
for {
xml <- \/.fromEither(eitherXml)

View File

@ -1,5 +1,14 @@
package coursier.core
/**
* Identify a "module".
*
* During resolution, all dependencies having the same module
* will be given the same version, if there are no version conflicts
* between them.
*
* Ivy attributes would land here, if support for Ivy is added.
*/
case class Module(organization: String,
name: String) {
@ -12,6 +21,12 @@ case class Module(organization: String,
sealed abstract class Scope(val name: String)
/**
* Dependencies with the same @module will typically see their @version-s merged.
*
* The remaining fields are left untouched, some being transitively
* propagated (exclusions, optional, in particular).
*/
case class Dependency(module: Module,
version: String,
scope: Scope,

View File

@ -1,18 +0,0 @@
<!DOCTYPE html>
<html>
<head>
<title>Dependency resolution with Coursier</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
</head>
<body style="margin: 0px">
<div>
<canvas style="display: block" id="canvas" width="255" height="255"/>
</div>
<script type="text/javascript" src="../web-opt.js"></script>
<script>
example.ScalaJSExample().main();
</script>
</body>
</html>

View File

@ -103,13 +103,13 @@ class Backend($: BackendScope[Unit, State]) {
val logger: Logger = new Logger {
def fetched(url: String) = {
println(s"Fetching $url")
$.modState(s => s.copy(log = s"Fetching $url" +: s.log))
}
def fetching(url: String) = {
println(s"Fetched $url")
$.modState(s => s.copy(log = s"Fetched $url" +: s.log))
}
def fetching(url: String) = {
println(s"Fetching $url")
$.modState(s => s.copy(log = s"Fetching $url" +: s.log))
}
def other(url: String, msg: String) = {
println(s"$url: $msg")
$.modState(s => s.copy(log = s"$url: $msg" +: s.log))