mirror of https://github.com/sbt/sbt.git
Try not flooding the terminal with ignored errors...
...in updateClassifiers. Also fail if an artifact cannot be fetched in update. A bit risky - might unveil locked errors, that ought to be circumvented.
This commit is contained in:
parent
d899303d2e
commit
f73dac68fd
|
|
@ -226,6 +226,10 @@ lazy val cache = project
|
||||||
import com.typesafe.tools.mima.core.ProblemFilters._
|
import com.typesafe.tools.mima.core.ProblemFilters._
|
||||||
|
|
||||||
Seq(
|
Seq(
|
||||||
|
// Since 1.0.0-M11
|
||||||
|
// Add constructor parameter on FileError - shouldn't be built by users anyway
|
||||||
|
ProblemFilters.exclude[MissingMethodProblem]("coursier.FileError.this"),
|
||||||
|
ProblemFilters.exclude[MissingMethodProblem]("coursier.FileError#Recoverable.this"),
|
||||||
// Since 1.0.0-M10
|
// Since 1.0.0-M10
|
||||||
// methods that should have been private anyway
|
// methods that should have been private anyway
|
||||||
ProblemFilters.exclude[MissingMethodProblem]("coursier.TermDisplay.update"),
|
ProblemFilters.exclude[MissingMethodProblem]("coursier.TermDisplay.update"),
|
||||||
|
|
|
||||||
|
|
@ -2,26 +2,41 @@ package coursier
|
||||||
|
|
||||||
import java.io.File
|
import java.io.File
|
||||||
|
|
||||||
sealed abstract class FileError(val message: String) extends Product with Serializable
|
sealed abstract class FileError(
|
||||||
|
val `type`: String,
|
||||||
|
val message: String
|
||||||
|
) extends Product with Serializable
|
||||||
|
|
||||||
object FileError {
|
object FileError {
|
||||||
|
|
||||||
final case class DownloadError(reason: String) extends FileError(s"Download error: $reason")
|
final case class DownloadError(reason: String) extends FileError(
|
||||||
|
"download error",
|
||||||
|
reason
|
||||||
|
)
|
||||||
|
|
||||||
final case class NotFound(
|
final case class NotFound(
|
||||||
file: String,
|
file: String,
|
||||||
permanent: Option[Boolean] = None
|
permanent: Option[Boolean] = None
|
||||||
) extends FileError(s"Not found: $file")
|
) extends FileError(
|
||||||
|
"not found",
|
||||||
|
file
|
||||||
|
)
|
||||||
|
|
||||||
final case class ChecksumNotFound(
|
final case class ChecksumNotFound(
|
||||||
sumType: String,
|
sumType: String,
|
||||||
file: String
|
file: String
|
||||||
) extends FileError(s"$sumType checksum not found: $file")
|
) extends FileError(
|
||||||
|
"checksum not found",
|
||||||
|
file
|
||||||
|
)
|
||||||
|
|
||||||
final case class ChecksumFormatError(
|
final case class ChecksumFormatError(
|
||||||
sumType: String,
|
sumType: String,
|
||||||
file: String
|
file: String
|
||||||
) extends FileError(s"Unrecognized $sumType checksum format in $file")
|
) extends FileError(
|
||||||
|
"checksum format error",
|
||||||
|
file
|
||||||
|
)
|
||||||
|
|
||||||
final case class WrongChecksum(
|
final case class WrongChecksum(
|
||||||
sumType: String,
|
sumType: String,
|
||||||
|
|
@ -29,10 +44,22 @@ object FileError {
|
||||||
expected: String,
|
expected: String,
|
||||||
file: String,
|
file: String,
|
||||||
sumFile: String
|
sumFile: String
|
||||||
) extends FileError(s"$sumType checksum validation failed: $file")
|
) extends FileError(
|
||||||
|
"wrong checksum",
|
||||||
|
file
|
||||||
|
)
|
||||||
|
|
||||||
sealed abstract class Recoverable(message: String) extends FileError(message)
|
sealed abstract class Recoverable(
|
||||||
final case class Locked(file: File) extends Recoverable(s"Locked: $file")
|
`type`: String,
|
||||||
final case class ConcurrentDownload(url: String) extends Recoverable(s"Concurrent download: $url")
|
message: String
|
||||||
|
) extends FileError(`type`, message)
|
||||||
|
final case class Locked(file: File) extends Recoverable(
|
||||||
|
"locked",
|
||||||
|
file.toString
|
||||||
|
)
|
||||||
|
final case class ConcurrentDownload(url: String) extends Recoverable(
|
||||||
|
"concurrent download",
|
||||||
|
url
|
||||||
|
)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,5 @@
|
||||||
package coursier
|
package coursier
|
||||||
|
|
||||||
import java.io.File
|
|
||||||
|
|
||||||
import sbt._
|
import sbt._
|
||||||
import sbt.Keys._
|
import sbt.Keys._
|
||||||
|
|
||||||
|
|
@ -43,7 +41,7 @@ object CoursierPlugin extends AutoPlugin {
|
||||||
coursierFallbackDependencies <<= Tasks.coursierFallbackDependenciesTask,
|
coursierFallbackDependencies <<= Tasks.coursierFallbackDependenciesTask,
|
||||||
coursierCache := Cache.default,
|
coursierCache := Cache.default,
|
||||||
update <<= Tasks.updateTask(withClassifiers = false),
|
update <<= Tasks.updateTask(withClassifiers = false),
|
||||||
updateClassifiers <<= Tasks.updateTask(withClassifiers = true),
|
updateClassifiers <<= Tasks.updateTask(withClassifiers = true, ignoreArtifactErrors = true),
|
||||||
updateSbtClassifiers in Defaults.TaskGlobal <<= Tasks.updateTask(withClassifiers = true, sbtClassifiers = true),
|
updateSbtClassifiers in Defaults.TaskGlobal <<= Tasks.updateTask(withClassifiers = true, sbtClassifiers = true),
|
||||||
coursierProject <<= Tasks.coursierProjectTask,
|
coursierProject <<= Tasks.coursierProjectTask,
|
||||||
coursierProjects <<= Tasks.coursierProjectsTask,
|
coursierProjects <<= Tasks.coursierProjectsTask,
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,11 @@ import scala.util.{Failure, Success, Try}
|
||||||
|
|
||||||
object Settings {
|
object Settings {
|
||||||
|
|
||||||
private val baseDefaultVerbosityLevel = 0
|
private lazy val baseDefaultVerbosityLevel =
|
||||||
|
if (System.console() == null) // non interactive mode
|
||||||
|
0
|
||||||
|
else
|
||||||
|
1
|
||||||
|
|
||||||
def defaultVerbosityLevel: Int = {
|
def defaultVerbosityLevel: Int = {
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -185,7 +185,11 @@ object Tasks {
|
||||||
Module("org.scala-lang", "scalap") -> scalaVersion
|
Module("org.scala-lang", "scalap") -> scalaVersion
|
||||||
)
|
)
|
||||||
|
|
||||||
def updateTask(withClassifiers: Boolean, sbtClassifiers: Boolean = false) = Def.task {
|
def updateTask(
|
||||||
|
withClassifiers: Boolean,
|
||||||
|
sbtClassifiers: Boolean = false,
|
||||||
|
ignoreArtifactErrors: Boolean = false
|
||||||
|
) = Def.task {
|
||||||
|
|
||||||
def grouped[K, V](map: Seq[(K, V)]): Map[K, Seq[V]] =
|
def grouped[K, V](map: Seq[(K, V)]): Map[K, Seq[V]] =
|
||||||
map.groupBy { case (k, _) => k }.map {
|
map.groupBy { case (k, _) => k }.map {
|
||||||
|
|
@ -375,7 +379,7 @@ object Tasks {
|
||||||
s"${dep.module}:${dep.version}:${dep.configuration}"
|
s"${dep.module}:${dep.version}:${dep.configuration}"
|
||||||
}.sorted.distinct
|
}.sorted.distinct
|
||||||
|
|
||||||
if (verbosityLevel >= 1) {
|
if (verbosityLevel >= 2) {
|
||||||
val repoReprs = repositories.map {
|
val repoReprs = repositories.map {
|
||||||
case r: IvyRepository =>
|
case r: IvyRepository =>
|
||||||
s"ivy:${r.pattern}"
|
s"ivy:${r.pattern}"
|
||||||
|
|
@ -396,7 +400,7 @@ object Tasks {
|
||||||
|
|
||||||
if (verbosityLevel >= 0)
|
if (verbosityLevel >= 0)
|
||||||
log.info(s"Resolving ${currentProject.module.organization}:${currentProject.module.name}:${currentProject.version}")
|
log.info(s"Resolving ${currentProject.module.organization}:${currentProject.module.name}:${currentProject.version}")
|
||||||
if (verbosityLevel >= 1)
|
if (verbosityLevel >= 2)
|
||||||
for (depRepr <- depsRepr(currentProject.dependencies))
|
for (depRepr <- depsRepr(currentProject.dependencies))
|
||||||
log.info(s" $depRepr")
|
log.info(s" $depRepr")
|
||||||
|
|
||||||
|
|
@ -467,7 +471,7 @@ object Tasks {
|
||||||
|
|
||||||
if (verbosityLevel >= 0)
|
if (verbosityLevel >= 0)
|
||||||
log.info("Resolution done")
|
log.info("Resolution done")
|
||||||
if (verbosityLevel >= 1) {
|
if (verbosityLevel >= 2) {
|
||||||
val finalDeps = Config.dependenciesWithConfig(
|
val finalDeps = Config.dependenciesWithConfig(
|
||||||
res,
|
res,
|
||||||
depsByConfig.map { case (k, l) => k -> l.toSet },
|
depsByConfig.map { case (k, l) => k -> l.toSet },
|
||||||
|
|
@ -532,18 +536,42 @@ object Tasks {
|
||||||
if (verbosityLevel >= 0)
|
if (verbosityLevel >= 0)
|
||||||
log.info("Fetching artifacts: done")
|
log.info("Fetching artifacts: done")
|
||||||
|
|
||||||
def artifactFileOpt(artifact: Artifact) = {
|
val artifactFiles = artifactFilesOrErrors.collect {
|
||||||
val fileOrError = artifactFilesOrErrors.getOrElse(artifact, -\/("Not downloaded"))
|
case (artifact, \/-(file)) =>
|
||||||
|
artifact -> file
|
||||||
|
}
|
||||||
|
|
||||||
fileOrError match {
|
val artifactErrors = artifactFilesOrErrors.toVector.collect {
|
||||||
case \/-(file) =>
|
case (_, -\/(err)) =>
|
||||||
if (file.toString.contains("file:/"))
|
err
|
||||||
throw new Exception(s"Wrong path: $file")
|
}
|
||||||
Some(file)
|
|
||||||
case -\/(err) =>
|
if (artifactErrors.nonEmpty) {
|
||||||
log.error(s"${artifact.url}: $err")
|
val groupedArtifactErrors = artifactErrors
|
||||||
None
|
.groupBy(_.`type`)
|
||||||
|
.mapValues(_.map(_.message).sorted)
|
||||||
|
.toVector
|
||||||
|
.sortBy(_._1)
|
||||||
|
|
||||||
|
for ((type0, errors) <- groupedArtifactErrors) {
|
||||||
|
log.error(s"${errors.size} $type0")
|
||||||
|
|
||||||
|
if (!ignoreArtifactErrors || verbosityLevel >= 1)
|
||||||
|
for (err <- errors)
|
||||||
|
log.error(" " + err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!ignoreArtifactErrors)
|
||||||
|
throw new Exception(s"Encountered ${artifactErrors.length} errors (see above messages)")
|
||||||
|
}
|
||||||
|
|
||||||
|
def artifactFileOpt(artifact: Artifact) = {
|
||||||
|
val res = artifactFiles.get(artifact)
|
||||||
|
|
||||||
|
if (res.isEmpty)
|
||||||
|
log.error(s"${artifact.url} not downloaded (should not happen)")
|
||||||
|
|
||||||
|
res
|
||||||
}
|
}
|
||||||
|
|
||||||
writeIvyFiles()
|
writeIvyFiles()
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue