-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Ref sbt/sbt-dependency-graph#178 This in-sources sbt-dependency-graph.
- Loading branch information
Showing
97 changed files
with
1,235 additions
and
2,368 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
95 changes: 95 additions & 0 deletions
95
main/src/main/scala/sbt/internal/graph/DependencyGraphKeys.scala
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,95 @@ | ||
/* | ||
* sbt | ||
* Copyright 2011 - 2018, Lightbend, Inc. | ||
* Copyright 2008 - 2010, Mark Harrah | ||
* Licensed under Apache License 2.0 (see LICENSE) | ||
*/ | ||
|
||
package sbt | ||
package internal | ||
package graph | ||
|
||
import java.io.File | ||
import java.net.URI | ||
import sbt.BuildSyntax._ | ||
import sbt.librarymanagement.{ ModuleID, UpdateReport } | ||
|
||
trait DependencyGraphKeys { | ||
val asString = taskKey[String]("Provides the string value for the task it is scoped for") | ||
// val printToConsole = TaskKey[Unit]("printToConsole", "Prints the tasks value to the console") | ||
val toFile = inputKey[File]("Writes the task value to the given file") | ||
|
||
val dependencyTreeIncludeScalaLibrary = settingKey[Boolean]( | ||
"Specifies if scala dependency should be included in dependencyTree output" | ||
) | ||
|
||
val dependencyGraphMLFile = | ||
settingKey[File]("The location the graphml file should be generated at") | ||
val dependencyGraphML = | ||
taskKey[File]("Creates a graphml file containing the dependency-graph for a project") | ||
val dependencyDotFile = | ||
settingKey[File]("The location the dot file should be generated at") | ||
val dependencyDotNodeLabel = settingKey[(String, String, String) => String]( | ||
"Returns a formated string of a dependency. Takes organization, name and version as parameters" | ||
) | ||
val dependencyDotHeader = settingKey[String]( | ||
"The header of the dot file. (e.g. to set your preferred node shapes)" | ||
) | ||
val dependencyDot = taskKey[File]( | ||
"Creates a dot file containing the dependency-graph for a project" | ||
) | ||
val dependencyDotString = taskKey[String]( | ||
"Creates a String containing the dependency-graph for a project in dot format" | ||
) | ||
val dependencyBrowseGraphTarget = settingKey[File]( | ||
"The location dependency browse graph files should be put." | ||
) | ||
val dependencyBrowseGraphHTML = taskKey[URI]( | ||
"Creates an HTML page that can be used to view the graph." | ||
) | ||
val dependencyBrowseGraph = taskKey[URI]( | ||
"Opens an HTML page that can be used to view the graph." | ||
) | ||
val dependencyBrowseTreeTarget = settingKey[File]( | ||
"The location dependency browse tree files should be put." | ||
) | ||
val dependencyBrowseTreeHTML = taskKey[URI]( | ||
"Creates an HTML page that can be used to view the dependency tree" | ||
) | ||
val dependencyBrowseTree = taskKey[URI]( | ||
"Opens an HTML page that can be used to view the dependency tree" | ||
) | ||
val moduleGraph = taskKey[ModuleGraph]("The dependency graph for a project") | ||
val moduleGraphIvyReport = taskKey[ModuleGraph]( | ||
"The dependency graph for a project as generated from an Ivy Report XML" | ||
) | ||
val moduleGraphSbt = taskKey[ModuleGraph]( | ||
"The dependency graph for a project as generated from SBT data structures." | ||
) | ||
val dependencyGraph = inputKey[Unit]("Prints the ascii graph to the console") | ||
val dependencyTree = taskKey[Unit]("Prints an ascii tree of all the dependencies to the console") | ||
val dependencyList = | ||
taskKey[Unit]("Prints a list of all dependencies to the console") | ||
val dependencyStats = | ||
taskKey[Unit]("Prints statistics for all dependencies to the console") | ||
val ivyReportFunction = taskKey[String => File]( | ||
"A function which returns the file containing the ivy report from the ivy cache for a given configuration" | ||
) | ||
val ivyReport = taskKey[File]( | ||
"A task which returns the location of the ivy report file for a given configuration (default `compile`)." | ||
) | ||
val dependencyLicenseInfo = taskKey[Unit]( | ||
"Aggregates and shows information about the licenses of dependencies" | ||
) | ||
|
||
// internal | ||
private[sbt] val ignoreMissingUpdate = | ||
TaskKey[UpdateReport]("dependencyUpdate", "sbt-dependency-graph version of update") | ||
private[sbt] val moduleGraphStore = | ||
TaskKey[ModuleGraph]("module-graph-store", "The stored module-graph from the last run") | ||
val whatDependsOn = | ||
InputKey[String]("what-depends-on", "Shows information about what depends on the given module") | ||
private[sbt] val crossProjectId = SettingKey[ModuleID]("dependency-graph-cross-project-id") | ||
} | ||
|
||
object DependencyGraphKeys extends DependencyGraphKeys |
58 changes: 58 additions & 0 deletions
58
main/src/main/scala/sbt/internal/graph/GraphTransformations.scala
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
/* | ||
* sbt | ||
* Copyright 2011 - 2018, Lightbend, Inc. | ||
* Copyright 2008 - 2010, Mark Harrah | ||
* Licensed under Apache License 2.0 (see LICENSE) | ||
*/ | ||
|
||
package sbt | ||
package internal | ||
package graph | ||
|
||
object GraphTransformations { | ||
def reverseGraphStartingAt(graph: ModuleGraph, root: GraphModuleId): ModuleGraph = { | ||
val deps = graph.reverseDependencyMap | ||
|
||
def visit( | ||
module: GraphModuleId, | ||
visited: Set[GraphModuleId] | ||
): Seq[(GraphModuleId, GraphModuleId)] = | ||
if (visited(module)) | ||
Nil | ||
else | ||
deps.get(module) match { | ||
case Some(deps) => | ||
deps.flatMap { to => | ||
(module, to.id) +: visit(to.id, visited + module) | ||
} | ||
case None => Nil | ||
} | ||
|
||
val edges = visit(root, Set.empty) | ||
val nodes = | ||
edges | ||
.foldLeft(Set.empty[GraphModuleId])((set, edge) => set + edge._1 + edge._2) | ||
.map(graph.module) | ||
ModuleGraph(nodes.toSeq, edges) | ||
} | ||
|
||
def ignoreScalaLibrary(scalaVersion: String, graph: ModuleGraph): ModuleGraph = { | ||
def isScalaLibrary(m: Module) = isScalaLibraryId(m.id) | ||
def isScalaLibraryId(id: GraphModuleId) = | ||
id.organization == "org.scala-lang" && id.name == "scala-library" | ||
|
||
def dependsOnScalaLibrary(m: Module): Boolean = | ||
graph.dependencyMap(m.id).exists(isScalaLibrary) | ||
|
||
def addScalaLibraryAnnotation(m: Module): Module = { | ||
if (dependsOnScalaLibrary(m)) | ||
m.copy(extraInfo = m.extraInfo + " [S]") | ||
else | ||
m | ||
} | ||
|
||
val newNodes = graph.nodes.map(addScalaLibraryAnnotation).filterNot(isScalaLibrary) | ||
val newEdges = graph.edges.filterNot(e => isScalaLibraryId(e._2)) | ||
ModuleGraph(newNodes, newEdges) | ||
} | ||
} |
67 changes: 67 additions & 0 deletions
67
main/src/main/scala/sbt/internal/graph/backend/IvyReport.scala
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,67 @@ | ||
/* | ||
* sbt | ||
* Copyright 2011 - 2018, Lightbend, Inc. | ||
* Copyright 2008 - 2010, Mark Harrah | ||
* Licensed under Apache License 2.0 (see LICENSE) | ||
*/ | ||
|
||
package sbt | ||
package internal | ||
package graph | ||
package backend | ||
|
||
import scala.xml.{ NodeSeq, Document, Node } | ||
import scala.xml.parsing.ConstructingParser | ||
|
||
object IvyReport { | ||
def fromReportFile(ivyReportFile: String): ModuleGraph = | ||
fromReportXML(loadXML(ivyReportFile)) | ||
|
||
def fromReportXML(doc: Document): ModuleGraph = { | ||
def edgesForModule(id: GraphModuleId, revision: NodeSeq): Seq[Edge] = | ||
for { | ||
caller ← revision \ "caller" | ||
callerModule = moduleIdFromElement(caller, caller.attribute("callerrev").get.text) | ||
} yield (moduleIdFromElement(caller, caller.attribute("callerrev").get.text), id) | ||
|
||
val moduleEdges: Seq[(Module, Seq[Edge])] = for { | ||
mod ← doc \ "dependencies" \ "module" | ||
revision ← mod \ "revision" | ||
rev = revision.attribute("name").get.text | ||
moduleId = moduleIdFromElement(mod, rev) | ||
module = Module( | ||
moduleId, | ||
(revision \ "license").headOption.flatMap(_.attribute("name")).map(_.text), | ||
evictedByVersion = | ||
(revision \ "evicted-by").headOption.flatMap(_.attribute("rev").map(_.text)), | ||
error = revision.attribute("error").map(_.text) | ||
) | ||
} yield (module, edgesForModule(moduleId, revision)) | ||
|
||
val (nodes, edges) = moduleEdges.unzip | ||
|
||
val info = (doc \ "info").head | ||
def infoAttr(name: String): String = | ||
info | ||
.attribute(name) | ||
.getOrElse(throw new IllegalArgumentException("Missing attribute " + name)) | ||
.text | ||
val rootModule = Module( | ||
GraphModuleId(infoAttr("organization"), infoAttr("module"), infoAttr("revision")) | ||
) | ||
|
||
ModuleGraph(rootModule +: nodes, edges.flatten) | ||
} | ||
|
||
private def moduleIdFromElement(element: Node, version: String): GraphModuleId = | ||
GraphModuleId( | ||
element.attribute("organization").get.text, | ||
element.attribute("name").get.text, | ||
version | ||
) | ||
|
||
private def loadXML(ivyReportFile: String) = | ||
ConstructingParser | ||
.fromSource(scala.io.Source.fromFile(ivyReportFile), preserveWS = false) | ||
.document() | ||
} |
54 changes: 54 additions & 0 deletions
54
main/src/main/scala/sbt/internal/graph/backend/SbtUpdateReport.scala
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,54 @@ | ||
/* | ||
* sbt | ||
* Copyright 2011 - 2018, Lightbend, Inc. | ||
* Copyright 2008 - 2010, Mark Harrah | ||
* Licensed under Apache License 2.0 (see LICENSE) | ||
*/ | ||
|
||
package sbt | ||
package internal | ||
package graph | ||
package backend | ||
|
||
import scala.language.implicitConversions | ||
import scala.language.reflectiveCalls | ||
import sbt.librarymanagement.{ ModuleID, ModuleReport, ConfigurationReport } | ||
|
||
object SbtUpdateReport { | ||
type OrganizationArtifactReport = { | ||
def modules: Seq[ModuleReport] | ||
} | ||
|
||
def fromConfigurationReport(report: ConfigurationReport, rootInfo: ModuleID): ModuleGraph = { | ||
implicit def id(sbtId: ModuleID): GraphModuleId = | ||
GraphModuleId(sbtId.organization, sbtId.name, sbtId.revision) | ||
|
||
def moduleEdges(orgArt: OrganizationArtifactReport): Seq[(Module, Seq[Edge])] = { | ||
val chosenVersion = orgArt.modules.find(!_.evicted).map(_.module.revision) | ||
orgArt.modules.map(moduleEdge(chosenVersion)) | ||
} | ||
|
||
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) | ||
( | ||
Module( | ||
id = report.module, | ||
license = report.licenses.headOption.map(_._1), | ||
evictedByVersion = evictedByVersion, | ||
jarFile = jarFile, | ||
error = report.problem | ||
), | ||
report.callers.map(caller => Edge(caller.caller, report.module)) | ||
) | ||
} | ||
|
||
val (nodes, edges) = report.details.flatMap(moduleEdges).unzip | ||
val root = Module(rootInfo) | ||
|
||
ModuleGraph(root +: nodes, edges.flatten) | ||
} | ||
} |
Oops, something went wrong.