Merge pull request #1532 from sbt/fix/1484-again

Fix NPE during update again
This commit is contained in:
eugene yokota 2014-08-16 14:39:33 -04:00
commit eaaa47a81c
3 changed files with 24 additions and 17 deletions

View File

@ -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()

View File

@ -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.

View File

@ -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) +