mirror of https://github.com/sbt/sbt.git
Merge pull request #1532 from sbt/fix/1484-again
Fix NPE during update again
This commit is contained in:
commit
60c8404d5c
|
|
@ -112,8 +112,8 @@ object EvictionWarning {
|
||||||
processEvictions(module, options, evictions)
|
processEvictions(module, options, evictions)
|
||||||
}
|
}
|
||||||
|
|
||||||
private[sbt] def buildEvictions(options: EvictionWarningOptions, report: UpdateReport): Seq[ModuleDetailReport] = {
|
private[sbt] def buildEvictions(options: EvictionWarningOptions, report: UpdateReport): Seq[OrganizationArtifactReport] = {
|
||||||
val buffer: mutable.ListBuffer[ModuleDetailReport] = mutable.ListBuffer()
|
val buffer: mutable.ListBuffer[OrganizationArtifactReport] = mutable.ListBuffer()
|
||||||
val confs = report.configurations filter { x => options.configStrings contains x.configuration }
|
val confs = report.configurations filter { x => options.configStrings contains x.configuration }
|
||||||
confs flatMap { confReport =>
|
confs flatMap { confReport =>
|
||||||
confReport.details map { detail =>
|
confReport.details map { detail =>
|
||||||
|
|
@ -134,7 +134,7 @@ object EvictionWarning {
|
||||||
case _ => false
|
case _ => false
|
||||||
}
|
}
|
||||||
|
|
||||||
private[sbt] def processEvictions(module: IvySbt#Module, options: EvictionWarningOptions, reports: Seq[ModuleDetailReport]): EvictionWarning = {
|
private[sbt] def processEvictions(module: IvySbt#Module, options: EvictionWarningOptions, reports: Seq[OrganizationArtifactReport]): EvictionWarning = {
|
||||||
val directDependencies = module.moduleSettings match {
|
val directDependencies = module.moduleSettings match {
|
||||||
case x: InlineConfiguration => x.dependencies
|
case x: InlineConfiguration => x.dependencies
|
||||||
case _ => Seq()
|
case _ => Seq()
|
||||||
|
|
|
||||||
|
|
@ -48,14 +48,14 @@ object IvyRetrieve {
|
||||||
// We need this because current module report used as part of UpdateReport/ConfigurationReport contains
|
// We need this because current module report used as part of UpdateReport/ConfigurationReport contains
|
||||||
// only the revolved modules.
|
// only the revolved modules.
|
||||||
// Sometimes the entire module can be excluded via rules etc.
|
// Sometimes the entire module can be excluded via rules etc.
|
||||||
private[sbt] def details(confReport: ConfigurationResolveReport): Seq[ModuleDetailReport] = {
|
private[sbt] def organizationArtifactReports(confReport: ConfigurationResolveReport): Seq[OrganizationArtifactReport] = {
|
||||||
val dependencies = confReport.getModuleRevisionIds.toArray.toVector collect { case revId: ModuleRevisionId => revId }
|
val dependencies = confReport.getModuleRevisionIds.toArray.toVector collect { case revId: ModuleRevisionId => revId }
|
||||||
val moduleIds = confReport.getModuleIds.toArray.toVector collect { case mId: IvyModuleId => mId }
|
val moduleIds = confReport.getModuleIds.toArray.toVector collect { case mId: IvyModuleId => mId }
|
||||||
def moduleDetail(mid: IvyModuleId): ModuleDetailReport = {
|
def organizationArtifact(mid: IvyModuleId): OrganizationArtifactReport = {
|
||||||
val deps = confReport.getNodes(mid).toArray.toVector collect { case node: IvyNode => node }
|
val deps = confReport.getNodes(mid).toArray.toVector collect { case node: IvyNode => node }
|
||||||
new ModuleDetailReport(mid.getOrganisation, mid.getName, deps map { moduleRevisionDetail(confReport, _) })
|
OrganizationArtifactReport(mid.getOrganisation, mid.getName, deps map { moduleRevisionDetail(confReport, _) })
|
||||||
}
|
}
|
||||||
moduleIds map { moduleDetail }
|
moduleIds map { organizationArtifact }
|
||||||
}
|
}
|
||||||
|
|
||||||
private[sbt] def nonEmptyString(s: String): Option[String] =
|
private[sbt] def nonEmptyString(s: String): Option[String] =
|
||||||
|
|
@ -68,11 +68,14 @@ object IvyRetrieve {
|
||||||
private[sbt] def moduleRevisionDetail(confReport: ConfigurationResolveReport, dep: IvyNode): ModuleReport = {
|
private[sbt] def moduleRevisionDetail(confReport: ConfigurationResolveReport, dep: IvyNode): ModuleReport = {
|
||||||
def toExtraAttributes(ea: ju.Map[_, _]): Map[String, String] =
|
def toExtraAttributes(ea: ju.Map[_, _]): Map[String, String] =
|
||||||
Map(ea.entrySet.toArray collect {
|
Map(ea.entrySet.toArray collect {
|
||||||
case entry: ju.Map.Entry[_, _] => (entry.getKey.toString, entry.getValue.toString)
|
case entry: ju.Map.Entry[_, _] if nonEmptyString(entry.getKey.toString).isDefined && nonEmptyString(entry.getValue.toString).isDefined =>
|
||||||
|
(entry.getKey.toString, entry.getValue.toString)
|
||||||
}: _*)
|
}: _*)
|
||||||
def toCaller(caller: IvyCaller): Caller = {
|
def toCaller(caller: IvyCaller): Caller = {
|
||||||
val m = toModuleID(caller.getModuleRevisionId)
|
val m = toModuleID(caller.getModuleRevisionId)
|
||||||
val callerConfigurations = caller.getCallerConfigurations.toArray.toVector
|
val callerConfigurations = caller.getCallerConfigurations.toArray.toVector collect {
|
||||||
|
case x if nonEmptyString(x).isDefined => x
|
||||||
|
}
|
||||||
val extraAttributes = toExtraAttributes(caller.getDependencyDescriptor.getExtraAttributes)
|
val extraAttributes = toExtraAttributes(caller.getDependencyDescriptor.getExtraAttributes)
|
||||||
new Caller(m, callerConfigurations, extraAttributes)
|
new Caller(m, callerConfigurations, extraAttributes)
|
||||||
}
|
}
|
||||||
|
|
@ -120,7 +123,7 @@ object IvyRetrieve {
|
||||||
val configurations = dep.getConfigurations(confReport.getConfiguration).toArray.toList
|
val configurations = dep.getConfigurations(confReport.getConfiguration).toArray.toList
|
||||||
val licenses: Seq[(String, Option[String])] = mdOpt match {
|
val licenses: Seq[(String, Option[String])] = mdOpt match {
|
||||||
case Some(md) => md.getLicenses.toArray.toVector collect {
|
case Some(md) => md.getLicenses.toArray.toVector collect {
|
||||||
case lic: IvyLicense =>
|
case lic: IvyLicense if Option(lic.getName).isDefined =>
|
||||||
(lic.getName, nonEmptyString(lic.getUrl))
|
(lic.getName, nonEmptyString(lic.getUrl))
|
||||||
}
|
}
|
||||||
case _ => Nil
|
case _ => Nil
|
||||||
|
|
@ -150,7 +153,7 @@ object IvyRetrieve {
|
||||||
def updateStats(report: ResolveReport): UpdateStats =
|
def updateStats(report: ResolveReport): UpdateStats =
|
||||||
new UpdateStats(report.getResolveTime, report.getDownloadTime, report.getDownloadSize, false)
|
new UpdateStats(report.getResolveTime, report.getDownloadTime, report.getDownloadSize, false)
|
||||||
def configurationReport(confReport: ConfigurationResolveReport): ConfigurationReport =
|
def configurationReport(confReport: ConfigurationResolveReport): ConfigurationReport =
|
||||||
new ConfigurationReport(confReport.getConfiguration, moduleReports(confReport), details(confReport), evicted(confReport))
|
new ConfigurationReport(confReport.getConfiguration, moduleReports(confReport), organizationArtifactReports(confReport), evicted(confReport))
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tries to find Ivy graph path the from node to target.
|
* Tries to find Ivy graph path the from node to target.
|
||||||
|
|
|
||||||
|
|
@ -46,7 +46,7 @@ final class UpdateReport(val cachedDescriptor: File, val configurations: Seq[Con
|
||||||
final class ConfigurationReport(
|
final class ConfigurationReport(
|
||||||
val configuration: String,
|
val configuration: String,
|
||||||
val modules: Seq[ModuleReport],
|
val modules: Seq[ModuleReport],
|
||||||
val details: Seq[ModuleDetailReport],
|
val details: Seq[OrganizationArtifactReport],
|
||||||
@deprecated("Use details instead to get better eviction info.", "0.13.6") val evicted: Seq[ModuleID]) {
|
@deprecated("Use details instead to get better eviction info.", "0.13.6") val evicted: Seq[ModuleID]) {
|
||||||
def this(configuration: String, modules: Seq[ModuleReport], evicted: Seq[ModuleID]) =
|
def this(configuration: String, modules: Seq[ModuleReport], evicted: Seq[ModuleID]) =
|
||||||
this(configuration, modules, Nil, evicted)
|
this(configuration, modules, Nil, evicted)
|
||||||
|
|
@ -67,17 +67,17 @@ final class ConfigurationReport(
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ModuleDetailReport represents an organization+name entry in Ivy resolution report.
|
* OrganizationArtifactReport represents an organization+name entry in Ivy resolution report.
|
||||||
* In sbt's terminology, "module" consists of organization, name, and version.
|
* In sbt's terminology, "module" consists of organization, name, and version.
|
||||||
* In Ivy's, "module" means just organization and name, and the one including version numbers
|
* In Ivy's, "module" means just organization and name, and the one including version numbers
|
||||||
* are called revisions.
|
* are called revisions.
|
||||||
*
|
*
|
||||||
* A sequence of ModuleDetailReport called details is newly added to ConfigurationReport, replacing evicted.
|
* A sequence of OrganizationArtifactReport called details is newly added to ConfigurationReport, replacing evicted.
|
||||||
* (Note old evicted was just a seq of ModuleIDs).
|
* (Note old evicted was just a seq of ModuleIDs).
|
||||||
* ModuleDetailReport groups the ModuleReport of both winners and evicted reports by their organization and name,
|
* OrganizationArtifactReport groups the ModuleReport of both winners and evicted reports by their organization and name,
|
||||||
* which can be used to calculate detailed evction warning etc.
|
* which can be used to calculate detailed evction warning etc.
|
||||||
*/
|
*/
|
||||||
final class ModuleDetailReport(
|
final class OrganizationArtifactReport private[sbt] (
|
||||||
val organization: String,
|
val organization: String,
|
||||||
val name: String,
|
val name: String,
|
||||||
val modules: Seq[ModuleReport]) {
|
val modules: Seq[ModuleReport]) {
|
||||||
|
|
@ -86,6 +86,10 @@ final class ModuleDetailReport(
|
||||||
s"\t$organization:$name\n${details.mkString}\n"
|
s"\t$organization:$name\n${details.mkString}\n"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
object OrganizationArtifactReport {
|
||||||
|
def apply(organization: String, name: String, modules: Seq[ModuleReport]): OrganizationArtifactReport =
|
||||||
|
new OrganizationArtifactReport(organization, name, modules)
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Provides information about the resolution of a module.
|
* Provides information about the resolution of a module.
|
||||||
|
|
@ -119,7 +123,7 @@ final class ModuleReport(
|
||||||
s"\t\t$module: " +
|
s"\t\t$module: " +
|
||||||
(if (arts.size <= 1) "" else "\n\t\t\t") + arts.mkString("\n\t\t\t") + "\n"
|
(if (arts.size <= 1) "" else "\n\t\t\t") + arts.mkString("\n\t\t\t") + "\n"
|
||||||
}
|
}
|
||||||
private[sbt] def detailReport: String =
|
def detailReport: String =
|
||||||
s"\t\t- ${module.revision}\n" +
|
s"\t\t- ${module.revision}\n" +
|
||||||
(if (arts.size <= 1) "" else arts.mkString("\t\t\t", "\n\t\t\t", "\n")) +
|
(if (arts.size <= 1) "" else arts.mkString("\t\t\t", "\n\t\t\t", "\n")) +
|
||||||
reportStr("status", status) +
|
reportStr("status", status) +
|
||||||
|
|
|
||||||
|
|
@ -65,8 +65,8 @@ object CacheIvy {
|
||||||
}
|
}
|
||||||
implicit def updateStatsFormat: Format[UpdateStats] =
|
implicit def updateStatsFormat: Format[UpdateStats] =
|
||||||
wrap[UpdateStats, (Long, Long, Long)](us => (us.resolveTime, us.downloadTime, us.downloadSize), { case (rt, dt, ds) => new UpdateStats(rt, dt, ds, true) })
|
wrap[UpdateStats, (Long, Long, Long)](us => (us.resolveTime, us.downloadTime, us.downloadSize), { case (rt, dt, ds) => new UpdateStats(rt, dt, ds, true) })
|
||||||
implicit def confReportFormat(implicit m: Format[String], mr: Format[Seq[ModuleReport]], mdr: Format[Seq[ModuleDetailReport]], mi: Format[Seq[ModuleID]]): Format[ConfigurationReport] =
|
implicit def confReportFormat(implicit m: Format[String], mr: Format[Seq[ModuleReport]], oar: Format[Seq[OrganizationArtifactReport]], mi: Format[Seq[ModuleID]]): Format[ConfigurationReport] =
|
||||||
wrap[ConfigurationReport, (String, Seq[ModuleReport], Seq[ModuleDetailReport], Seq[ModuleID])](r => (r.configuration, r.modules, r.details, r.evicted), { case (c, m, d, v) => new ConfigurationReport(c, m, d, v) })
|
wrap[ConfigurationReport, (String, Seq[ModuleReport], Seq[OrganizationArtifactReport], Seq[ModuleID])](r => (r.configuration, r.modules, r.details, r.evicted), { case (c, m, d, v) => new ConfigurationReport(c, m, d, v) })
|
||||||
implicit def moduleReportFormat(implicit cf: Format[Seq[Caller]], ff: Format[File]): Format[ModuleReport] = {
|
implicit def moduleReportFormat(implicit cf: Format[Seq[Caller]], ff: Format[File]): Format[ModuleReport] = {
|
||||||
wrap[ModuleReport, (ModuleID, Seq[(Artifact, File)], Seq[Artifact], Option[String], Option[Long], Option[String], Option[String], Boolean, Option[String], Option[String], Option[String], Option[String], Map[String, String], Option[Boolean], Option[String], Seq[String], Seq[(String, Option[String])], Seq[Caller])](
|
wrap[ModuleReport, (ModuleID, Seq[(Artifact, File)], Seq[Artifact], Option[String], Option[Long], Option[String], Option[String], Boolean, Option[String], Option[String], Option[String], Option[String], Map[String, String], Option[Boolean], Option[String], Seq[String], Seq[(String, Option[String])], Seq[Caller])](
|
||||||
m => (m.module, m.artifacts, m.missingArtifacts, m.status, m.publicationDate map { _.getTime }, m.resolver, m.artifactResolver, m.evicted, m.evictedData, m.evictedReason, m.problem, m.homepage, m.extraAttributes, m.isDefault, m.branch, m.configurations, m.licenses, m.callers),
|
m => (m.module, m.artifacts, m.missingArtifacts, m.status, m.publicationDate map { _.getTime }, m.resolver, m.artifactResolver, m.evicted, m.evictedData, m.evictedReason, m.problem, m.homepage, m.extraAttributes, m.isDefault, m.branch, m.configurations, m.licenses, m.callers),
|
||||||
|
|
@ -78,8 +78,8 @@ object CacheIvy {
|
||||||
{ case (n, t, x, c, cs, u, e) => Artifact(n, t, x, c, cs, u, e) }
|
{ case (n, t, x, c, cs, u, e) => Artifact(n, t, x, c, cs, u, e) }
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
implicit def moduleDetailReportFormat(implicit sf: Format[String], bf: Format[Boolean], df: Format[Seq[ModuleReport]]): Format[ModuleDetailReport] =
|
implicit def organizationArtifactReportFormat(implicit sf: Format[String], bf: Format[Boolean], df: Format[Seq[ModuleReport]]): Format[OrganizationArtifactReport] =
|
||||||
wrap[ModuleDetailReport, (String, String, Seq[ModuleReport])](m => (m.organization, m.name, m.modules), { case (o, n, r) => new ModuleDetailReport(o, n, r) })
|
wrap[OrganizationArtifactReport, (String, String, Seq[ModuleReport])](m => (m.organization, m.name, m.modules), { case (o, n, r) => OrganizationArtifactReport(o, n, r) })
|
||||||
implicit def callerFormat: Format[Caller] =
|
implicit def callerFormat: Format[Caller] =
|
||||||
wrap[Caller, (ModuleID, Seq[String], Map[String, String])](c => (c.caller, c.callerConfigurations, c.callerExtraAttributes), { case (c, cc, ea) => new Caller(c, cc, ea) })
|
wrap[Caller, (ModuleID, Seq[String], Map[String, String])](c => (c.caller, c.callerConfigurations, c.callerExtraAttributes), { case (c, cc, ea) => new Caller(c, cc, ea) })
|
||||||
implicit def exclusionRuleFormat(implicit sf: Format[String]): Format[ExclusionRule] =
|
implicit def exclusionRuleFormat(implicit sf: Format[String]): Format[ExclusionRule] =
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,18 @@
|
||||||
|
lazy val check = taskKey[Unit]("tests update")
|
||||||
|
|
||||||
|
def commonSettings: Seq[Def.Setting[_]] = Seq(
|
||||||
|
resolvers ++= Resolver.typesafeIvyRepo("releases") :: Resolver.typesafeRepo("releases") :: Resolver.sbtPluginRepo("releases") :: Nil,
|
||||||
|
check := {
|
||||||
|
val ur = update.value
|
||||||
|
import sbinary._, Operations._, DefaultProtocol._
|
||||||
|
import Cache.seqFormat, CacheIvy._
|
||||||
|
toByteArray(ur)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
lazy val projA = project.
|
||||||
|
settings(commonSettings: _*).
|
||||||
|
settings(
|
||||||
|
addSbtPlugin("com.typesafe.play" % "sbt-plugin" % "2.3.2"),
|
||||||
|
addSbtPlugin("com.typesafe.sbt" % "sbt-native-packager" % "0.7.3")
|
||||||
|
)
|
||||||
|
|
@ -0,0 +1 @@
|
||||||
|
> projA/check
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
package sbt
|
package sbt
|
||||||
|
|
||||||
import java.io.{IOException, StringWriter, PrintWriter, File}
|
import java.io.{ IOException, StringWriter, PrintWriter, File }
|
||||||
import java.net.{InetAddress}
|
import java.net.{ InetAddress }
|
||||||
|
|
||||||
import scala.collection.mutable.ListBuffer
|
import scala.collection.mutable.ListBuffer
|
||||||
import scala.util.DynamicVariable
|
import scala.util.DynamicVariable
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue