New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Explanation [ not issue ] #169

leobenkel opened this Issue Nov 14, 2018 · 2 comments


None yet
2 participants
Copy link

leobenkel commented Nov 14, 2018

Can anyone explain to me what

moduleGraphSbt :=
          .map(report ⇒ SbtUpdateReport.fromConfigurationReport(report, crossProjectId.value))

is doing ? Here:

moduleGraphSbt :=
ignoreMissingUpdate.value.configuration(configuration.value).map(report SbtUpdateReport.fromConfigurationReport(report, crossProjectId.value)).getOrElse(ModuleGraph.empty),

I am trying to build my own sbt plugin to analyze dependencies and I am trying to reproduce the same graph of dependencies that you have. But I struggle with this step.


This comment has been minimized.

Copy link

jrudolph commented Nov 17, 2018

Here are the steps:

  • ignoreMissingUpdate is very similar to the regular update step, it runs the ivy resolution and returns an UpdateReport
  • configuration(...) returns the result of the resolution for one ivy configuration (like compile, provided, runtime, or test) if it exists
  • SbtUpdateReport.fromConfigurationReport does the real work of converting the sbt ConfigurationReport into a ModuleGraph which is the sbt-dependency-graph data structure to represent the dependencies


def fromConfigurationReport(report: ConfigurationReport, rootInfo: sbt.ModuleID): ModuleGraph = {
implicit def id(sbtId: sbt.ModuleID): ModuleId = ModuleId(sbtId.organization,, sbtId.revision)
def moduleEdges(orgArt: OrganizationArtifactReport): Seq[(Module, Seq[Edge])] = {
val chosenVersion = orgArt.modules.find(!_.evicted).map(_.module.revision)
def moduleEdge(chosenVersion: Option[String])(report: ModuleReport): (Module, Seq[Edge]) = {
val evictedByVersion = if (report.evicted) chosenVersion else None
val jarFile = report.artifacts.find(_._1.`type` == "jar").orElse(report.artifacts.find(_._1.extension == "jar")).map(_._2)
id = report.module,
license =,
evictedByVersion = evictedByVersion,
jarFile = jarFile,
error = report.problem), Edge(caller.caller, report.module)))
val (nodes, edges) = report.details.flatMap(moduleEdges).unzip
val root = Module(rootInfo)
ModuleGraph(root +: nodes, edges.flatten)

I'd recommend to use an IDEA like IntelliJ IDEA and use "jump to definition" (ctrl-click) to discover what code like this is doing.


This comment has been minimized.

Copy link

leobenkel commented Nov 18, 2018

Thats what I was doing but didn't really know how SBT was working. Thank you so much for the explanation !

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment