From 1e3f31df16f4b5a284b068359442c5860708fd98 Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Fri, 15 Aug 2014 01:57:21 -0400 Subject: [PATCH 1/2] ModuleDetailReport => OrganizationArtifactReport MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ModuleDetailReport hasn’t been released yet, so this rename is safe. --- ivy/src/main/scala/sbt/EvictionWarning.scala | 6 +++--- ivy/src/main/scala/sbt/IvyRetrieve.scala | 10 +++++----- ivy/src/main/scala/sbt/UpdateReport.scala | 14 +++++++++----- 3 files changed, 17 insertions(+), 13 deletions(-) diff --git a/ivy/src/main/scala/sbt/EvictionWarning.scala b/ivy/src/main/scala/sbt/EvictionWarning.scala index bacebdee3..da121e0fa 100644 --- a/ivy/src/main/scala/sbt/EvictionWarning.scala +++ b/ivy/src/main/scala/sbt/EvictionWarning.scala @@ -112,8 +112,8 @@ object EvictionWarning { processEvictions(module, options, evictions) } - private[sbt] def buildEvictions(options: EvictionWarningOptions, report: UpdateReport): Seq[ModuleDetailReport] = { - val buffer: mutable.ListBuffer[ModuleDetailReport] = mutable.ListBuffer() + private[sbt] def buildEvictions(options: EvictionWarningOptions, report: UpdateReport): Seq[OrganizationArtifactReport] = { + val buffer: mutable.ListBuffer[OrganizationArtifactReport] = mutable.ListBuffer() val confs = report.configurations filter { x => options.configStrings contains x.configuration } confs flatMap { confReport => confReport.details map { detail => @@ -134,7 +134,7 @@ object EvictionWarning { 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 { case x: InlineConfiguration => x.dependencies case _ => Seq() diff --git a/ivy/src/main/scala/sbt/IvyRetrieve.scala b/ivy/src/main/scala/sbt/IvyRetrieve.scala index b83b924a9..ed252e43b 100644 --- a/ivy/src/main/scala/sbt/IvyRetrieve.scala +++ b/ivy/src/main/scala/sbt/IvyRetrieve.scala @@ -48,14 +48,14 @@ object IvyRetrieve { // We need this because current module report used as part of UpdateReport/ConfigurationReport contains // only the revolved modules. // 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 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 } - 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] = @@ -150,7 +150,7 @@ object IvyRetrieve { def updateStats(report: ResolveReport): UpdateStats = new UpdateStats(report.getResolveTime, report.getDownloadTime, report.getDownloadSize, false) 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. diff --git a/ivy/src/main/scala/sbt/UpdateReport.scala b/ivy/src/main/scala/sbt/UpdateReport.scala index 2adc13931..d32bbe9a9 100644 --- a/ivy/src/main/scala/sbt/UpdateReport.scala +++ b/ivy/src/main/scala/sbt/UpdateReport.scala @@ -46,7 +46,7 @@ final class UpdateReport(val cachedDescriptor: File, val configurations: Seq[Con final class ConfigurationReport( val configuration: String, 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]) { def this(configuration: String, modules: Seq[ModuleReport], evicted: Seq[ModuleID]) = 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 Ivy's, "module" means just organization and name, and the one including version numbers * 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). - * 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. */ -final class ModuleDetailReport( +final class OrganizationArtifactReport private[sbt] ( val organization: String, val name: String, val modules: Seq[ModuleReport]) { @@ -86,6 +86,10 @@ final class ModuleDetailReport( 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. From 74c6c18a4c520bb07c4f41720bb4df75bccc7378 Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Fri, 15 Aug 2014 02:57:17 -0400 Subject: [PATCH 2/2] Fixes #1484. Fixes another variant of update NPE Ivy gives an array that contains null for caller configurations. sbinary barfs when it sees null. Curiously two of the sbt plugins that hit this bug happens to be from Typesafe: addSbtPlugin("com.typesafe.play" % "sbt-plugin" % "2.3.2") addSbtPlugin("com.typesafe.sbt" % "sbt-native-packager" % "0.7.3") --- ivy/src/main/scala/sbt/IvyRetrieve.scala | 9 ++++++--- ivy/src/main/scala/sbt/UpdateReport.scala | 2 +- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/ivy/src/main/scala/sbt/IvyRetrieve.scala b/ivy/src/main/scala/sbt/IvyRetrieve.scala index ed252e43b..5f07963bd 100644 --- a/ivy/src/main/scala/sbt/IvyRetrieve.scala +++ b/ivy/src/main/scala/sbt/IvyRetrieve.scala @@ -68,11 +68,14 @@ object IvyRetrieve { private[sbt] def moduleRevisionDetail(confReport: ConfigurationResolveReport, dep: IvyNode): ModuleReport = { def toExtraAttributes(ea: ju.Map[_, _]): Map[String, String] = 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 = { 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) new Caller(m, callerConfigurations, extraAttributes) } @@ -120,7 +123,7 @@ object IvyRetrieve { val configurations = dep.getConfigurations(confReport.getConfiguration).toArray.toList val licenses: Seq[(String, Option[String])] = mdOpt match { case Some(md) => md.getLicenses.toArray.toVector collect { - case lic: IvyLicense => + case lic: IvyLicense if Option(lic.getName).isDefined => (lic.getName, nonEmptyString(lic.getUrl)) } case _ => Nil diff --git a/ivy/src/main/scala/sbt/UpdateReport.scala b/ivy/src/main/scala/sbt/UpdateReport.scala index d32bbe9a9..7e04d5135 100644 --- a/ivy/src/main/scala/sbt/UpdateReport.scala +++ b/ivy/src/main/scala/sbt/UpdateReport.scala @@ -123,7 +123,7 @@ final class ModuleReport( s"\t\t$module: " + (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" + (if (arts.size <= 1) "" else arts.mkString("\t\t\t", "\n\t\t\t", "\n")) + reportStr("status", status) +