mirror of https://github.com/sbt/sbt.git
Clean stuff
This commit is contained in:
parent
744e6186d6
commit
2cd1a3b0b1
|
|
@ -6,6 +6,8 @@ import java.net.{ HttpURLConnection, URL, URLConnection }
|
|||
import scala.language.higherKinds
|
||||
|
||||
import scalaz.{ EitherT, Monad }
|
||||
import scalaz.syntax.monad._
|
||||
import scalaz.Scalaz.ToEitherOps
|
||||
|
||||
object FallbackDependenciesRepository {
|
||||
|
||||
|
|
@ -15,12 +17,12 @@ object FallbackDependenciesRepository {
|
|||
// E.g. https://github.com/NetLogo/NetLogo/releases/download/5.3.1/NetLogo.jar
|
||||
// returning 403s. Hence the second attempt below.
|
||||
|
||||
val firstAttemptOpt = url.getProtocol match {
|
||||
case "file" =>
|
||||
Some(new File(url.getPath).exists()) // FIXME Escaping / de-escaping needed here?
|
||||
val protocolSpecificAttemptOpt = {
|
||||
|
||||
case "http" | "https" =>
|
||||
def ifFile: Boolean =
|
||||
new File(url.getPath).exists() // FIXME Escaping / de-escaping needed here?
|
||||
|
||||
def ifHttp: Option[Boolean] = {
|
||||
// HEAD request attempt, adapted from http://stackoverflow.com/questions/22541629/android-how-can-i-make-an-http-head-request/22545275#22545275
|
||||
|
||||
var conn: HttpURLConnection = null
|
||||
|
|
@ -31,34 +33,43 @@ object FallbackDependenciesRepository {
|
|||
conn.setRequestMethod("HEAD")
|
||||
conn.getInputStream.close()
|
||||
Some(true)
|
||||
} catch {
|
||||
case _: FileNotFoundException =>
|
||||
Some(false)
|
||||
case _: IOException => // error other than not found
|
||||
None
|
||||
} finally {
|
||||
}
|
||||
catch {
|
||||
case _: FileNotFoundException => Some(false)
|
||||
case _: IOException => None // error other than not found
|
||||
}
|
||||
finally {
|
||||
if (conn != null)
|
||||
coursier.Cache.closeConn(conn)
|
||||
}
|
||||
case _ =>
|
||||
None
|
||||
}
|
||||
|
||||
url.getProtocol match {
|
||||
case "file" => Some(ifFile)
|
||||
case "http" | "https" => ifHttp
|
||||
case _ => None
|
||||
}
|
||||
}
|
||||
|
||||
firstAttemptOpt.getOrElse {
|
||||
def genericAttempt: Boolean = {
|
||||
var conn: URLConnection = null
|
||||
try {
|
||||
conn = url.openConnection()
|
||||
// NOT setting request type to HEAD here.
|
||||
conn.getInputStream.close()
|
||||
true
|
||||
} catch {
|
||||
case _: IOException =>
|
||||
false
|
||||
} finally {
|
||||
}
|
||||
catch {
|
||||
case _: IOException => false
|
||||
}
|
||||
finally {
|
||||
if (conn != null)
|
||||
coursier.Cache.closeConn(conn)
|
||||
}
|
||||
}
|
||||
|
||||
protocolSpecificAttemptOpt
|
||||
.getOrElse(genericAttempt)
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -67,22 +78,23 @@ final case class FallbackDependenciesRepository(
|
|||
fallbacks: Map[(Module, String), (URL, Boolean)]
|
||||
) extends Repository {
|
||||
|
||||
private val source: Artifact.Source = new Artifact.Source {
|
||||
def artifacts(
|
||||
dependency: Dependency,
|
||||
project: Project,
|
||||
overrideClassifiers: Option[Seq[String]]
|
||||
) =
|
||||
fallbacks.get(dependency.moduleVersion) match {
|
||||
case None => Nil
|
||||
case Some((url, changing)) =>
|
||||
val url0 = url.toString
|
||||
val ext = url0.substring(url0.lastIndexOf('.') + 1)
|
||||
Seq(
|
||||
Artifact(url0, Map.empty, Map.empty, Attributes(ext, ""), changing, None)
|
||||
)
|
||||
}
|
||||
}
|
||||
private val source: Artifact.Source =
|
||||
new Artifact.Source {
|
||||
def artifacts(
|
||||
dependency: Dependency,
|
||||
project: Project,
|
||||
overrideClassifiers: Option[Seq[String]]
|
||||
) =
|
||||
fallbacks
|
||||
.get(dependency.moduleVersion)
|
||||
.toSeq
|
||||
.map {
|
||||
case (url, changing) =>
|
||||
val url0 = url.toString
|
||||
val ext = url0.substring(url0.lastIndexOf('.') + 1)
|
||||
Artifact(url0, Map.empty, Map.empty, Attributes(ext, ""), changing, None)
|
||||
}
|
||||
}
|
||||
|
||||
def find[F[_]](
|
||||
module: Module,
|
||||
|
|
@ -90,25 +102,22 @@ final case class FallbackDependenciesRepository(
|
|||
fetch: Fetch.Content[F]
|
||||
)(implicit
|
||||
F: Monad[F]
|
||||
): EitherT[F, String, (Artifact.Source, Project)] =
|
||||
fallbacks.get((module, version)) match {
|
||||
case None =>
|
||||
EitherT.left(F.point("No fallback URL found"))
|
||||
): EitherT[F, String, (Artifact.Source, Project)] = {
|
||||
|
||||
case Some((url, _)) =>
|
||||
val res = fallbacks
|
||||
.get((module, version))
|
||||
.fold("No fallback URL found".left[(Artifact.Source, Project)]) {
|
||||
case (url, _) =>
|
||||
|
||||
val urlStr = url.toExternalForm
|
||||
val idx = urlStr.lastIndexOf('/')
|
||||
val urlStr = url.toExternalForm
|
||||
val idx = urlStr.lastIndexOf('/')
|
||||
|
||||
if (idx < 0 || urlStr.endsWith("/"))
|
||||
EitherT.left(F.point(s"$url doesn't point to a file"))
|
||||
else {
|
||||
val (dirUrlStr, fileName) = urlStr.splitAt(idx + 1)
|
||||
if (idx < 0 || urlStr.endsWith("/"))
|
||||
s"$url doesn't point to a file".left
|
||||
else {
|
||||
val (dirUrlStr, fileName) = urlStr.splitAt(idx + 1)
|
||||
|
||||
// Not sure F.point will make that run like Task.apply would have
|
||||
// if F = Task
|
||||
EitherT.right(F.point(FallbackDependenciesRepository.exists(url))).flatMap { exists =>
|
||||
if (exists) {
|
||||
if (FallbackDependenciesRepository.exists(url)) {
|
||||
val proj = Project(
|
||||
module,
|
||||
version,
|
||||
|
|
@ -126,10 +135,12 @@ final case class FallbackDependenciesRepository(
|
|||
Info.empty
|
||||
)
|
||||
|
||||
EitherT.right(F.point((source, proj)))
|
||||
(source, proj).right
|
||||
} else
|
||||
EitherT.left(F.point(s"$fileName not found under $dirUrlStr"))
|
||||
s"$fileName not found under $dirUrlStr".left
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
EitherT(res.point)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,28 +2,27 @@ package coursier
|
|||
|
||||
import scala.language.higherKinds
|
||||
|
||||
import scalaz.{ -\/, \/-, Monad, EitherT }
|
||||
import scalaz.{EitherT, Monad}
|
||||
import scalaz.syntax.monad._
|
||||
import scalaz.syntax.std.option._
|
||||
|
||||
final case class InterProjectRepository(projects: Seq[Project]) extends Repository {
|
||||
|
||||
private val map = projects
|
||||
.map { proj => proj.moduleVersion -> proj }
|
||||
.map(proj => proj.moduleVersion -> proj)
|
||||
.toMap
|
||||
|
||||
def find[F[_]](
|
||||
def find[F[_]: Monad](
|
||||
module: Module,
|
||||
version: String,
|
||||
fetch: Fetch.Content[F]
|
||||
)(implicit
|
||||
F: Monad[F]
|
||||
): EitherT[F, String, (Artifact.Source, Project)] = {
|
||||
val res = map.get((module, version)) match {
|
||||
case Some(proj) =>
|
||||
\/-((Artifact.Source.empty, proj))
|
||||
case None =>
|
||||
-\/("Not found")
|
||||
}
|
||||
|
||||
EitherT(F.point(res))
|
||||
val res = map
|
||||
.get((module, version))
|
||||
.toRightDisjunction("Not found")
|
||||
.map((Artifact.Source.empty, _))
|
||||
|
||||
EitherT(res.point)
|
||||
}
|
||||
}
|
||||
|
|
@ -3,7 +3,8 @@ package coursier
|
|||
import scala.collection.mutable.ArrayBuffer
|
||||
|
||||
sealed abstract class ResolutionError extends Product with Serializable {
|
||||
def cause: Option[Throwable] = this match {
|
||||
|
||||
final def cause: Option[Throwable] = this match {
|
||||
case ResolutionError.MaximumIterationsReached => None
|
||||
case ResolutionError.UnknownException(ex) => Some(ex)
|
||||
case ResolutionError.UnknownDownloadException(ex) => Some(ex)
|
||||
|
|
@ -12,10 +13,10 @@ sealed abstract class ResolutionError extends Product with Serializable {
|
|||
case _: ResolutionError.DownloadErrors => None
|
||||
}
|
||||
|
||||
def message: String = this match {
|
||||
final def message: String = this match {
|
||||
case ResolutionError.MaximumIterationsReached =>
|
||||
"Maximum number of iteration of dependency resolution reached"
|
||||
case ResolutionError.UnknownException(ex) =>
|
||||
case ResolutionError.UnknownException(_) =>
|
||||
"Exception during resolution"
|
||||
case ResolutionError.UnknownDownloadException(ex) =>
|
||||
"Error while downloading / verifying artifacts"
|
||||
|
|
@ -29,10 +30,10 @@ sealed abstract class ResolutionError extends Product with Serializable {
|
|||
err.description(verbose = true)
|
||||
}
|
||||
|
||||
def exception(): ResolutionException =
|
||||
final def exception(): ResolutionException =
|
||||
new ResolutionException(this)
|
||||
|
||||
def throwException(): Nothing =
|
||||
final def throwException(): Nothing =
|
||||
throw exception()
|
||||
}
|
||||
|
||||
|
|
@ -49,40 +50,44 @@ object ResolutionError {
|
|||
def grouped(errs: Seq[String]) =
|
||||
errs
|
||||
.map { s =>
|
||||
val idx = s.indexOf(": ")
|
||||
if (idx >= 0)
|
||||
(s.take(idx), s.drop(idx + ": ".length))
|
||||
else
|
||||
("", s)
|
||||
s.split(": ", 2) match {
|
||||
case Array(k, v) => (k, v)
|
||||
case _ => ("", s)
|
||||
}
|
||||
}
|
||||
.groupBy(_._1)
|
||||
.mapValues(_.map(_._2))
|
||||
.toVector
|
||||
.sortBy(_._1)
|
||||
|
||||
val lines = new ArrayBuffer[String]
|
||||
|
||||
lines += s"Encountered ${errors.length} error(s) in dependency resolution:"
|
||||
val lines = new ArrayBuffer[String]
|
||||
def print(s: String, indentLevel: Int = 0) =
|
||||
lines += " " * indentLevel * 2 + s
|
||||
def result = lines.mkString("\n")
|
||||
|
||||
|
||||
print(s"Encountered ${errors.length} error(s) in dependency resolution:")
|
||||
|
||||
for (((mod, ver), errs) <- errors) {
|
||||
lines += s" $mod:$ver:"
|
||||
print(s"$mod:$ver:", 1)
|
||||
|
||||
for ((type0, errs0) <- grouped(errs))
|
||||
if (type0.isEmpty)
|
||||
for (err <- errs0)
|
||||
lines += s" $err"
|
||||
print(err, 2)
|
||||
else
|
||||
errs0 match {
|
||||
case Seq(err) =>
|
||||
lines += s" $type0: $err"
|
||||
print(s"$type0: $err", 2)
|
||||
case _ =>
|
||||
lines += s" $type0:"
|
||||
print(s"$type0:", 2)
|
||||
for (err <- errs0)
|
||||
lines += s" $err"
|
||||
print(err, 3)
|
||||
}
|
||||
}
|
||||
|
||||
lines.mkString("\n")
|
||||
result
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -96,16 +101,21 @@ object ResolutionError {
|
|||
.toVector
|
||||
.sortBy(_._1)
|
||||
|
||||
val b = new ArrayBuffer[String]
|
||||
|
||||
val lines = new ArrayBuffer[String]
|
||||
def print(s: String, indentLevel: Int = 0) =
|
||||
lines += " " * indentLevel * 2 + s
|
||||
def result = lines.mkString("\n")
|
||||
|
||||
|
||||
for ((type0, errors) <- groupedArtifactErrors) {
|
||||
b += s"${errors.size} $type0"
|
||||
print(s"${errors.size} $type0")
|
||||
if (verbose)
|
||||
for (err <- errors)
|
||||
b += " " + err
|
||||
print(err, 1)
|
||||
}
|
||||
|
||||
b.mkString("\n")
|
||||
result
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,11 +8,13 @@ object SbtBootJars {
|
|||
scalaVersion: String,
|
||||
jars: Seq[File]
|
||||
): Map[(Module, String), File] =
|
||||
jars.collect {
|
||||
case jar if jar.getName.endsWith(".jar") =>
|
||||
val name = jar.getName.stripSuffix(".jar")
|
||||
val mod = Module(scalaOrg, name)
|
||||
jars
|
||||
.collect {
|
||||
case jar if jar.getName.endsWith(".jar") =>
|
||||
val name = jar.getName.stripSuffix(".jar")
|
||||
val mod = Module(scalaOrg, name)
|
||||
|
||||
(mod, scalaVersion) -> jar
|
||||
}.toMap
|
||||
(mod, scalaVersion) -> jar
|
||||
}
|
||||
.toMap
|
||||
}
|
||||
|
|
@ -6,7 +6,7 @@ import scala.util.{Failure, Success, Try}
|
|||
|
||||
object Settings {
|
||||
|
||||
private lazy val baseDefaultVerbosityLevel =
|
||||
private val baseDefaultVerbosityLevel =
|
||||
if (System.console() == null) // non interactive mode
|
||||
0
|
||||
else
|
||||
|
|
@ -15,17 +15,18 @@ object Settings {
|
|||
def defaultVerbosityLevel(logger: Logger): Int = {
|
||||
|
||||
def fromOption(value: Option[String], description: String): Option[Int] =
|
||||
value.filter(_.nonEmpty).flatMap {
|
||||
str =>
|
||||
value
|
||||
.filter(_.nonEmpty)
|
||||
.flatMap { str =>
|
||||
Try(str.toInt) match {
|
||||
case Success(level) => Some(level)
|
||||
case Failure(ex) =>
|
||||
case Failure(_) =>
|
||||
logger.warn(
|
||||
s"unrecognized $description value (should be an integer), ignoring it."
|
||||
)
|
||||
None
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
val fromEnv = fromOption(
|
||||
sys.env.get("COURSIER_VERBOSITY"),
|
||||
|
|
|
|||
Loading…
Reference in New Issue