diff --git a/.travis.yml b/.travis.yml
index e17c5bb7f..c0a6784d3 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -15,7 +15,7 @@ env:
matrix:
- SBT_CMD="mimaReportBinaryIssues ; javafmtCheck ; Test / javafmtCheck; scalafmtCheckAll ; scalafmtSbtCheck; serverTestProj/scalafmtCheckAll; headerCheck ;test:headerCheck ;whitesourceOnPush ;test:compile; publishLocal; test; serverTestProj/test; doc; $UTIL_TESTS; ++$SCALA_213; $UTIL_TESTS"
- SBT_CMD="scripted actions/* apiinfo/* compiler-project/* ivy-deps-management/* reporter/* tests/* watch/* classloader-cache/* package/*"
- - SBT_CMD="scripted dependency-management/* plugins/* project-load/* java/* run/* nio/*"
+ - SBT_CMD="scripted dependency-graph/* dependency-management/* plugins/* project-load/* java/* run/* nio/*"
- SBT_CMD="repoOverrideTest:scripted dependency-management/*; scripted source-dependencies/* project/*"
matrix:
diff --git a/internal/util-logging/src/main/scala/sbt/internal/util/Terminal.scala b/internal/util-logging/src/main/scala/sbt/internal/util/Terminal.scala
index 2855423f8..14bff4939 100644
--- a/internal/util-logging/src/main/scala/sbt/internal/util/Terminal.scala
+++ b/internal/util-logging/src/main/scala/sbt/internal/util/Terminal.scala
@@ -308,6 +308,10 @@ object Terminal {
private[this] lazy val isColorEnabledProp: Option[Boolean] =
sys.props.get("sbt.color").orElse(sys.props.get("sbt.colour")).flatMap(parseLogOption)
+ private[sbt] def red(str: String, doRed: Boolean): String =
+ if (formatEnabledInEnv && doRed) Console.RED + str + Console.RESET
+ else str
+
/**
*
* @param isServer toggles whether or not this is a server of client process
diff --git a/main/src/main/scala/sbt/Defaults.scala b/main/src/main/scala/sbt/Defaults.scala
index 64adc35a5..5e1022128 100644
--- a/main/src/main/scala/sbt/Defaults.scala
+++ b/main/src/main/scala/sbt/Defaults.scala
@@ -880,7 +880,7 @@ object Defaults extends BuildCommon {
Seq(
initialCommands :== "",
cleanupCommands :== "",
- asciiGraphWidth :== 40
+ asciiGraphWidth :== 80
)
)
diff --git a/main/src/main/scala/sbt/internal/PluginDiscovery.scala b/main/src/main/scala/sbt/internal/PluginDiscovery.scala
index 62d481cac..3f6a9f450 100644
--- a/main/src/main/scala/sbt/internal/PluginDiscovery.scala
+++ b/main/src/main/scala/sbt/internal/PluginDiscovery.scala
@@ -52,6 +52,7 @@ object PluginDiscovery {
"sbt.plugins.SemanticdbPlugin" -> sbt.plugins.SemanticdbPlugin,
"sbt.plugins.JUnitXmlReportPlugin" -> sbt.plugins.JUnitXmlReportPlugin,
"sbt.plugins.Giter8TemplatePlugin" -> sbt.plugins.Giter8TemplatePlugin,
+ "sbt.plugins.DependencyGraphPlugin" -> sbt.plugins.DependencyGraphPlugin,
)
val detectedAutoPlugins = discover[AutoPlugin](AutoPlugins)
val allAutoPlugins = (defaultAutoPlugins ++ detectedAutoPlugins.modules) map {
diff --git a/main/src/main/scala/sbt/internal/SettingGraph.scala b/main/src/main/scala/sbt/internal/SettingGraph.scala
index be9f83f9d..fdf5f30ec 100644
--- a/main/src/main/scala/sbt/internal/SettingGraph.scala
+++ b/main/src/main/scala/sbt/internal/SettingGraph.scala
@@ -81,8 +81,12 @@ object Graph {
// [info] | +-baz
// [info] |
// [info] +-quux
- def toAscii[A](top: A, children: A => Seq[A], display: A => String, defaultWidth: Int): String = {
- val maxColumn = math.max(Terminal.get.getWidth, defaultWidth) - 8
+ def toAscii[A](
+ top: A,
+ children: A => Seq[A],
+ display: A => String,
+ maxColumn: Int
+ ): String = {
val twoSpaces = " " + " " // prevent accidentally being converted into a tab
def limitLine(s: String): String =
if (s.length > maxColumn) s.slice(0, maxColumn - 2) + ".."
@@ -96,21 +100,33 @@ object Graph {
}) +
s.slice(at + 1, s.length)
else s
- def toAsciiLines(node: A, level: Int): (String, Vector[String]) = {
- val line = limitLine((twoSpaces * level) + (if (level == 0) "" else "+-") + display(node))
- val cs = Vector(children(node): _*)
- val childLines = cs map { toAsciiLines(_, level + 1) }
- val withBar = childLines.zipWithIndex flatMap {
- case ((line, withBar), pos) if pos < (cs.size - 1) =>
- (line +: withBar) map { insertBar(_, 2 * (level + 1)) }
- case ((line, withBar), _) if withBar.lastOption.getOrElse(line).trim != "" =>
- (line +: withBar) ++ Vector(twoSpaces * (level + 1))
- case ((line, withBar), _) => line +: withBar
+ def toAsciiLines(node: A, level: Int, parents: Set[A]): Vector[String] =
+ if (parents contains node) // cycle
+ Vector(limitLine((twoSpaces * level) + "#-" + display(node) + " (cycle)"))
+ else {
+ val line = limitLine((twoSpaces * level) + (if (level == 0) "" else "+-") + display(node))
+ val cs = Vector(children(node): _*)
+ val childLines = cs map {
+ toAsciiLines(_, level + 1, parents + node)
+ }
+ val withBar = childLines.zipWithIndex flatMap {
+ case (lines, pos) if pos < (cs.size - 1) =>
+ lines map {
+ insertBar(_, 2 * (level + 1))
+ }
+ case (lines, pos) =>
+ if (lines.last.trim != "") lines ++ Vector(twoSpaces * (level + 1))
+ else lines
+ }
+ line +: withBar
}
- (line, withBar)
- }
- val (line, withBar) = toAsciiLines(top, 0)
- (line +: withBar).mkString("\n")
+ toAsciiLines(top, 0, Set.empty).mkString("\n")
+ }
+
+ def defaultColumnSize: Int = {
+ val termWidth = Terminal.console.getWidth
+ if (termWidth > 20) termWidth - 8
+ else 80 // ignore termWidth
}
}
diff --git a/main/src/main/scala/sbt/internal/graph/DependencyGraphKeys.scala b/main/src/main/scala/sbt/internal/graph/DependencyGraphKeys.scala
new file mode 100644
index 000000000..a02ae6a87
--- /dev/null
+++ b/main/src/main/scala/sbt/internal/graph/DependencyGraphKeys.scala
@@ -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
diff --git a/main/src/main/scala/sbt/internal/graph/GraphTransformations.scala b/main/src/main/scala/sbt/internal/graph/GraphTransformations.scala
new file mode 100644
index 000000000..c7385383d
--- /dev/null
+++ b/main/src/main/scala/sbt/internal/graph/GraphTransformations.scala
@@ -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)
+ }
+}
diff --git a/main/src/main/scala/sbt/internal/graph/backend/IvyReport.scala b/main/src/main/scala/sbt/internal/graph/backend/IvyReport.scala
new file mode 100644
index 000000000..99270b939
--- /dev/null
+++ b/main/src/main/scala/sbt/internal/graph/backend/IvyReport.scala
@@ -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()
+}
diff --git a/main/src/main/scala/sbt/internal/graph/backend/SbtUpdateReport.scala b/main/src/main/scala/sbt/internal/graph/backend/SbtUpdateReport.scala
new file mode 100644
index 000000000..5db194c8e
--- /dev/null
+++ b/main/src/main/scala/sbt/internal/graph/backend/SbtUpdateReport.scala
@@ -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)
+ }
+}
diff --git a/main/src/main/scala/sbt/internal/graph/model.scala b/main/src/main/scala/sbt/internal/graph/model.scala
new file mode 100644
index 000000000..f4d4676a1
--- /dev/null
+++ b/main/src/main/scala/sbt/internal/graph/model.scala
@@ -0,0 +1,105 @@
+/*
+ * 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 sjsonnew._
+import scala.collection.mutable.{ HashMap, MultiMap, Set }
+
+private[sbt] case class GraphModuleId(organization: String, name: String, version: String) {
+ def idString: String = organization + ":" + name + ":" + version
+}
+
+private[sbt] object GraphModuleId {
+ import sjsonnew.BasicJsonProtocol.StringJsonFormat
+ implicit val graphModuleIdIso = LList.iso[GraphModuleId, String :*: String :*: String :*: LNil](
+ { m: GraphModuleId =>
+ ("organization", m.organization) :*: ("name", m.name) :*: ("version", m.version) :*: LNil
+ }, {
+ case (_, organization) :*: (_, name) :*: (_, version) :*: LNil =>
+ GraphModuleId(organization, name, version)
+ }
+ )
+}
+
+private[sbt] case class Module(
+ id: GraphModuleId,
+ license: Option[String] = None,
+ extraInfo: String = "",
+ evictedByVersion: Option[String] = None,
+ jarFile: Option[File] = None,
+ error: Option[String] = None
+) {
+ def hadError: Boolean = error.isDefined
+ def isUsed: Boolean = !isEvicted
+ def isEvicted: Boolean = evictedByVersion.isDefined
+}
+
+private[sbt] object Module {
+ import sjsonnew.BasicJsonProtocol._
+ implicit val moduleIso = LList.iso[Module, GraphModuleId :*: Option[String] :*: String :*: Option[
+ String
+ ] :*: Option[File] :*: Option[String] :*: LNil](
+ { m: Module =>
+ ("id", m.id) :*: ("license", m.license) :*: ("extraInfo", m.extraInfo) :*:
+ ("evictedByVersion", m.evictedByVersion) :*: (
+ "jarFile",
+ m.jarFile
+ ) :*: ("error", m.error) :*: LNil
+ }, {
+ case (_, id) :*: (_, license) :*: (_, extraInfo) :*: (_, evictedByVersion) :*: (_, jarFile) :*: (
+ _,
+ error
+ ) :*: LNil =>
+ Module(id, license, extraInfo, evictedByVersion, jarFile, error)
+ }
+ )
+}
+
+private[sbt] case class ModuleGraph(nodes: Seq[Module], edges: Seq[Edge]) {
+ lazy val modules: Map[GraphModuleId, Module] =
+ nodes.map(n => (n.id, n)).toMap
+
+ def module(id: GraphModuleId): Module = modules(id)
+
+ lazy val dependencyMap: Map[GraphModuleId, Seq[Module]] =
+ createMap(identity)
+
+ lazy val reverseDependencyMap: Map[GraphModuleId, Seq[Module]] =
+ createMap { case (a, b) => (b, a) }
+
+ def createMap(
+ bindingFor: ((GraphModuleId, GraphModuleId)) => (GraphModuleId, GraphModuleId)
+ ): Map[GraphModuleId, Seq[Module]] = {
+ val m = new HashMap[GraphModuleId, Set[Module]] with MultiMap[GraphModuleId, Module]
+ edges.foreach { entry =>
+ val (f, t) = bindingFor(entry)
+ m.addBinding(f, module(t))
+ }
+ m.toMap.mapValues(_.toSeq.sortBy(_.id.idString)).withDefaultValue(Nil)
+ }
+
+ def roots: Seq[Module] =
+ nodes.filter(n => !edges.exists(_._2 == n.id)).sortBy(_.id.idString)
+}
+
+private[sbt] object ModuleGraph {
+ val empty = ModuleGraph(Seq.empty, Seq.empty)
+
+ import BasicJsonProtocol._
+ implicit val moduleGraphIso = LList.iso[ModuleGraph, Vector[Module] :*: Vector[Edge] :*: LNil](
+ { g: ModuleGraph =>
+ ("nodes", g.nodes.toVector) :*: ("edges", g.edges.toVector) :*: LNil
+ }, {
+ case (_, nodes: Vector[Module]) :*: (_, edges: Vector[Edge]) :*: LNil =>
+ ModuleGraph(nodes, edges)
+ }
+ )
+}
diff --git a/main/src/main/scala/sbt/internal/graph/package.scala b/main/src/main/scala/sbt/internal/graph/package.scala
new file mode 100644
index 000000000..f1fac27a6
--- /dev/null
+++ b/main/src/main/scala/sbt/internal/graph/package.scala
@@ -0,0 +1,14 @@
+/*
+ * sbt
+ * Copyright 2011 - 2018, Lightbend, Inc.
+ * Copyright 2008 - 2010, Mark Harrah
+ * Licensed under Apache License 2.0 (see LICENSE)
+ */
+
+package sbt
+package internal
+
+package object graph {
+ type Edge = (GraphModuleId, GraphModuleId)
+ def Edge(from: GraphModuleId, to: GraphModuleId): Edge = from -> to
+}
diff --git a/main/src/main/scala/sbt/internal/graph/rendering/AsciiTree.scala b/main/src/main/scala/sbt/internal/graph/rendering/AsciiTree.scala
new file mode 100644
index 000000000..33f37513a
--- /dev/null
+++ b/main/src/main/scala/sbt/internal/graph/rendering/AsciiTree.scala
@@ -0,0 +1,42 @@
+/*
+ * 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 rendering
+
+import sbt.internal.util.Terminal.red
+
+object AsciiTree {
+ def asciiTree(graph: ModuleGraph): String = {
+ val deps = graph.dependencyMap
+
+ // there should only be one root node (the project itself)
+ val roots = graph.roots
+ roots
+ .map { root =>
+ Graph
+ .toAscii[Module](
+ root,
+ node => deps.getOrElse(node.id, Seq.empty[Module]),
+ displayModule,
+ Graph.defaultColumnSize
+ )
+ }
+ .mkString("\n")
+ }
+
+ def displayModule(module: Module): String =
+ red(
+ module.id.idString +
+ module.extraInfo +
+ module.error.map(" (error: " + _ + ")").getOrElse("") +
+ module.evictedByVersion.map(_ formatted " (evicted by: %s)").getOrElse(""),
+ module.hadError
+ )
+}
diff --git a/sbt-dependency-graph/src/main/scala/net/virtualvoid/sbt/graph/rendering/DOT.scala b/main/src/main/scala/sbt/internal/graph/rendering/DOT.scala
similarity index 54%
rename from sbt-dependency-graph/src/main/scala/net/virtualvoid/sbt/graph/rendering/DOT.scala
rename to main/src/main/scala/sbt/internal/graph/rendering/DOT.scala
index dd63bacb3..6c984f1ca 100644
--- a/sbt-dependency-graph/src/main/scala/net/virtualvoid/sbt/graph/rendering/DOT.scala
+++ b/main/src/main/scala/sbt/internal/graph/rendering/DOT.scala
@@ -1,38 +1,33 @@
/*
- * Copyright 2015 Johannes Rudolph
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
+ * sbt
+ * Copyright 2011 - 2018, Lightbend, Inc.
+ * Copyright 2008 - 2010, Mark Harrah
+ * Licensed under Apache License 2.0 (see LICENSE)
*/
-package net.virtualvoid.sbt.graph
+package sbt
+package internal
+package graph
package rendering
object DOT {
val EvictedStyle = "stroke-dasharray: 5,5"
def dotGraph(
- graph: ModuleGraph,
- dotHead: String,
- nodeFormation: (String, String, String) ⇒ String,
- labelRendering: HTMLLabelRendering): String = {
+ graph: ModuleGraph,
+ dotHead: String,
+ nodeFormation: (String, String, String) => String,
+ labelRendering: HTMLLabelRendering
+ ): String = {
val nodes = {
for (n ← graph.nodes) yield {
val style = if (n.isEvicted) EvictedStyle else ""
- val label = nodeFormation(n.id.organisation, n.id.name, n.id.version)
+ val label = nodeFormation(n.id.organization, n.id.name, n.id.version)
""" "%s"[%s style="%s"]""".format(
n.id.idString,
labelRendering.renderLabel(label),
- style)
+ style
+ )
}
}.mkString("\n")
@@ -41,23 +36,31 @@ object DOT {
// add extra edges from evicted to evicted-by module
val evictedByEdges: Seq[Edge] =
- graph.nodes.filter(_.isEvicted).map(m ⇒ Edge(m.id, m.id.copy(version = m.evictedByVersion.get)))
+ graph.nodes
+ .filter(_.isEvicted)
+ .map(m => Edge(m.id, m.id.copy(version = m.evictedByVersion.get)))
// remove edges to new evicted-by module which is now replaced by a chain
// dependend -> [evicted] -> dependee
val evictionTargetEdges =
- graph.edges.filter(targetWasEvicted).map {
- case (from, evicted) ⇒ (from, evicted.copy(version = graph.module(evicted).evictedByVersion.get))
- }.toSet
+ graph.edges
+ .filter(targetWasEvicted)
+ .map {
+ case (from, evicted) =>
+ (from, evicted.copy(version = graph.module(evicted).evictedByVersion.get))
+ }
+ .toSet
val filteredEdges =
graph.edges
- .filterNot(e ⇒ originWasEvicted(e) || evictionTargetEdges(e)) ++ evictedByEdges
+ .filterNot(e => originWasEvicted(e) || evictionTargetEdges(e)) ++ evictedByEdges
val edges = {
for (e ← filteredEdges) yield {
- val extra = if (graph.module(e._1).isEvicted)
- s""" [label="Evicted By" style="$EvictedStyle"]""" else ""
+ val extra =
+ if (graph.module(e._1).isEvicted)
+ s""" [label="Evicted By" style="$EvictedStyle"]"""
+ else ""
""" "%s" -> "%s"%s""".format(e._1.idString, e._2.idString, extra)
}
}.mkString("\n")
@@ -68,6 +71,7 @@ object DOT {
sealed trait HTMLLabelRendering {
def renderLabel(labelText: String): String
}
+
/**
* Render HTML labels in Angle brackets as defined at http://graphviz.org/content/node-shapes#html
*/
diff --git a/main/src/main/scala/sbt/internal/graph/rendering/DagreHTML.scala b/main/src/main/scala/sbt/internal/graph/rendering/DagreHTML.scala
new file mode 100644
index 000000000..f00a197d2
--- /dev/null
+++ b/main/src/main/scala/sbt/internal/graph/rendering/DagreHTML.scala
@@ -0,0 +1,38 @@
+/*
+ * 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 rendering
+
+import java.io.File
+import java.net.{ URLEncoder, URI }
+
+import sbt.io.IO
+
+object DagreHTML {
+ def createLink(dotGraph: String, targetDirectory: File): URI = {
+ targetDirectory.mkdirs()
+ val graphHTML = new File(targetDirectory, "graph.html")
+ TreeView.saveResource("graph.html", graphHTML)
+ IO.write(new File(targetDirectory, "dependencies.dot"), dotGraph, IO.utf8)
+
+ val graphString =
+ URLEncoder
+ .encode(dotGraph, "utf8")
+ .replaceAllLiterally("+", "%20")
+
+ IO.write(
+ new File(targetDirectory, "dependencies.dot.js"),
+ s"""data = "$graphString";""",
+ IO.utf8
+ )
+
+ new URI(graphHTML.toURI.toString)
+ }
+}
diff --git a/main/src/main/scala/sbt/internal/graph/rendering/FlatList.scala b/main/src/main/scala/sbt/internal/graph/rendering/FlatList.scala
new file mode 100644
index 000000000..a0a842408
--- /dev/null
+++ b/main/src/main/scala/sbt/internal/graph/rendering/FlatList.scala
@@ -0,0 +1,20 @@
+/*
+ * 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 rendering
+
+object FlatList {
+ def render(display: Module => String)(graph: ModuleGraph): String =
+ graph.modules.values.toSeq.distinct
+ .filterNot(_.isEvicted)
+ .sortBy(m => (m.id.organization, m.id.name))
+ .map(display)
+ .mkString("\n")
+}
diff --git a/main/src/main/scala/sbt/internal/graph/rendering/GraphML.scala b/main/src/main/scala/sbt/internal/graph/rendering/GraphML.scala
new file mode 100644
index 000000000..024d3c6bd
--- /dev/null
+++ b/main/src/main/scala/sbt/internal/graph/rendering/GraphML.scala
@@ -0,0 +1,40 @@
+/*
+ * 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 rendering
+
+import scala.xml.XML
+
+object GraphML {
+ def saveAsGraphML(graph: ModuleGraph, outputFile: String): Unit = {
+ val nodesXml =
+ for (n ← graph.nodes)
+ yield
+
+ {n.id.idString}
+
+
+
+ val edgesXml =
+ for (e ← graph.edges)
+ yield
+
+ val xml =
+
+
+
+ {nodesXml}
+ {edgesXml}
+
+
+
+ XML.save(outputFile, xml)
+ }
+}
diff --git a/main/src/main/scala/sbt/internal/graph/rendering/LicenseInfo.scala b/main/src/main/scala/sbt/internal/graph/rendering/LicenseInfo.scala
new file mode 100644
index 000000000..27aa44708
--- /dev/null
+++ b/main/src/main/scala/sbt/internal/graph/rendering/LicenseInfo.scala
@@ -0,0 +1,26 @@
+/*
+ * 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 rendering
+
+object LicenseInfo {
+ def render(graph: ModuleGraph): String =
+ graph.nodes
+ .filter(_.isUsed)
+ .groupBy(_.license)
+ .toSeq
+ .sortBy(_._1)
+ .map {
+ case (license, modules) =>
+ license.getOrElse("No license specified") + "\n" +
+ modules.map(_.id.idString formatted "\t %s").mkString("\n")
+ }
+ .mkString("\n\n")
+}
diff --git a/main/src/main/scala/sbt/internal/graph/rendering/Statistics.scala b/main/src/main/scala/sbt/internal/graph/rendering/Statistics.scala
new file mode 100644
index 000000000..a52d4d387
--- /dev/null
+++ b/main/src/main/scala/sbt/internal/graph/rendering/Statistics.scala
@@ -0,0 +1,80 @@
+/*
+ * 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 rendering
+
+object Statistics {
+ def renderModuleStatsList(graph: ModuleGraph): String = {
+ case class ModuleStats(
+ id: GraphModuleId,
+ numDirectDependencies: Int,
+ numTransitiveDependencies: Int,
+ selfSize: Option[Long],
+ transitiveSize: Long,
+ transitiveDependencyStats: Map[GraphModuleId, ModuleStats]
+ ) {
+ def transitiveStatsWithSelf: Map[GraphModuleId, ModuleStats] =
+ transitiveDependencyStats + (id -> this)
+ }
+
+ def statsFor(moduleId: GraphModuleId): ModuleStats = {
+ val directDependencies = graph.dependencyMap(moduleId).filterNot(_.isEvicted).map(_.id)
+ val dependencyStats =
+ directDependencies.map(statsFor).flatMap(_.transitiveStatsWithSelf).toMap
+ val selfSize = graph.module(moduleId).jarFile.filter(_.exists).map(_.length)
+ val numDirectDependencies = directDependencies.size
+ val numTransitiveDependencies = dependencyStats.size
+ val transitiveSize = selfSize.getOrElse(0L) + dependencyStats
+ .map(_._2.selfSize.getOrElse(0L))
+ .sum
+
+ ModuleStats(
+ moduleId,
+ numDirectDependencies,
+ numTransitiveDependencies,
+ selfSize,
+ transitiveSize,
+ dependencyStats
+ )
+ }
+
+ def format(stats: ModuleStats): String = {
+ import stats._
+ def mb(bytes: Long): Double = bytes.toDouble / 1000000
+ val selfSize =
+ stats.selfSize match {
+ case Some(size) => f"${mb(size)}%7.3f"
+ case None => "-------"
+ }
+ f"${mb(transitiveSize)}%7.3f MB $selfSize MB $numTransitiveDependencies%4d $numDirectDependencies%4d ${id.idString}%s"
+ }
+
+ val allStats =
+ graph.roots
+ .flatMap(r => statsFor(r.id).transitiveStatsWithSelf)
+ .toMap
+ .values
+ .toSeq
+ .sortBy(s => (-s.transitiveSize, -s.numTransitiveDependencies))
+
+ val header = " TotSize JarSize #TDe #Dep Module\n"
+
+ header +
+ allStats.map(format).mkString("\n") +
+ """
+ |
+ |Columns are
+ | - Jar-Size including dependencies
+ | - Jar-Size
+ | - Number of transitive dependencies
+ | - Number of direct dependencies
+ | - ModuleID""".stripMargin
+ }
+}
diff --git a/main/src/main/scala/sbt/internal/graph/rendering/TreeView.scala b/main/src/main/scala/sbt/internal/graph/rendering/TreeView.scala
new file mode 100644
index 000000000..2bba9f20f
--- /dev/null
+++ b/main/src/main/scala/sbt/internal/graph/rendering/TreeView.scala
@@ -0,0 +1,80 @@
+/*
+ * 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 rendering
+
+import java.io.{ OutputStream, InputStream, FileOutputStream, File }
+import java.net.URI
+
+import graph.{ Module, ModuleGraph }
+import sbt.io.IO
+
+import scala.annotation.tailrec
+import scala.util.parsing.json.{ JSONArray, JSONObject }
+import com.github.ghik.silencer.silent
+
+@silent object TreeView {
+ def createJson(graph: ModuleGraph): String = {
+ val trees = graph.roots
+ .map(module => processSubtree(graph, module))
+ .toList
+ JSONArray(trees).toString
+ }
+
+ def createLink(graphJson: String, targetDirectory: File): URI = {
+ targetDirectory.mkdirs()
+ val graphHTML = new File(targetDirectory, "tree.html")
+ saveResource("tree.html", graphHTML)
+ IO.write(new File(targetDirectory, "tree.json"), graphJson, IO.utf8)
+ IO.write(new File(targetDirectory, "tree.data.js"), s"tree_data = $graphJson;", IO.utf8)
+ new URI(graphHTML.toURI.toString)
+ }
+
+ private def processSubtree(graph: ModuleGraph, module: Module): JSONObject = {
+ val children = graph.dependencyMap
+ .getOrElse(module.id, List())
+ .map(module => processSubtree(graph, module))
+ .toList
+ moduleAsJson(module, children)
+ }
+
+ private def moduleAsJson(module: Module, children: List[JSONObject]): JSONObject = {
+ val eviction = module.evictedByVersion.map(version => s" (evicted by $version)").getOrElse("")
+ val error = module.error.map(err => s" (errors: $err)").getOrElse("")
+ val text = module.id.idString + eviction + error
+ JSONObject(Map("text" -> text, "children" -> JSONArray(children)))
+ }
+
+ def saveResource(resourcePath: String, to: File): Unit = {
+ val is = getClass.getClassLoader.getResourceAsStream(resourcePath)
+ require(is ne null, s"Couldn't load '$resourcePath' from classpath.")
+
+ val fos = new FileOutputStream(to)
+ try copy(is, fos)
+ finally {
+ is.close()
+ fos.close()
+ }
+ }
+
+ def copy(from: InputStream, to: OutputStream): Unit = {
+ val buffer = new Array[Byte](65536)
+
+ @tailrec def rec(): Unit = {
+ val read = from.read(buffer)
+ if (read > 0) {
+ to.write(buffer, 0, read)
+ rec()
+ } else if (read == 0)
+ throw new IllegalStateException("InputStream.read returned 0")
+ }
+ rec()
+ }
+}
diff --git a/main/src/main/scala/sbt/plugins/DependencyGraphPlugin.scala b/main/src/main/scala/sbt/plugins/DependencyGraphPlugin.scala
new file mode 100644
index 000000000..dd546e5ab
--- /dev/null
+++ b/main/src/main/scala/sbt/plugins/DependencyGraphPlugin.scala
@@ -0,0 +1,329 @@
+/*
+ * sbt
+ * Copyright 2011 - 2018, Lightbend, Inc.
+ * Copyright 2008 - 2010, Mark Harrah
+ * Licensed under Apache License 2.0 (see LICENSE)
+ */
+
+package sbt
+package plugins
+
+import java.io.File
+
+import sbt.Def._
+import sbt.Keys._
+import sbt.SlashSyntax0._
+import sbt.PluginTrigger.AllRequirements
+import sbt.Project._
+import sbt.internal.graph._
+import sbt.internal.graph.backend.{ IvyReport, SbtUpdateReport }
+import sbt.internal.graph.rendering.{ DagreHTML, TreeView }
+import sbt.internal.librarymanagement._
+import sbt.internal.util.complete.{ Parser, Parsers }
+import sbt.io.IO
+import sbt.io.syntax._
+import sbt.librarymanagement._
+import sbt.librarymanagement.ivy.InlineIvyConfiguration
+import sbt.librarymanagement.Configurations.{
+ Compile,
+ IntegrationTest,
+ Optional,
+ Provided,
+ Runtime,
+ Test
+}
+// import Keys._
+
+object DependencyGraphPlugin extends AutoPlugin {
+ import sjsonnew.BasicJsonProtocol._
+
+ object autoImport extends DependencyGraphKeys
+
+ import autoImport._
+ override def trigger: PluginTrigger = AllRequirements
+ override def globalSettings: Seq[Def.Setting[_]] = Seq(
+ dependencyTreeIncludeScalaLibrary := false
+ )
+ override def projectSettings: Seq[Def.Setting[_]] = graphSettings
+ def graphSettings = baseSettings ++ reportSettings
+
+ def baseSettings =
+ Seq(
+ ivyReportFunction := ivyReportFunctionTask.value,
+ // disable the cached resolution engine (exposing a scoped `ivyModule` used directly by `updateTask`), as it
+ // generates artificial module descriptors which are internal to sbt, making it hard to reconstruct the
+ // dependency tree
+ ignoreMissingUpdate / updateOptions := updateOptions.value.withCachedResolution(false),
+ ignoreMissingUpdate / ivyConfiguration := {
+ // inTask will make sure the new definition will pick up `updateOptions in ignoreMissingUpdate`
+ inTask(ignoreMissingUpdate, Classpaths.mkIvyConfiguration).value
+ },
+ ignoreMissingUpdate / ivyModule := {
+ // concatenating & inlining ivySbt & ivyModule default task implementations, as `SbtAccess.inTask` does
+ // NOT correctly force the scope when applied to `TaskKey.toTask` instances (as opposed to raw
+ // implementations like `Classpaths.mkIvyConfiguration` or `Classpaths.updateTask`)
+ val is = new IvySbt((ivyConfiguration in ignoreMissingUpdate).value)
+ new is.Module(moduleSettings.value)
+ },
+ // don't fail on missing dependencies
+ ignoreMissingUpdate / updateConfiguration := updateConfiguration.value.withMissingOk(true),
+ ignoreMissingUpdate := {
+ // inTask will make sure the new definition will pick up `ivyModule/updateConfiguration in ignoreMissingUpdate`
+ inTask(ignoreMissingUpdate, Classpaths.updateTask).value
+ },
+ )
+
+ def reportSettings =
+ Seq(Compile, Test, IntegrationTest, Runtime, Provided, Optional).flatMap(ivyReportForConfig)
+
+ val renderingAlternatives: Seq[(TaskKey[Unit], ModuleGraph => String)] =
+ Seq(
+ dependencyTree -> rendering.AsciiTree.asciiTree _,
+ dependencyList -> rendering.FlatList.render(_.id.idString),
+ dependencyStats -> rendering.Statistics.renderModuleStatsList _,
+ dependencyLicenseInfo -> rendering.LicenseInfo.render _
+ )
+
+ def ivyReportForConfig(config: Configuration) =
+ inConfig(config)(
+ Seq(
+ ivyReport := {
+ Def
+ .task {
+ ivyReportFunction.value.apply(config.toString)
+ }
+ .dependsOn(ignoreMissingUpdate)
+ }.value,
+ crossProjectId := CrossVersion(scalaVersion.value, scalaBinaryVersion.value)(
+ projectID.value
+ ),
+ moduleGraphSbt :=
+ ignoreMissingUpdate.value
+ .configuration(configuration.value)
+ .map(report => SbtUpdateReport.fromConfigurationReport(report, crossProjectId.value))
+ .getOrElse(ModuleGraph.empty),
+ moduleGraphIvyReport := IvyReport.fromReportFile(absoluteReportPath(ivyReport.value)),
+ moduleGraph := {
+ sbtVersion.value match {
+ case Version(0, 13, x, _) if x >= 6 => moduleGraphSbt.value
+ case Version(1, _, _, _) => moduleGraphSbt.value
+ }
+ },
+ moduleGraph := {
+ // FIXME: remove busywork
+ val sv = scalaVersion.value
+ val moduleGraph = DependencyGraphKeys.moduleGraph.value
+ if (dependencyTreeIncludeScalaLibrary.value) moduleGraph
+ else GraphTransformations.ignoreScalaLibrary(sv, moduleGraph)
+ },
+ moduleGraphStore := (moduleGraph storeAs moduleGraphStore triggeredBy moduleGraph).value,
+ // browse
+ dependencyBrowseGraphTarget := { target.value / "browse-dependency-graph" },
+ dependencyBrowseGraphHTML := browseGraphHTMLTask.value,
+ dependencyBrowseGraph := openBrowser(dependencyBrowseGraphHTML).value,
+ dependencyBrowseTreeTarget := { target.value / "browse-dependency-tree" },
+ dependencyBrowseTreeHTML := browseTreeHTMLTask.value,
+ dependencyBrowseTree := openBrowser(dependencyBrowseTreeHTML).value,
+ // dot support
+ dependencyDotFile := { target.value / "dependencies-%s.dot".format(config.toString) },
+ dependencyDot / asString := rendering.DOT.dotGraph(
+ moduleGraph.value,
+ dependencyDotHeader.value,
+ dependencyDotNodeLabel.value,
+ rendering.DOT.AngleBrackets
+ ),
+ dependencyDot := writeToFile(dependencyDot / asString, dependencyDotFile).value,
+ dependencyDotHeader :=
+ """|digraph "dependency-graph" {
+ | graph[rankdir="LR"]
+ | edge [
+ | arrowtail="none"
+ | ]""".stripMargin,
+ dependencyDotNodeLabel := { (organization: String, name: String, version: String) =>
+ """%s %s %s""".format(organization, name, version)
+ },
+ // GraphML support
+ dependencyGraphMLFile := {
+ target.value / "dependencies-%s.graphml".format(config.toString)
+ },
+ dependencyGraphML := dependencyGraphMLTask.value,
+ whatDependsOn := {
+ val ArtifactPattern(org, name, versionFilter) = artifactPatternParser.parsed
+ val graph = moduleGraph.value
+ val modules =
+ versionFilter match {
+ case Some(version) => GraphModuleId(org, name, version) :: Nil
+ case None =>
+ graph.nodes.filter(m => m.id.organization == org && m.id.name == name).map(_.id)
+ }
+ val output =
+ modules
+ .map { module =>
+ rendering.AsciiTree
+ .asciiTree(GraphTransformations.reverseGraphStartingAt(graph, module))
+ }
+ .mkString("\n")
+
+ streams.value.log.info(output)
+ output
+ },
+ ) ++
+ renderingAlternatives.flatMap((renderingTaskSettings _).tupled)
+ )
+
+ def renderingTaskSettings(key: TaskKey[Unit], renderer: ModuleGraph => String): Seq[Setting[_]] =
+ Seq(
+ key := {
+ val s = streams.value
+ val str = (key / asString).value
+ s.log.info(str)
+ },
+ key / asString := renderer(moduleGraph.value),
+ key / toFile := {
+ val (targetFile, force) = targetFileAndForceParser.parsed
+ writeToFile(key.key.label, (asString in key).value, targetFile, force, streams.value)
+ },
+ )
+
+ def ivyReportFunctionTask = Def.task {
+ val ivyConfig = Keys.ivyConfiguration.value.asInstanceOf[InlineIvyConfiguration]
+ val projectID = Keys.projectID.value
+ val ivyModule = Keys.ivyModule.value
+
+ (config: String) => {
+ val org = projectID.organization
+ val name = crossName(ivyModule)
+ new File(ivyConfig.resolutionCacheDir.get, s"reports/$org-$name-$config.xml")
+ }
+ }
+
+ def dependencyGraphMLTask =
+ Def.task {
+ val resultFile = dependencyGraphMLFile.value
+ rendering.GraphML.saveAsGraphML(moduleGraph.value, resultFile.getAbsolutePath)
+ streams.value.log.info("Wrote dependency graph to '%s'" format resultFile)
+ resultFile
+ }
+
+ def browseGraphHTMLTask =
+ Def.task {
+ val dotGraph = rendering.DOT.dotGraph(
+ moduleGraph.value,
+ dependencyDotHeader.value,
+ dependencyDotNodeLabel.value,
+ rendering.DOT.LabelTypeHtml
+ )
+ val link = DagreHTML.createLink(dotGraph, target.value)
+ streams.value.log.info(s"HTML graph written to $link")
+ link
+ }
+
+ def browseTreeHTMLTask =
+ Def.task {
+ val renderedTree = TreeView.createJson(moduleGraph.value)
+ val link = TreeView.createLink(renderedTree, target.value)
+ streams.value.log.info(s"HTML tree written to $link")
+ link
+ }
+
+ def writeToFile(dataTask: TaskKey[String], fileTask: SettingKey[File]) =
+ Def.task {
+ val outFile = fileTask.value
+ IO.write(outFile, dataTask.value, IO.utf8)
+
+ streams.value.log.info("Wrote dependency graph to '%s'" format outFile)
+ outFile
+ }
+
+ def writeToFile(
+ what: String,
+ data: String,
+ targetFile: File,
+ force: Boolean,
+ streams: TaskStreams
+ ): File =
+ if (targetFile.exists && !force)
+ throw new RuntimeException(
+ s"Target file for $what already exists at ${targetFile.getAbsolutePath}. Use '-f' to override"
+ )
+ else {
+ IO.write(targetFile, data, IO.utf8)
+
+ streams.log.info(s"Wrote $what to '$targetFile'")
+ targetFile
+ }
+
+ def absoluteReportPath = (file: File) => file.getAbsolutePath
+
+ def openBrowser(uriKey: TaskKey[URI]) =
+ Def.task {
+ val uri = uriKey.value
+ streams.value.log.info("Opening in browser...")
+ java.awt.Desktop.getDesktop.browse(uri)
+ uri
+ }
+
+ case class ArtifactPattern(organization: String, name: String, version: Option[String])
+
+ import sbt.internal.util.complete.DefaultParsers._
+ val artifactPatternParser: Def.Initialize[State => Parser[ArtifactPattern]] =
+ Keys.resolvedScoped { ctx => (state: State) =>
+ val graph = Defaults.loadFromContext(moduleGraphStore, ctx, state) getOrElse ModuleGraph(
+ Nil,
+ Nil
+ )
+
+ graph.nodes
+ .map(_.id)
+ .groupBy(m => (m.organization, m.name))
+ .map {
+ case ((org, name), modules) =>
+ val versionParsers: Seq[Parser[Option[String]]] =
+ modules.map { id =>
+ token(Space ~> id.version).?
+ }
+
+ (Space ~> token(org) ~ token(Space ~> name) ~ oneOf(versionParsers)).map {
+ case ((org, name), version) => ArtifactPattern(org, name, version)
+ }
+ }
+ .reduceOption(_ | _)
+ .getOrElse {
+ // If the moduleGraphStore couldn't be loaded because no dependency tree command was run before, we should still provide a parser for the command.
+ ((Space ~> token(StringBasic, "")) ~ (Space ~> token(
+ StringBasic,
+ ""
+ )) ~ (Space ~> token(StringBasic, "")).?).map {
+ case ((org, mod), version) =>
+ ArtifactPattern(org, mod, version)
+ }
+ }
+ }
+ val shouldForceParser: Parser[Boolean] =
+ (Space ~> (Parser.literal("-f") | "--force")).?.map(_.isDefined)
+
+ val targetFileAndForceParser: Parser[(File, Boolean)] =
+ Parsers.fileParser(new File(".")) ~ shouldForceParser
+
+ // This is to support 0.13.8's InlineConfigurationWithExcludes while not forcing 0.13.8
+ type HasModule = {
+ val module: ModuleID
+ }
+ def crossName(ivyModule: IvySbt#Module) =
+ ivyModule.moduleSettings match {
+ case ic: ModuleDescriptorConfiguration => ic.module.name
+ case _ =>
+ throw new IllegalStateException(
+ "sbt-dependency-graph plugin currently only supports ModuleDescriptorConfiguration of ivy settings (the default in sbt)"
+ )
+ }
+
+ val VersionPattern = """(\d+)\.(\d+)\.(\d+)(?:-(.*))?""".r
+ object Version {
+ def unapply(str: String): Option[(Int, Int, Int, Option[String])] = str match {
+ case VersionPattern(major, minor, fix, appendix) =>
+ Some((major.toInt, minor.toInt, fix.toInt, Option(appendix)))
+ case _ => None
+ }
+ }
+}
diff --git a/sbt-dependency-graph/CHANGELOG.md b/sbt-dependency-graph/CHANGELOG.md
deleted file mode 100644
index 02eb5e41b..000000000
--- a/sbt-dependency-graph/CHANGELOG.md
+++ /dev/null
@@ -1,149 +0,0 @@
-# Changelog
-
-## Unreleased
- * [#184](https://github.com/jrudolph/sbt-dependency-graph/pull/184): Fix regression in 0.10.0-RC1 for recent sbt versions when
- `cachedResolution` (with coursier turned off). Thanks [@bjaglin](https://github.com/bjaglin) for the report and the fix.
-
-## Version 0.10.0-RC1 (2019-07-24)
- * [#136](https://github.com/jrudolph/sbt-dependency-graph/pull/136): Added `dependencyBrowseTree` to open a searchable dependency tree in the browser.
- Thanks, [@pcejrowski](https://github.com/pcejrowski) for contributing this feature.
- * [#163](https://github.com/jrudolph/sbt-dependency-graph/pull/163): Remove some usage of internal sbt APIs, this allows to run sbt-dependency-graph with sbt 1.3.0
- but results are not entirely correct.
- * [#165](https://github.com/jrudolph/sbt-dependency-graph/pull/165): For common operations introduce `asString`, `printToConsole`, and `toFile` subtasks
-
-## Version 0.9.2 (2018-08-26)
- * [#159](https://github.com/jrudolph/sbt-dependency-graph/pull/159): Fixed regression in `whatDependsOn` where task parser failed when no other sbt-dependency-graph task was called before
-
-## Version 0.9.1 (2018-07-17)
-
- * [#110](https://github.com/jrudolph/sbt-dependency-graph/issues/110): `whatDependsOn` can now be called without specifying a version. Thanks, @chikei for the initial implementation.
- * [#150](https://github.com/jrudolph/sbt-dependency-graph/issues/150): `ivyReport` now reports correct path again even for older sbt versions (< 0.13.16)
-
-## Version 0.9.0 (2017-10-25)
-
-This version (finally!) adds support for sbt 1.0. *sbt-dependency-graph* depends on a lot of internals from sbt to do its
-work which is why it was quite an effort to do the migration. Thanks [@MasseGuillaume](https://github.com/MasseGuillaume) from Scala Center,
-[@2m](https://github.com/2m), and [@xuwei-k](https://github.com/xuwei-k) for helping out with the effort.
-
-The plugin is cross-built for sbt 0.13 (and will continued to be for while). The `dependencyGraph` task is currently not
-supported on sbt 1.0. Use `dependencyBrowseGraph`, instead.
-
-## Version 0.8.2 (2016-02-01)
-
-This is a maintenance release [fixing](https://github.com/jrudolph/sbt-dependency-graph/issues/89) `dependencyBrowseGraph`
-in the latest Chrome versions. Thanks [@chtefi](https://github.com/chtefi)!
-
-## Version 0.8.1 (2016-01-08)
-
-This is a maintenance release fixing a regression in 0.8.0 and adding two small features.
-
-All changes:
-
- * [#84](https://github.com/jrudolph/sbt-dependency-graph/issues/84): Fix regression of DOT label rendering introduced in 0.8.0.
- * [#83](https://github.com/jrudolph/sbt-dependency-graph/issues/83): Added new task `dependencyStats` which prints a
- simple table of jar sizes for all your dependencies. Handy if you want to know why your assembled jar gets so big.
- * [#85](https://github.com/jrudolph/sbt-dependency-graph/issues/85): Added new task `dependencyList` which prints a
- flat, deduplicated list of all the transitive dependencies.
-
-## Version 0.8.0 (2015-11-26)
-
-sbt-dependency-graph is finally an AutoPlugin and can now show the dependency graph in the browser directly.
-
-### New features
-
- - (experimental) open dependency graph directly in the browser with `dependencyBrowseGraph` ([#29](https://github.com/jrudolph/sbt-dependency-graph/issues/29))
- 
-
- - this plugin is finally an sbt AutoPlugin and it is automatically enabled
- ([#51](https://github.com/jrudolph/sbt-dependency-graph/issues/51))
-
-**Note: To update from 0.7.x remove the `net.virtualvoid.sbt.graph.Plugin.graphSettings` line from your configurations.**
-
-### Other changes
-
- - a new backend was implemented which accesses the in-memory dependency data structures of sbt directly. The plugin doesn't
- require accessing the ivy report XML any more (the old backend can still be wired in for comparisons if needed) which
- should have solved the race condition and the dreaded `FileNotFoundException` ([#39](https://github.com/jrudolph/sbt-dependency-graph/issues/39))
- in multi-module projects. The new backend is only used for sbt >= 0.13.6.
- - code was restructured which touched a lot of the classes but didn't change the function or syntax of settings and tasks.
- - fixed [#77](https://github.com/jrudolph/sbt-dependency-graph/issues/77)
-
-
-## Version 0.7.5 (2015-03-30)
-
-This is a maintenance release adding support for sbt 0.13.8.
-
-All changes:
-
- * [#67](https://github.com/jrudolph/sbt-dependency-graph/issues/67): Added support for sbt 0.13.8. Thanks
- [@eed3si9n](https://github.com/eed3si9n) for the fix.
- * [#37](https://github.com/jrudolph/sbt-dependency-graph/issues/37): Don't fail with StringIndexOutOfBoundsException
- for deep trees.
- * [#44](https://github.com/jrudolph/sbt-dependency-graph/issues/44): Only match scala lib by org/name.
- Thanks [@2beaucoup](https://github.com/2beaucoup) for the fix.
-
-## Version 0.7.4 (2013-06-26)
-
-This is a maintenance release fixing an exception when generating graphs without a terminal [#32](https://github.com/jrudolph/sbt-dependency-graph/issues/32).
-
-## Version 0.7.3 (2013-04-28)
-
-This is a maintenance release. Following issues have been fixed:
-
- * [#27](https://github.com/jrudolph/sbt-dependency-graph/issues/27): A dependency configured with
- a version range was not properly associated with its dependant.
- * [#30](https://github.com/jrudolph/sbt-dependency-graph/issues/30) & [#31](https://github.com/jrudolph/sbt-dependency-graph/issues/31):
- Make it work again with sbt 0.12.3. The path of the dependency resolution file changed in sbt 0.12.3.
- Thanks [ebowman](https://github.com/ebowman) for the fix.
-
-## Version 0.7.2 (2013-03-02)
-
-This is a maintenance release. Following issues have been fixed:
-
- * [#27](https://github.com/jrudolph/sbt-dependency-graph/issues/27): A dependency configured with
- a version range was not properly associated with its dependant.
-
-
-## Version 0.7.1
-
-New features in this version:
-
- * `dependency-license-info`: show dependencies grouped by declared license
- * `dependency-dot`: create dot file from dependency graph. Contributed by
- [berleon](https://github.com/berleon).
-
-## Version 0.7.0 (2012-10-24)
-
-New features in this version:
-
- * `dependency-graph` now renders a real graph. Thanks go to [Matt Russell](https://github.com/mdr/) for
- this added awesomeness.
- * The tree output from previous versions is now available with `dependency-tree`.
- * New task `what-depends-on` showing reverse dependency tree for a selected module (incl. tab-completion for modules)
- * Don't fail in cases of a missing dependency. Show errors directly in the output.
- * Show info about evicted versions.
- * By default, exclude scala-library dependency and append `[S]` to the artifact name instead. Set
- `filter-scala-library` to `false` to disable this feature.
- * Works with sbt 0.12.1. The ivy report files were moved to a new location making an update necessary.
-
-
-## Version 0.6.0 (2012-05-23)
-
-New features in this version:
-
- * `dependency-graph` task now prints the dependency graph to the console
- (contributed by @gseitz)
- * `dependency-graph-ml` contains now the old functionality of `dependency-graph`
- which generates a `.graphml` file. Nodes now contain the dependency version as well (contributed by @gseitz).
- * The output filename of `dependency-graph-ml` has been changed to include the configuration name. It is now
- configurable using the `dependency-graph-ml-file` setting.
- * The common `scalaVersion in update` idiom to support Scala 2.9.1 libraries in a
- Scala 2.9.2 broke the plugin in 0.5.2, because it wouldn't find the ivy report xml file
- any more. This was fixed.
- * All tasks are scoped by configuration.
-
-## Version 0.5.2 (2012-02-13)
-
-## Version 0.5.1 (2011-11-18)
-
-## Version 0.5 (2011-11-15)
\ No newline at end of file
diff --git a/sbt-dependency-graph/LICENSE b/sbt-dependency-graph/LICENSE
deleted file mode 100644
index f49a4e16e..000000000
--- a/sbt-dependency-graph/LICENSE
+++ /dev/null
@@ -1,201 +0,0 @@
- Apache License
- Version 2.0, January 2004
- http://www.apache.org/licenses/
-
- TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
-
- 1. Definitions.
-
- "License" shall mean the terms and conditions for use, reproduction,
- and distribution as defined by Sections 1 through 9 of this document.
-
- "Licensor" shall mean the copyright owner or entity authorized by
- the copyright owner that is granting the License.
-
- "Legal Entity" shall mean the union of the acting entity and all
- other entities that control, are controlled by, or are under common
- control with that entity. For the purposes of this definition,
- "control" means (i) the power, direct or indirect, to cause the
- direction or management of such entity, whether by contract or
- otherwise, or (ii) ownership of fifty percent (50%) or more of the
- outstanding shares, or (iii) beneficial ownership of such entity.
-
- "You" (or "Your") shall mean an individual or Legal Entity
- exercising permissions granted by this License.
-
- "Source" form shall mean the preferred form for making modifications,
- including but not limited to software source code, documentation
- source, and configuration files.
-
- "Object" form shall mean any form resulting from mechanical
- transformation or translation of a Source form, including but
- not limited to compiled object code, generated documentation,
- and conversions to other media types.
-
- "Work" shall mean the work of authorship, whether in Source or
- Object form, made available under the License, as indicated by a
- copyright notice that is included in or attached to the work
- (an example is provided in the Appendix below).
-
- "Derivative Works" shall mean any work, whether in Source or Object
- form, that is based on (or derived from) the Work and for which the
- editorial revisions, annotations, elaborations, or other modifications
- represent, as a whole, an original work of authorship. For the purposes
- of this License, Derivative Works shall not include works that remain
- separable from, or merely link (or bind by name) to the interfaces of,
- the Work and Derivative Works thereof.
-
- "Contribution" shall mean any work of authorship, including
- the original version of the Work and any modifications or additions
- to that Work or Derivative Works thereof, that is intentionally
- submitted to Licensor for inclusion in the Work by the copyright owner
- or by an individual or Legal Entity authorized to submit on behalf of
- the copyright owner. For the purposes of this definition, "submitted"
- means any form of electronic, verbal, or written communication sent
- to the Licensor or its representatives, including but not limited to
- communication on electronic mailing lists, source code control systems,
- and issue tracking systems that are managed by, or on behalf of, the
- Licensor for the purpose of discussing and improving the Work, but
- excluding communication that is conspicuously marked or otherwise
- designated in writing by the copyright owner as "Not a Contribution."
-
- "Contributor" shall mean Licensor and any individual or Legal Entity
- on behalf of whom a Contribution has been received by Licensor and
- subsequently incorporated within the Work.
-
- 2. Grant of Copyright License. Subject to the terms and conditions of
- this License, each Contributor hereby grants to You a perpetual,
- worldwide, non-exclusive, no-charge, royalty-free, irrevocable
- copyright license to reproduce, prepare Derivative Works of,
- publicly display, publicly perform, sublicense, and distribute the
- Work and such Derivative Works in Source or Object form.
-
- 3. Grant of Patent License. Subject to the terms and conditions of
- this License, each Contributor hereby grants to You a perpetual,
- worldwide, non-exclusive, no-charge, royalty-free, irrevocable
- (except as stated in this section) patent license to make, have made,
- use, offer to sell, sell, import, and otherwise transfer the Work,
- where such license applies only to those patent claims licensable
- by such Contributor that are necessarily infringed by their
- Contribution(s) alone or by combination of their Contribution(s)
- with the Work to which such Contribution(s) was submitted. If You
- institute patent litigation against any entity (including a
- cross-claim or counterclaim in a lawsuit) alleging that the Work
- or a Contribution incorporated within the Work constitutes direct
- or contributory patent infringement, then any patent licenses
- granted to You under this License for that Work shall terminate
- as of the date such litigation is filed.
-
- 4. Redistribution. You may reproduce and distribute copies of the
- Work or Derivative Works thereof in any medium, with or without
- modifications, and in Source or Object form, provided that You
- meet the following conditions:
-
- (a) You must give any other recipients of the Work or
- Derivative Works a copy of this License; and
-
- (b) You must cause any modified files to carry prominent notices
- stating that You changed the files; and
-
- (c) You must retain, in the Source form of any Derivative Works
- that You distribute, all copyright, patent, trademark, and
- attribution notices from the Source form of the Work,
- excluding those notices that do not pertain to any part of
- the Derivative Works; and
-
- (d) If the Work includes a "NOTICE" text file as part of its
- distribution, then any Derivative Works that You distribute must
- include a readable copy of the attribution notices contained
- within such NOTICE file, excluding those notices that do not
- pertain to any part of the Derivative Works, in at least one
- of the following places: within a NOTICE text file distributed
- as part of the Derivative Works; within the Source form or
- documentation, if provided along with the Derivative Works; or,
- within a display generated by the Derivative Works, if and
- wherever such third-party notices normally appear. The contents
- of the NOTICE file are for informational purposes only and
- do not modify the License. You may add Your own attribution
- notices within Derivative Works that You distribute, alongside
- or as an addendum to the NOTICE text from the Work, provided
- that such additional attribution notices cannot be construed
- as modifying the License.
-
- You may add Your own copyright statement to Your modifications and
- may provide additional or different license terms and conditions
- for use, reproduction, or distribution of Your modifications, or
- for any such Derivative Works as a whole, provided Your use,
- reproduction, and distribution of the Work otherwise complies with
- the conditions stated in this License.
-
- 5. Submission of Contributions. Unless You explicitly state otherwise,
- any Contribution intentionally submitted for inclusion in the Work
- by You to the Licensor shall be under the terms and conditions of
- this License, without any additional terms or conditions.
- Notwithstanding the above, nothing herein shall supersede or modify
- the terms of any separate license agreement you may have executed
- with Licensor regarding such Contributions.
-
- 6. Trademarks. This License does not grant permission to use the trade
- names, trademarks, service marks, or product names of the Licensor,
- except as required for reasonable and customary use in describing the
- origin of the Work and reproducing the content of the NOTICE file.
-
- 7. Disclaimer of Warranty. Unless required by applicable law or
- agreed to in writing, Licensor provides the Work (and each
- Contributor provides its Contributions) on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
- implied, including, without limitation, any warranties or conditions
- of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
- PARTICULAR PURPOSE. You are solely responsible for determining the
- appropriateness of using or redistributing the Work and assume any
- risks associated with Your exercise of permissions under this License.
-
- 8. Limitation of Liability. In no event and under no legal theory,
- whether in tort (including negligence), contract, or otherwise,
- unless required by applicable law (such as deliberate and grossly
- negligent acts) or agreed to in writing, shall any Contributor be
- liable to You for damages, including any direct, indirect, special,
- incidental, or consequential damages of any character arising as a
- result of this License or out of the use or inability to use the
- Work (including but not limited to damages for loss of goodwill,
- work stoppage, computer failure or malfunction, or any and all
- other commercial damages or losses), even if such Contributor
- has been advised of the possibility of such damages.
-
- 9. Accepting Warranty or Additional Liability. While redistributing
- the Work or Derivative Works thereof, You may choose to offer,
- and charge a fee for, acceptance of support, warranty, indemnity,
- or other liability obligations and/or rights consistent with this
- License. However, in accepting such obligations, You may act only
- on Your own behalf and on Your sole responsibility, not on behalf
- of any other Contributor, and only if You agree to indemnify,
- defend, and hold each Contributor harmless for any liability
- incurred by, or claims asserted against, such Contributor by reason
- of your accepting any such warranty or additional liability.
-
- END OF TERMS AND CONDITIONS
-
- APPENDIX: How to apply the Apache License to your work.
-
- To apply the Apache License to your work, attach the following
- boilerplate notice, with the fields enclosed by brackets "[]"
- replaced with your own identifying information. (Don't include
- the brackets!) The text should be enclosed in the appropriate
- comment syntax for the file format. We also recommend that a
- file or class name and description of purpose be included on the
- same "printed page" as the copyright notice for easier
- identification within third-party archives.
-
- Copyright [yyyy] [name of copyright owner]
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
\ No newline at end of file
diff --git a/sbt-dependency-graph/NOTICE b/sbt-dependency-graph/NOTICE
deleted file mode 100644
index 282e7e8e5..000000000
--- a/sbt-dependency-graph/NOTICE
+++ /dev/null
@@ -1,26 +0,0 @@
-AsciiTreeLayout.scala is copied from sbt and is distributed under the following license:
-
-Copyright (c) 2008, 2009, 2010 Steven Blundy, Josh Cough, Mark Harrah, Stuart Roebuck, Tony Sloane, Vesa Vilhonen, Jason Zaugg
-All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions
-are met:
-1. Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
-2. Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-3. The name of the author may not be used to endorse or promote products
- derived from this software without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
-IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
-OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
-IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
-INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
-NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
-THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/sbt-dependency-graph/PUBLISHING b/sbt-dependency-graph/PUBLISHING
deleted file mode 100644
index 1f728acbf..000000000
--- a/sbt-dependency-graph/PUBLISHING
+++ /dev/null
@@ -1,12 +0,0 @@
-Before publishing:
-
- * create entry in CHANGELOG
- * update version in README
-
- * run `;^ clean; ^ test:compile; ^ test; ^ scripted; ^publishSigned`
-
- * test staged version in sonatype
- * release from sonatype
-
-After publishing:
- * push master and tags
diff --git a/sbt-dependency-graph/README.md b/sbt-dependency-graph/README.md
deleted file mode 100644
index e2b07689f..000000000
--- a/sbt-dependency-graph/README.md
+++ /dev/null
@@ -1,97 +0,0 @@
-# sbt-dependency-graph
-
-[](https://gitter.im/jrudolph/sbt-dependency-graph?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
-
-Visualize your project's dependencies.
-
-**Note: Under sbt >= 1.3.x some features might currently not work as expected or not at all (like `dependencyLicenses`).**
-
-## Usage Instructions
-
-sbt-dependency-graph is an informational tool rather than one that changes your build, so you will more than likely wish to
-install it as a [global plugin] so that you can use it in any SBT project without the need to explicitly add it to each one. To do
-this, add the plugin dependency to `~/.sbt/0.13/plugins/plugins.sbt` for sbt 0.13 or `~/.sbt/1.0/plugins/plugins.sbt` for sbt 1.0:
-
-```scala
-addSbtPlugin("net.virtual-void" % "sbt-dependency-graph" % "0.10.0-RC1")
-```
-
-To add the plugin only to a single project, put this line into `project/plugins.sbt` of your project, instead.
-
-The plugin currently supports sbt versions >= 0.13.10 and sbt 1.0.x. For versions supporting older versions of sbt see
-the notes of version [0.8.2](https://github.com/jrudolph/sbt-dependency-graph/tree/v0.8.2#compatibility-notes).
-
-## Main Tasks
-
- * `dependencyTree`: Shows an ASCII tree representation of the project's dependencies
- * `dependencyBrowseGraph`: Opens a browser window with a visualization of the dependency graph (courtesy of graphlib-dot + dagre-d3).
- * `dependencyBrowseTree`: Opens a browser window with a visualization of the dependency tree (courtesy of jstree).
- * `dependencyList`: Shows a flat list of all transitive dependencies on the sbt console (sorted by organization and name)
- * `whatDependsOn ?`: Find out what depends on an artifact. Shows a reverse dependency
- tree for the selected module. The `` argument is optional.
- * `dependencyLicenseInfo`: show dependencies grouped by declared license
- * `dependencyStats`: Shows a table with each module a row with (transitive) Jar sizes and number of dependencies
- * `dependencyGraphMl`: Generates a `.graphml` file with the project's dependencies to `target/dependencies-.graphml`.
- Use e.g. [yEd](http://www.yworks.com/en/products_yed_about.html) to format the graph to your needs.
- * `dependencyDot`: Generates a .dot file with the project's dependencies to `target/dependencies-.dot`.
- Use [graphviz](http://www.graphviz.org/) to render it to your preferred graphic format.
- * `dependencyGraph`: Shows an ASCII graph of the project's dependencies on the sbt console (only supported on sbt 0.13)
- * `ivyReport`: Lets ivy generate the resolution report for you project. Use
- `show ivyReport` for the filename of the generated report
-
-The following tasks also support the `toFile` subtask to save the contents to a file:
-
- * `dependencyTree`
- * `dependencyList`
- * `dependencyStats`
- * `dependencyLicenseInfo`
-
-The `toFile` subtask has the following syntax:
-
-```
-:::toFile [-f|--force]
-```
-
-Use `-f` to force overwriting an existing file.
-
-E.g. `test:dependencyStats::toFile target/depstats.txt` will write the output of the `dependencyStats` in the `test`
-configuration to the file `target/depstats.txt` but would not overwrite an existing file.
-
-All tasks can be scoped to a configuration to get the report for a specific configuration. `test:dependencyGraph`,
-for example, prints the dependencies in the `test` configuration. If you don't specify any configuration, `compile` is
-assumed as usual.
-
-Note: If you want to run tasks with parameters from outside the sbt shell, make sure to put the whole task invocation in
-quotes, e.g. `sbt "whatDependsOn "`.
-
-## Configuration settings
-
- * `filterScalaLibrary`: Defines if the scala library should be excluded from the output of the dependency-* functions.
- If `true`, instead of showing the dependency `"[S]"` is appended to the artifact name. Set to `false` if
- you want the scala-library dependency to appear in the output. (default: true)
- * `dependencyGraphMLFile`: a setting which allows configuring the output path of `dependency-graph-ml`.
- * `dependencyDotFile`: a setting which allows configuring the output path of `dependency-dot`.
- * `dependencyDotHeader`: a setting to customize the header of the dot file (e.g. to set your preferred node shapes).
- * `dependencyDotNodeLabel`: defines the format of a node label
- (default set to `[organisation] [name] [version]`)
-
-E.g. in `build.sbt` you can change configuration settings like this:
-
-```scala
-filterScalaLibrary := false // include scala library in output
-
-dependencyDotFile := file("dependencies.dot") //render dot file to `./dependencies.dot`
-```
-
-## Known issues
-
- * [#19]: There's an unfixed bug with graph generation for particular layouts. Workaround:
- Use `dependency-tree` instead of `dependency-graph`.
-
-## License
-
-Published under the [Apache License 2.0](http://en.wikipedia.org/wiki/Apache_license).
-
-[global plugin]: http://www.scala-sbt.org/0.13/tutorial/Using-Plugins.html#Global+plugins
-[global build configuration]: http://www.scala-sbt.org/0.13/docs/Global-Settings.html
-[#19]: https://github.com/jrudolph/sbt-dependency-graph/issues/19
diff --git a/sbt-dependency-graph/build.sbt b/sbt-dependency-graph/build.sbt
deleted file mode 100644
index 27799adea..000000000
--- a/sbt-dependency-graph/build.sbt
+++ /dev/null
@@ -1,30 +0,0 @@
-enablePlugins(ScriptedPlugin)
-
-scriptedLaunchOpts += s"-Dproject.version=${version.value}"
-
-libraryDependencies ++= {
- if ((sbtVersion in pluginCrossBuild).value startsWith "0.13")
- Seq("com.github.mdr" %% "ascii-graphs" % "0.0.3")
- else
- Nil
-}
-
-
-libraryDependencies += "org.specs2" %% "specs2-core" % "3.10.0" % Test
-
-libraryDependencies += Defaults.sbtPluginExtra(
- "com.dwijnand" % "sbt-compat" % "1.2.6",
- (sbtBinaryVersion in pluginCrossBuild).value,
- (scalaBinaryVersion in update).value
-)
-
-crossSbtVersions := Seq("1.2.7", "0.13.18")
-
-scalacOptions ++= Seq(
- "-deprecation",
- "-encoding", "UTF-8",
- "-feature",
- "-unchecked"
-)
-
-ScalariformSupport.formatSettings
diff --git a/sbt-dependency-graph/project.sbt b/sbt-dependency-graph/project.sbt
deleted file mode 100644
index 8d6305446..000000000
--- a/sbt-dependency-graph/project.sbt
+++ /dev/null
@@ -1,9 +0,0 @@
-sbtPlugin := true
-
-name := "sbt-dependency-graph"
-
-organization := "net.virtual-void"
-
-homepage := Some(url("http://github.com/jrudolph/sbt-dependency-graph"))
-
-licenses in GlobalScope += "Apache License 2.0" -> url("https://github.com/jrudolph/sbt-dependency-graph/raw/master/LICENSE")
diff --git a/sbt-dependency-graph/project/ScalariformSupport.scala b/sbt-dependency-graph/project/ScalariformSupport.scala
deleted file mode 100644
index 665a9e6fe..000000000
--- a/sbt-dependency-graph/project/ScalariformSupport.scala
+++ /dev/null
@@ -1,20 +0,0 @@
-import sbt._
-
-import com.typesafe.sbt.SbtScalariform
-import com.typesafe.sbt.SbtScalariform.ScalariformKeys
-
-object ScalariformSupport {
- lazy val formatSettings = SbtScalariform.scalariformSettings ++ Seq(
- ScalariformKeys.preferences in Compile := formattingPreferences,
- ScalariformKeys.preferences in Test := formattingPreferences
- )
-
- import scalariform.formatter.preferences._
- def formattingPreferences =
- FormattingPreferences()
- .setPreference(RewriteArrowSymbols, true)
- .setPreference(AlignParameters, true)
- .setPreference(AlignSingleLineCaseStatements, true)
- .setPreference(DoubleIndentClassDeclaration, true)
-
-}
diff --git a/sbt-dependency-graph/project/build.properties b/sbt-dependency-graph/project/build.properties
deleted file mode 100644
index 72f902892..000000000
--- a/sbt-dependency-graph/project/build.properties
+++ /dev/null
@@ -1 +0,0 @@
-sbt.version=1.2.7
diff --git a/sbt-dependency-graph/project/pgp.sbt b/sbt-dependency-graph/project/pgp.sbt
deleted file mode 100644
index 2efcc4b69..000000000
--- a/sbt-dependency-graph/project/pgp.sbt
+++ /dev/null
@@ -1 +0,0 @@
-addSbtPlugin("com.jsuereth" % "sbt-pgp" % "1.1.0")
diff --git a/sbt-dependency-graph/project/plugins.sbt b/sbt-dependency-graph/project/plugins.sbt
deleted file mode 100644
index cb24a862c..000000000
--- a/sbt-dependency-graph/project/plugins.sbt
+++ /dev/null
@@ -1,4 +0,0 @@
-libraryDependencies += "org.scala-sbt" %% "scripted-plugin" % sbtVersion.value
-
-addSbtPlugin("org.scalariform" % "sbt-scalariform" % "1.8.2")
-addSbtPlugin("com.dwijnand" % "sbt-dynver" % "2.0.0")
diff --git a/sbt-dependency-graph/publish.sbt b/sbt-dependency-graph/publish.sbt
deleted file mode 100644
index efef315bc..000000000
--- a/sbt-dependency-graph/publish.sbt
+++ /dev/null
@@ -1,31 +0,0 @@
-publishTo := {
- val nexus = "https://oss.sonatype.org/"
- Some {
- if (version.value.trim.contains("+")) "snapshots" at nexus + "content/repositories/snapshots"
- else "releases" at nexus + "service/local/staging/deploy/maven2"
- }
-}
-
-publishMavenStyle := true
-
-publishArtifact in Test := false
-
-pomIncludeRepository := { _ => false }
-
-scmInfo := Some(
- ScmInfo(
- browseUrl = url("https://github.com/jrudolph/sbt-dependency-graph"),
- connection = "scm:git:git@github.com:jrudolph/sbt-dependency-graph.git"
- )
-)
-
-developers := List(
- Developer(
- "jrudolph",
- "Johannes Rudolph",
- "johannes.rudolph@gmail.com",
- url("https://virtual-void.net")
- )
-)
-
-useGpg := true
diff --git a/sbt-dependency-graph/src/main/resources/graph.html b/sbt-dependency-graph/src/main/resources/graph.html
deleted file mode 100644
index 4ea8baba6..000000000
--- a/sbt-dependency-graph/src/main/resources/graph.html
+++ /dev/null
@@ -1,115 +0,0 @@
-
-
-
-
-
-Dependency Graph
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/sbt-dependency-graph/src/main/resources/tree.html b/sbt-dependency-graph/src/main/resources/tree.html
deleted file mode 100644
index 909a9b82e..000000000
--- a/sbt-dependency-graph/src/main/resources/tree.html
+++ /dev/null
@@ -1,49 +0,0 @@
-
-
-
-
- dependencyBrowseTree
-
-
-
-
-
-
-
-
-
-
-
-
Dependencies
-Search:
-
-
-
-
-
\ No newline at end of file
diff --git a/sbt-dependency-graph/src/main/scala-sbt-0.13/net/virtualvoid/sbt/graph/ModuleGraphProtocolCompat.scala b/sbt-dependency-graph/src/main/scala-sbt-0.13/net/virtualvoid/sbt/graph/ModuleGraphProtocolCompat.scala
deleted file mode 100644
index d28f20d8b..000000000
--- a/sbt-dependency-graph/src/main/scala-sbt-0.13/net/virtualvoid/sbt/graph/ModuleGraphProtocolCompat.scala
+++ /dev/null
@@ -1,3 +0,0 @@
-package net.virtualvoid.sbt.graph
-
-trait ModuleGraphProtocolCompat
diff --git a/sbt-dependency-graph/src/main/scala-sbt-0.13/net/virtualvoid/sbt/graph/rendering/AsciiGraph.scala b/sbt-dependency-graph/src/main/scala-sbt-0.13/net/virtualvoid/sbt/graph/rendering/AsciiGraph.scala
deleted file mode 100644
index f1c83ec18..000000000
--- a/sbt-dependency-graph/src/main/scala-sbt-0.13/net/virtualvoid/sbt/graph/rendering/AsciiGraph.scala
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- * Copyright 2015 Johannes Rudolph
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package net.virtualvoid.sbt.graph
-package rendering
-
-import com.github.mdr.ascii.layout._
-import net.virtualvoid.sbt.graph.DependencyGraphKeys._
-import sbt.Keys._
-
-object AsciiGraph {
- def asciiGraph(graph: ModuleGraph): String =
- Layouter.renderGraph(buildAsciiGraph(graph))
-
- private def buildAsciiGraph(moduleGraph: ModuleGraph): Graph[String] = {
- def renderVertex(module: Module): String =
- module.id.name + module.extraInfo + "\n" +
- module.id.organisation + "\n" +
- module.id.version +
- module.error.map("\nerror: " + _).getOrElse("") +
- module.evictedByVersion.map(_ formatted "\nevicted by: %s").getOrElse("")
-
- val vertices = moduleGraph.nodes.map(renderVertex).toList
- val edges = moduleGraph.edges.toList.map { case (from, to) ⇒ (renderVertex(moduleGraph.module(from)), renderVertex(moduleGraph.module(to))) }
- Graph(vertices, edges)
- }
-
- def asciiGraphSetttings = Seq[sbt.Def.Setting[_]](
- DependencyGraphKeys.asciiGraph := asciiGraph(moduleGraph.value),
- dependencyGraph := {
- val force = DependencyGraphSettings.shouldForceParser.parsed
- val log = streams.value.log
- if (force || moduleGraph.value.nodes.size < 15) {
- log.info(rendering.AsciiGraph.asciiGraph(moduleGraph.value))
- log.info("\n\n")
- log.info("Note: The old tree layout is still available by using `dependency-tree`")
- }
-
- log.info(rendering.AsciiTree.asciiTree(moduleGraph.value))
-
- if (!force) {
- log.info("\n")
- log.info("Note: The graph was estimated to be too big to display (> 15 nodes). Use `sbt 'dependency-graph --force'` (with the single quotes) to force graph display.")
- }
- })
-}
diff --git a/sbt-dependency-graph/src/main/scala-sbt-0.13/sbt/dependencygraph/DependencyGraphSbtCompat.scala b/sbt-dependency-graph/src/main/scala-sbt-0.13/sbt/dependencygraph/DependencyGraphSbtCompat.scala
deleted file mode 100644
index 5aa6bacc6..000000000
--- a/sbt-dependency-graph/src/main/scala-sbt-0.13/sbt/dependencygraph/DependencyGraphSbtCompat.scala
+++ /dev/null
@@ -1,15 +0,0 @@
-package sbt
-package dependencygraph
-
-import scala.language.implicitConversions
-
-object DependencyGraphSbtCompat {
- object Implicits {
- implicit def convertConfig(config: sbt.Configuration): String = config.toString
-
- implicit class RichUpdateConfiguration(val updateConfig: UpdateConfiguration) extends AnyVal {
- def withMissingOk(missingOk: Boolean): UpdateConfiguration =
- updateConfig.copy(missingOk = missingOk)
- }
- }
-}
diff --git a/sbt-dependency-graph/src/main/scala-sbt-1.0/net/virtualvoid/sbt/graph/ModuleGraphProtocolCompat.scala b/sbt-dependency-graph/src/main/scala-sbt-1.0/net/virtualvoid/sbt/graph/ModuleGraphProtocolCompat.scala
deleted file mode 100644
index 1fb08ccc7..000000000
--- a/sbt-dependency-graph/src/main/scala-sbt-1.0/net/virtualvoid/sbt/graph/ModuleGraphProtocolCompat.scala
+++ /dev/null
@@ -1,25 +0,0 @@
-package net.virtualvoid.sbt.graph
-
-import java.io.{ ByteArrayInputStream, ByteArrayOutputStream, File }
-import java.util.Base64
-
-import sbinary.{ Format, JavaInput, JavaOutput }
-import sjsonnew.{ Builder, Unbuilder }
-
-trait ModuleGraphProtocolCompat {
- implicit def sjsonNewAndShinyTransformAndTranspileAdapterFactoryModuleImplementation[T](implicit format: Format[T]): sjsonnew.JsonFormat[T] =
- new sjsonnew.JsonFormat[T] {
- // note, how this is simpler to write than to learn any sjonnew protocol syntax
- def write[J](obj: T, builder: Builder[J]): Unit = {
- val baos = new ByteArrayOutputStream()
- format.writes(new JavaOutput(baos), obj)
- val str = Base64.getEncoder.encodeToString(baos.toByteArray)
- builder.writeString(str)
- }
- def read[J](jsOpt: Option[J], unbuilder: Unbuilder[J]): T = {
- val str = unbuilder.readString(jsOpt.get)
- val bais = new ByteArrayInputStream(Base64.getDecoder.decode(str))
- format.reads(new JavaInput(bais))
- }
- }
-}
diff --git a/sbt-dependency-graph/src/main/scala-sbt-1.0/net/virtualvoid/sbt/graph/rendering/AsciiGraph.scala b/sbt-dependency-graph/src/main/scala-sbt-1.0/net/virtualvoid/sbt/graph/rendering/AsciiGraph.scala
deleted file mode 100644
index b9e187a3b..000000000
--- a/sbt-dependency-graph/src/main/scala-sbt-1.0/net/virtualvoid/sbt/graph/rendering/AsciiGraph.scala
+++ /dev/null
@@ -1,22 +0,0 @@
-/*
- * Copyright 2017 Johannes Rudolph
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package net.virtualvoid.sbt.graph
-package rendering
-
-object AsciiGraph {
- def asciiGraphSetttings = Seq.empty[sbt.Def.Setting[_]]
-}
\ No newline at end of file
diff --git a/sbt-dependency-graph/src/main/scala-sbt-1.0/sbt/dependencygraph/DependencyGraphSbtCompat.scala b/sbt-dependency-graph/src/main/scala-sbt-1.0/sbt/dependencygraph/DependencyGraphSbtCompat.scala
deleted file mode 100644
index ea196cb8f..000000000
--- a/sbt-dependency-graph/src/main/scala-sbt-1.0/sbt/dependencygraph/DependencyGraphSbtCompat.scala
+++ /dev/null
@@ -1,6 +0,0 @@
-package sbt
-package dependencygraph
-
-object DependencyGraphSbtCompat {
- object Implicits
-}
diff --git a/sbt-dependency-graph/src/main/scala/net/virtualvoid/sbt/graph/DependencyGraphKeys.scala b/sbt-dependency-graph/src/main/scala/net/virtualvoid/sbt/graph/DependencyGraphKeys.scala
deleted file mode 100644
index 2abdd156d..000000000
--- a/sbt-dependency-graph/src/main/scala/net/virtualvoid/sbt/graph/DependencyGraphKeys.scala
+++ /dev/null
@@ -1,113 +0,0 @@
-/*
- * Copyright 2014 Johannes Rudolph
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package net.virtualvoid.sbt.graph
-
-import sbt._
-
-trait DependencyGraphKeys {
- val asString = TaskKey[String]("asString", "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]("toFile", "Writes the task value to the given file")
-
- val dependencyGraphMLFile = SettingKey[File](
- "dependency-graph-ml-file",
- "The location the graphml file should be generated at")
- val dependencyGraphML = TaskKey[File](
- "dependency-graph-ml",
- "Creates a graphml file containing the dependency-graph for a project")
- val dependencyDotFile = SettingKey[File](
- "dependency-dot-file",
- "The location the dot file should be generated at")
- val dependencyDotNodeLabel = SettingKey[(String, String, String) ⇒ String](
- "dependency-dot-node-label",
- "Returns a formated string of a dependency. Takes organisation, name and version as parameters")
- val dependencyDotHeader = SettingKey[String](
- "dependency-dot-header",
- "The header of the dot file. (e.g. to set your preferred node shapes)")
- val dependencyDot = TaskKey[File](
- "dependency-dot",
- "Creates a dot file containing the dependency-graph for a project")
- val dependencyDotString = TaskKey[String](
- "dependency-dot-string",
- "Creates a String containing the dependency-graph for a project in dot format")
- val dependencyBrowseGraphTarget = SettingKey[File](
- "dependency-browse-graph-target",
- "The location dependency browse graph files should be put.")
- val dependencyBrowseGraphHTML = TaskKey[URI](
- "dependency-browse-graph-html",
- "Creates an HTML page that can be used to view the graph.")
- val dependencyBrowseGraph = TaskKey[URI](
- "dependency-browse-graph",
- "Opens an HTML page that can be used to view the graph.")
- val dependencyBrowseTreeTarget = SettingKey[File](
- "dependency-browse-tree-target",
- "The location dependency browse tree files should be put.")
- val dependencyBrowseTreeHTML = TaskKey[URI](
- "dependency-browse-tree-html",
- "Creates an HTML page that can be used to view the dependency tree")
- val dependencyBrowseTree = TaskKey[URI](
- "dependency-browse-tree",
- "Opens an HTML page that can be used to view the dependency tree")
- val moduleGraph = TaskKey[ModuleGraph](
- "module-graph",
- "The dependency graph for a project")
- val moduleGraphIvyReport = TaskKey[ModuleGraph](
- "module-graph-ivy-report",
- "The dependency graph for a project as generated from an Ivy Report XML")
- val moduleGraphSbt = TaskKey[ModuleGraph](
- "module-graph-sbt",
- "The dependency graph for a project as generated from SBT data structures.")
- val asciiGraph = TaskKey[String](
- "dependency-graph-string",
- "Returns a string containing the ascii representation of the dependency graph for a project")
- val dependencyGraph = InputKey[Unit](
- "dependency-graph",
- "Prints the ascii graph to the console")
- val asciiTree = TaskKey[String](
- "dependency-tree-string",
- "Returns a string containing an ascii tree representation of the dependency graph for a project")
- val dependencyTree = TaskKey[Unit](
- "dependency-tree",
- "Prints an ascii tree of all the dependencies to the console")
- val dependencyList = TaskKey[Unit](
- "dependency-list",
- "Prints a list of all dependencies to the console")
- val dependencyStats = TaskKey[Unit](
- "dependency-stats",
- "Prints statistics for all dependencies to the console")
- val ivyReportFunction = TaskKey[String ⇒ File](
- "ivy-report-function",
- "A function which returns the file containing the ivy report from the ivy cache for a given configuration")
- val ivyReport = TaskKey[File](
- "ivy-report",
- "A task which returns the location of the ivy report file for a given configuration (default `compile`).")
- val filterScalaLibrary = SettingKey[Boolean](
- "filter-scala-library",
- "Specifies if scala dependency should be filtered in dependency-* output")
-
- val licenseInfo = TaskKey[Unit](
- "dependency-license-info",
- "Aggregates and shows information about the licenses of dependencies")
-
- // internal
- private[graph] val ignoreMissingUpdate = TaskKey[UpdateReport]("dependencyUpdate", "sbt-dependency-graph version of update")
- private[graph] 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[graph] val crossProjectId = SettingKey[ModuleID]("dependency-graph-cross-project-id")
-}
-
-object DependencyGraphKeys extends DependencyGraphKeys
diff --git a/sbt-dependency-graph/src/main/scala/net/virtualvoid/sbt/graph/DependencyGraphPlugin.scala b/sbt-dependency-graph/src/main/scala/net/virtualvoid/sbt/graph/DependencyGraphPlugin.scala
deleted file mode 100755
index 31f36d729..000000000
--- a/sbt-dependency-graph/src/main/scala/net/virtualvoid/sbt/graph/DependencyGraphPlugin.scala
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * Copyright 2011, 2012 Johannes Rudolph
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package net.virtualvoid.sbt.graph
-
-import sbt._
-import Keys._
-
-object DependencyGraphPlugin extends AutoPlugin {
- object autoImport extends DependencyGraphKeys
-
- override def projectSettings: Seq[Def.Setting[_]] = DependencyGraphSettings.graphSettings
-
- override def trigger: PluginTrigger = AllRequirements
-}
diff --git a/sbt-dependency-graph/src/main/scala/net/virtualvoid/sbt/graph/DependencyGraphSettings.scala b/sbt-dependency-graph/src/main/scala/net/virtualvoid/sbt/graph/DependencyGraphSettings.scala
deleted file mode 100644
index bec65daf6..000000000
--- a/sbt-dependency-graph/src/main/scala/net/virtualvoid/sbt/graph/DependencyGraphSettings.scala
+++ /dev/null
@@ -1,279 +0,0 @@
-/*
- * Copyright 2015 Johannes Rudolph
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package net.virtualvoid.sbt.graph
-
-import scala.language.reflectiveCalls
-import sbt._
-import Keys._
-import sbt.complete.Parser
-import net.virtualvoid.sbt.graph.backend.{ IvyReport, SbtUpdateReport }
-import net.virtualvoid.sbt.graph.rendering.{ AsciiGraph, DagreHTML, TreeView }
-import net.virtualvoid.sbt.graph.util.IOUtil
-import internal.librarymanagement._
-import librarymanagement._
-import sbt.dependencygraph.SbtAccess
-import sbt.dependencygraph.DependencyGraphSbtCompat.Implicits._
-import sbt.complete.Parsers
-
-object DependencyGraphSettings {
- import DependencyGraphKeys._
- import ModuleGraphProtocol._
-
- def graphSettings = baseSettings ++ reportSettings
-
- def baseSettings = Seq(
- ivyReportFunction := ivyReportFunctionTask.value,
-
- // disable the cached resolution engine (exposing a scoped `ivyModule` used directly by `updateTask`), as it
- // generates artificial module descriptors which are internal to sbt, making it hard to reconstruct the
- // dependency tree
- updateOptions in ignoreMissingUpdate := updateOptions.value.withCachedResolution(false),
- ivyConfiguration in ignoreMissingUpdate :=
- // inTask will make sure the new definition will pick up `updateOptions in ignoreMissingUpdate`
- SbtAccess.inTask(ignoreMissingUpdate, Classpaths.mkIvyConfiguration).value,
- ivyModule in ignoreMissingUpdate := {
- // concatenating & inlining ivySbt & ivyModule default task implementations, as `SbtAccess.inTask` does
- // NOT correctly force the scope when applied to `TaskKey.toTask` instances (as opposed to raw
- // implementations like `Classpaths.mkIvyConfiguration` or `Classpaths.updateTask`)
- val is = new IvySbt((ivyConfiguration in ignoreMissingUpdate).value)
- new is.Module(moduleSettings.value)
- },
-
- // don't fail on missing dependencies
- updateConfiguration in ignoreMissingUpdate := updateConfiguration.value.withMissingOk(true),
-
- ignoreMissingUpdate :=
- // inTask will make sure the new definition will pick up `ivyModule/updateConfiguration in ignoreMissingUpdate`
- SbtAccess.inTask(ignoreMissingUpdate, Classpaths.updateTask).value,
-
- filterScalaLibrary in Global := true)
-
- def reportSettings =
- Seq(Compile, Test, IntegrationTest, Runtime, Provided, Optional).flatMap(ivyReportForConfig)
-
- val renderingAlternatives: Seq[(TaskKey[Unit], ModuleGraph ⇒ String)] =
- Seq(
- dependencyTree -> rendering.AsciiTree.asciiTree _,
- dependencyList -> rendering.FlatList.render(_.id.idString),
- dependencyStats -> rendering.Statistics.renderModuleStatsList _,
- licenseInfo -> rendering.LicenseInfo.render _)
-
- def ivyReportForConfig(config: Configuration) = inConfig(config)(
- Seq(
- ivyReport := { Def.task { ivyReportFunction.value.apply(config.toString) } dependsOn (ignoreMissingUpdate) }.value,
- crossProjectId := sbt.CrossVersion(scalaVersion.value, scalaBinaryVersion.value)(projectID.value),
- moduleGraphSbt :=
- ignoreMissingUpdate.value.configuration(configuration.value).map(report ⇒ SbtUpdateReport.fromConfigurationReport(report, crossProjectId.value)).getOrElse(ModuleGraph.empty),
- moduleGraphIvyReport := IvyReport.fromReportFile(absoluteReportPath(ivyReport.value)),
- moduleGraph := {
- sbtVersion.value match {
- case Version(0, 13, x, _) if x >= 6 ⇒ moduleGraphSbt.value
- case Version(1, _, _, _) ⇒ moduleGraphSbt.value
- }
- },
- moduleGraph := {
- // FIXME: remove busywork
- val scalaVersion = Keys.scalaVersion.value
- val moduleGraph = DependencyGraphKeys.moduleGraph.value
-
- if (filterScalaLibrary.value) GraphTransformations.ignoreScalaLibrary(scalaVersion, moduleGraph)
- else moduleGraph
- },
- moduleGraphStore := (moduleGraph storeAs moduleGraphStore triggeredBy moduleGraph).value,
-
- // browse
- dependencyBrowseGraphTarget := { target.value / "browse-dependency-graph" },
- dependencyBrowseGraphHTML := browseGraphHTMLTask.value,
- dependencyBrowseGraph := openBrowser(dependencyBrowseGraphHTML).value,
-
- dependencyBrowseTreeTarget := { target.value / "browse-dependency-tree" },
- dependencyBrowseTreeHTML := browseTreeHTMLTask.value,
- dependencyBrowseTree := openBrowser(dependencyBrowseTreeHTML).value,
-
- // dot support
- dependencyDotFile := { target.value / "dependencies-%s.dot".format(config.toString) },
- dependencyDotString := rendering.DOT.dotGraph(moduleGraph.value, dependencyDotHeader.value, dependencyDotNodeLabel.value, rendering.DOT.AngleBrackets),
- dependencyDot := writeToFile(dependencyDotString, dependencyDotFile).value,
- dependencyDotHeader :=
- """|digraph "dependency-graph" {
- | graph[rankdir="LR"]
- | edge [
- | arrowtail="none"
- | ]""".stripMargin,
- dependencyDotNodeLabel := { (organisation: String, name: String, version: String) ⇒
- """%s %s %s""".format(organisation, name, version)
- },
-
- // GraphML support
- dependencyGraphMLFile := { target.value / "dependencies-%s.graphml".format(config.toString) },
- dependencyGraphML := dependencyGraphMLTask.value,
-
- whatDependsOn := {
- val ArtifactPattern(org, name, versionFilter) = artifactPatternParser.parsed
- val graph = moduleGraph.value
- val modules =
- versionFilter match {
- case Some(version) ⇒ ModuleId(org, name, version) :: Nil
- case None ⇒ graph.nodes.filter(m ⇒ m.id.organisation == org && m.id.name == name).map(_.id)
- }
- val output =
- modules
- .map { module ⇒
- rendering.AsciiTree.asciiTree(GraphTransformations.reverseGraphStartingAt(graph, module))
- }
- .mkString("\n")
-
- streams.value.log.info(output)
- output
- },
- // deprecated settings
- asciiTree := (asString in dependencyTree).value) ++
- renderingAlternatives.flatMap((renderingTaskSettings _).tupled) ++
- AsciiGraph.asciiGraphSetttings)
-
- def renderingTaskSettings(key: TaskKey[Unit], renderer: ModuleGraph ⇒ String): Seq[Setting[_]] =
- Seq(
- asString in key := renderer(moduleGraph.value),
- printToConsole in key := streams.value.log.info((asString in key).value),
- toFile in key := {
- val (targetFile, force) = targetFileAndForceParser.parsed
- writeToFile(key.key.label, (asString in key).value, targetFile, force, streams.value)
- },
- key := (printToConsole in key).value)
-
- def ivyReportFunctionTask = Def.task {
- val ivyConfig = Keys.ivyConfiguration.value.asInstanceOf[InlineIvyConfiguration]
- val projectID = Keys.projectID.value
- val ivyModule = Keys.ivyModule.value
-
- (config: String) ⇒ {
- val org = projectID.organization
- val name = crossName(ivyModule)
- new File(ivyConfig.resolutionCacheDir.get, s"reports/$org-$name-$config.xml")
- }
- }
-
- def dependencyGraphMLTask =
- Def.task {
- val resultFile = dependencyGraphMLFile.value
- rendering.GraphML.saveAsGraphML(moduleGraph.value, resultFile.getAbsolutePath)
- streams.value.log.info("Wrote dependency graph to '%s'" format resultFile)
- resultFile
- }
-
- def browseGraphHTMLTask =
- Def.task {
- val dotGraph = rendering.DOT.dotGraph(moduleGraph.value, dependencyDotHeader.value, dependencyDotNodeLabel.value, rendering.DOT.LabelTypeHtml)
- val link = DagreHTML.createLink(dotGraph, target.value)
- streams.value.log.info(s"HTML graph written to $link")
- link
- }
-
- def browseTreeHTMLTask =
- Def.task {
- val renderedTree = TreeView.createJson(moduleGraph.value)
- val link = TreeView.createLink(renderedTree, target.value)
- streams.value.log.info(s"HTML tree written to $link")
- link
- }
-
- def writeToFile(dataTask: TaskKey[String], fileTask: SettingKey[File]) =
- Def.task {
- val outFile = fileTask.value
- IOUtil.writeToFile(dataTask.value, outFile)
-
- streams.value.log.info("Wrote dependency graph to '%s'" format outFile)
- outFile
- }
-
- def writeToFile(what: String, data: String, targetFile: File, force: Boolean, streams: TaskStreams): File =
- if (targetFile.exists && !force)
- throw new RuntimeException(s"Target file for $what already exists at ${targetFile.getAbsolutePath}. Use '-f' to override")
- else {
- IOUtil.writeToFile(data, targetFile)
-
- streams.log.info(s"Wrote $what to '$targetFile'")
- targetFile
- }
-
- def absoluteReportPath = (file: File) ⇒ file.getAbsolutePath
-
- def openBrowser(uriKey: TaskKey[URI]) =
- Def.task {
- val uri = uriKey.value
- streams.value.log.info("Opening in browser...")
- java.awt.Desktop.getDesktop.browse(uri)
- uri
- }
-
- case class ArtifactPattern(
- organisation: String,
- name: String,
- version: Option[String])
-
- import sbt.complete.DefaultParsers._
- val artifactPatternParser: Def.Initialize[State ⇒ Parser[ArtifactPattern]] =
- resolvedScoped { ctx ⇒ (state: State) ⇒
- val graph = loadFromContext(moduleGraphStore, ctx, state) getOrElse ModuleGraph(Nil, Nil)
-
- graph.nodes
- .map(_.id)
- .groupBy(m ⇒ (m.organisation, m.name))
- .map {
- case ((org, name), modules) ⇒
- val versionParsers: Seq[Parser[Option[String]]] =
- modules.map { id ⇒
- token(Space ~> id.version).?
- }
-
- (Space ~> token(org) ~ token(Space ~> name) ~ oneOf(versionParsers)).map {
- case ((org, name), version) ⇒ ArtifactPattern(org, name, version)
- }
- }
- .reduceOption(_ | _).getOrElse {
- // If the moduleGraphStore couldn't be loaded because no dependency tree command was run before, we should still provide a parser for the command.
- ((Space ~> token(StringBasic, "")) ~ (Space ~> token(StringBasic, "")) ~ (Space ~> token(StringBasic, "")).?).map {
- case ((org, mod), version) ⇒
- ArtifactPattern(org, mod, version)
- }
- }
- }
- val shouldForceParser: Parser[Boolean] = (Space ~> (Parser.literal("-f") | "--force")).?.map(_.isDefined)
-
- val targetFileAndForceParser: Parser[(File, Boolean)] =
- Parsers.fileParser(new File(".")) ~ shouldForceParser
-
- // This is to support 0.13.8's InlineConfigurationWithExcludes while not forcing 0.13.8
- type HasModule = {
- val module: ModuleID
- }
- def crossName(ivyModule: IvySbt#Module) =
- ivyModule.moduleSettings match {
- case ic: InlineConfiguration ⇒ ic.module.name
- case hm: HasModule @unchecked if hm.getClass.getName == "sbt.InlineConfigurationWithExcludes" ⇒ hm.module.name
- case _ ⇒
- throw new IllegalStateException("sbt-dependency-graph plugin currently only supports InlineConfiguration of ivy settings (the default in sbt)")
- }
-
- val VersionPattern = """(\d+)\.(\d+)\.(\d+)(?:-(.*))?""".r
- object Version {
- def unapply(str: String): Option[(Int, Int, Int, Option[String])] = str match {
- case VersionPattern(major, minor, fix, appendix) ⇒ Some((major.toInt, minor.toInt, fix.toInt, Option(appendix)))
- case _ ⇒ None
- }
- }
-}
diff --git a/sbt-dependency-graph/src/main/scala/net/virtualvoid/sbt/graph/GraphTransformations.scala b/sbt-dependency-graph/src/main/scala/net/virtualvoid/sbt/graph/GraphTransformations.scala
deleted file mode 100644
index c5c4e8a21..000000000
--- a/sbt-dependency-graph/src/main/scala/net/virtualvoid/sbt/graph/GraphTransformations.scala
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
- * Copyright 2011, 2012 Johannes Rudolph
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package net.virtualvoid.sbt.graph
-
-object GraphTransformations {
- def reverseGraphStartingAt(graph: ModuleGraph, root: ModuleId): ModuleGraph = {
- val deps = graph.reverseDependencyMap
-
- def visit(module: ModuleId, visited: Set[ModuleId]): Seq[(ModuleId, ModuleId)] =
- 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[ModuleId])((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: ModuleId) = id.organisation == "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)
- }
-}
diff --git a/sbt-dependency-graph/src/main/scala/net/virtualvoid/sbt/graph/Main.scala b/sbt-dependency-graph/src/main/scala/net/virtualvoid/sbt/graph/Main.scala
deleted file mode 100644
index fb51d60b7..000000000
--- a/sbt-dependency-graph/src/main/scala/net/virtualvoid/sbt/graph/Main.scala
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * Copyright 2015 Johannes Rudolph
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package net.virtualvoid.sbt.graph
-
-import java.io.File
-
-import net.virtualvoid.sbt.graph.backend.IvyReport
-
-object Main extends App {
- def die(msg: String): Nothing = {
- println(msg)
- sys.exit(1)
- }
- def usage: String =
- "Usage: "
-
- val reportFile = args.lift(0).filter(f ⇒ new File(f).exists).getOrElse(die(usage))
- val outputFile = args.lift(1).getOrElse(die(usage))
- val graph = IvyReport.fromReportFile(reportFile)
- rendering.GraphML.saveAsGraphML(graph, outputFile)
-}
diff --git a/sbt-dependency-graph/src/main/scala/net/virtualvoid/sbt/graph/backend/IvyReport.scala b/sbt-dependency-graph/src/main/scala/net/virtualvoid/sbt/graph/backend/IvyReport.scala
deleted file mode 100644
index 426a68a3e..000000000
--- a/sbt-dependency-graph/src/main/scala/net/virtualvoid/sbt/graph/backend/IvyReport.scala
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- * Copyright 2015 Johannes Rudolph
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package net.virtualvoid.sbt.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: ModuleId, 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(ModuleId(infoAttr("organisation"), infoAttr("module"), infoAttr("revision")))
-
- ModuleGraph(rootModule +: nodes, edges.flatten)
- }
-
- private def moduleIdFromElement(element: Node, version: String): ModuleId =
- ModuleId(element.attribute("organisation").get.text, element.attribute("name").get.text, version)
-
- private def loadXML(ivyReportFile: String) =
- ConstructingParser.fromSource(io.Source.fromFile(ivyReportFile), preserveWS = false).document()
-}
diff --git a/sbt-dependency-graph/src/main/scala/net/virtualvoid/sbt/graph/backend/SbtUpdateReport.scala b/sbt-dependency-graph/src/main/scala/net/virtualvoid/sbt/graph/backend/SbtUpdateReport.scala
deleted file mode 100644
index 44a4c6cec..000000000
--- a/sbt-dependency-graph/src/main/scala/net/virtualvoid/sbt/graph/backend/SbtUpdateReport.scala
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- * Copyright 2015 Johannes Rudolph
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package net.virtualvoid.sbt.graph
-package backend
-
-import scala.language.implicitConversions
-import scala.language.reflectiveCalls
-
-import sbt._
-
-object SbtUpdateReport {
- type OrganizationArtifactReport = {
- def modules: Seq[ModuleReport]
- }
-
- def fromConfigurationReport(report: ConfigurationReport, rootInfo: sbt.ModuleID): ModuleGraph = {
- implicit def id(sbtId: sbt.ModuleID): ModuleId = ModuleId(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)
- }
-}
diff --git a/sbt-dependency-graph/src/main/scala/net/virtualvoid/sbt/graph/model.scala b/sbt-dependency-graph/src/main/scala/net/virtualvoid/sbt/graph/model.scala
deleted file mode 100644
index cbfc43294..000000000
--- a/sbt-dependency-graph/src/main/scala/net/virtualvoid/sbt/graph/model.scala
+++ /dev/null
@@ -1,79 +0,0 @@
-/*
- * Copyright 2015 Johannes Rudolph
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package net.virtualvoid.sbt.graph
-
-import java.io.File
-
-import sbinary.Format
-
-import scala.collection.mutable.{ HashMap, MultiMap, Set }
-
-case class ModuleId(
- organisation: String,
- name: String,
- version: String) {
- def idString: String = organisation + ":" + name + ":" + version
-}
-case class Module(
- id: ModuleId,
- license: Option[String] = None,
- extraInfo: String = "",
- evictedByVersion: Option[String] = None,
- jarFile: Option[File] = None,
- error: Option[String] = None) {
- def hadError: Boolean = error.isDefined
- def isUsed: Boolean = !isEvicted
- def isEvicted: Boolean = evictedByVersion.isDefined
-}
-
-object ModuleGraph {
- val empty = ModuleGraph(Seq.empty, Seq.empty)
-}
-
-case class ModuleGraph(nodes: Seq[Module], edges: Seq[Edge]) {
- lazy val modules: Map[ModuleId, Module] =
- nodes.map(n ⇒ (n.id, n)).toMap
-
- def module(id: ModuleId): Module = modules(id)
-
- lazy val dependencyMap: Map[ModuleId, Seq[Module]] =
- createMap(identity)
-
- lazy val reverseDependencyMap: Map[ModuleId, Seq[Module]] =
- createMap { case (a, b) ⇒ (b, a) }
-
- def createMap(bindingFor: ((ModuleId, ModuleId)) ⇒ (ModuleId, ModuleId)): Map[ModuleId, Seq[Module]] = {
- val m = new HashMap[ModuleId, Set[Module]] with MultiMap[ModuleId, Module]
- edges.foreach { entry ⇒
- val (f, t) = bindingFor(entry)
- m.addBinding(f, module(t))
- }
- m.toMap.mapValues(_.toSeq.sortBy(_.id.idString)).withDefaultValue(Nil)
- }
-
- def roots: Seq[Module] =
- nodes.filter(n ⇒ !edges.exists(_._2 == n.id)).sortBy(_.id.idString)
-}
-
-object ModuleGraphProtocol extends ModuleGraphProtocolCompat {
- import sbinary.DefaultProtocol._
-
- implicit def seqFormat[T: Format]: Format[Seq[T]] = wrap[Seq[T], List[T]](_.toList, _.toSeq)
- implicit val ModuleIdFormat: Format[ModuleId] = asProduct3(ModuleId)(ModuleId.unapply(_).get)
- implicit val ModuleFormat: Format[Module] = asProduct6(Module)(Module.unapply(_).get)
- implicit val ModuleGraphFormat: Format[ModuleGraph] = asProduct2(ModuleGraph.apply _)(ModuleGraph.unapply(_).get)
-}
diff --git a/sbt-dependency-graph/src/main/scala/net/virtualvoid/sbt/graph/package.scala b/sbt-dependency-graph/src/main/scala/net/virtualvoid/sbt/graph/package.scala
deleted file mode 100644
index 41921bcfa..000000000
--- a/sbt-dependency-graph/src/main/scala/net/virtualvoid/sbt/graph/package.scala
+++ /dev/null
@@ -1,22 +0,0 @@
-/*
- * Copyright 2015 Johannes Rudolph
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package net.virtualvoid.sbt
-
-package object graph {
- type Edge = (ModuleId, ModuleId)
- def Edge(from: ModuleId, to: ModuleId): Edge = from -> to
-}
diff --git a/sbt-dependency-graph/src/main/scala/net/virtualvoid/sbt/graph/rendering/AsciiTree.scala b/sbt-dependency-graph/src/main/scala/net/virtualvoid/sbt/graph/rendering/AsciiTree.scala
deleted file mode 100644
index c2670e6a2..000000000
--- a/sbt-dependency-graph/src/main/scala/net/virtualvoid/sbt/graph/rendering/AsciiTree.scala
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * Copyright 2015 Johannes Rudolph
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package net.virtualvoid.sbt.graph
-package rendering
-
-import util.AsciiTreeLayout
-import util.ConsoleUtils._
-
-object AsciiTree {
- def asciiTree(graph: ModuleGraph): String = {
- val deps = graph.dependencyMap
-
- // there should only be one root node (the project itself)
- val roots = graph.roots
- roots.map { root ⇒
- AsciiTreeLayout.toAscii[Module](root, node ⇒ deps.getOrElse(node.id, Seq.empty[Module]), displayModule)
- }.mkString("\n")
- }
-
- def displayModule(module: Module): String =
- red(module.id.idString +
- module.extraInfo +
- module.error.map(" (error: " + _ + ")").getOrElse("") +
- module.evictedByVersion.map(_ formatted " (evicted by: %s)").getOrElse(""), module.hadError)
-}
diff --git a/sbt-dependency-graph/src/main/scala/net/virtualvoid/sbt/graph/rendering/DagreHTML.scala b/sbt-dependency-graph/src/main/scala/net/virtualvoid/sbt/graph/rendering/DagreHTML.scala
deleted file mode 100644
index 3064ef502..000000000
--- a/sbt-dependency-graph/src/main/scala/net/virtualvoid/sbt/graph/rendering/DagreHTML.scala
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * Copyright 2015 Johannes Rudolph
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package net.virtualvoid.sbt.graph
-package rendering
-
-import java.io.File
-import java.net.{ URLEncoder, URI }
-
-import net.virtualvoid.sbt.graph.util.IOUtil
-
-object DagreHTML {
- def createLink(dotGraph: String, targetDirectory: File): URI = {
- targetDirectory.mkdirs()
- val graphHTML = new File(targetDirectory, "graph.html")
- IOUtil.saveResource("graph.html", graphHTML)
- IOUtil.writeToFile(dotGraph, new File(targetDirectory, "dependencies.dot"))
-
- val graphString =
- URLEncoder.encode(dotGraph, "utf8")
- .replaceAllLiterally("+", "%20")
-
- IOUtil.writeToFile(s"""data = "$graphString";""", new File(targetDirectory, "dependencies.dot.js"))
-
- new URI(graphHTML.toURI.toString)
- }
-}
diff --git a/sbt-dependency-graph/src/main/scala/net/virtualvoid/sbt/graph/rendering/FlatList.scala b/sbt-dependency-graph/src/main/scala/net/virtualvoid/sbt/graph/rendering/FlatList.scala
deleted file mode 100644
index 95f0676d6..000000000
--- a/sbt-dependency-graph/src/main/scala/net/virtualvoid/sbt/graph/rendering/FlatList.scala
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * Copyright 2016 Johannes Rudolph
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package net.virtualvoid.sbt.graph
-package rendering
-
-object FlatList {
- def render(display: Module ⇒ String)(graph: ModuleGraph): String =
- graph.modules.values.toSeq
- .distinct
- .filterNot(_.isEvicted)
- .sortBy(m ⇒ (m.id.organisation, m.id.name))
- .map(display)
- .mkString("\n")
-}
diff --git a/sbt-dependency-graph/src/main/scala/net/virtualvoid/sbt/graph/rendering/GraphML.scala b/sbt-dependency-graph/src/main/scala/net/virtualvoid/sbt/graph/rendering/GraphML.scala
deleted file mode 100644
index e1681fdad..000000000
--- a/sbt-dependency-graph/src/main/scala/net/virtualvoid/sbt/graph/rendering/GraphML.scala
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * Copyright 2015 Johannes Rudolph
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package net.virtualvoid.sbt.graph.rendering
-
-import net.virtualvoid.sbt.graph.ModuleGraph
-
-import scala.xml.XML
-
-object GraphML {
- def saveAsGraphML(graph: ModuleGraph, outputFile: String): Unit = {
- val nodesXml =
- for (n ← graph.nodes)
- yield
-
- { n.id.idString }
-
-
-
- val edgesXml =
- for (e ← graph.edges)
- yield
-
- val xml =
-
-
-
- { nodesXml }
- { edgesXml }
-
-
-
- XML.save(outputFile, xml)
- }
-}
diff --git a/sbt-dependency-graph/src/main/scala/net/virtualvoid/sbt/graph/rendering/LicenseInfo.scala b/sbt-dependency-graph/src/main/scala/net/virtualvoid/sbt/graph/rendering/LicenseInfo.scala
deleted file mode 100644
index cb97d3f0e..000000000
--- a/sbt-dependency-graph/src/main/scala/net/virtualvoid/sbt/graph/rendering/LicenseInfo.scala
+++ /dev/null
@@ -1,12 +0,0 @@
-package net.virtualvoid.sbt.graph.rendering
-
-import net.virtualvoid.sbt.graph.ModuleGraph
-
-object LicenseInfo {
- def render(graph: ModuleGraph): String =
- graph.nodes.filter(_.isUsed).groupBy(_.license).toSeq.sortBy(_._1).map {
- case (license, modules) ⇒
- license.getOrElse("No license specified") + "\n" +
- modules.map(_.id.idString formatted "\t %s").mkString("\n")
- }.mkString("\n\n")
-}
diff --git a/sbt-dependency-graph/src/main/scala/net/virtualvoid/sbt/graph/rendering/Statistics.scala b/sbt-dependency-graph/src/main/scala/net/virtualvoid/sbt/graph/rendering/Statistics.scala
deleted file mode 100644
index a9d10fdba..000000000
--- a/sbt-dependency-graph/src/main/scala/net/virtualvoid/sbt/graph/rendering/Statistics.scala
+++ /dev/null
@@ -1,71 +0,0 @@
-/*
- * Copyright 2016 Johannes Rudolph
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package net.virtualvoid.sbt.graph
-package rendering
-
-object Statistics {
- def renderModuleStatsList(graph: ModuleGraph): String = {
- case class ModuleStats(
- id: ModuleId,
- numDirectDependencies: Int,
- numTransitiveDependencies: Int,
- selfSize: Option[Long],
- transitiveSize: Long,
- transitiveDependencyStats: Map[ModuleId, ModuleStats]) {
- def transitiveStatsWithSelf: Map[ModuleId, ModuleStats] = transitiveDependencyStats + (id -> this)
- }
-
- def statsFor(moduleId: ModuleId): ModuleStats = {
- val directDependencies = graph.dependencyMap(moduleId).filterNot(_.isEvicted).map(_.id)
- val dependencyStats = directDependencies.map(statsFor).flatMap(_.transitiveStatsWithSelf).toMap
- val selfSize = graph.module(moduleId).jarFile.filter(_.exists).map(_.length)
- val numDirectDependencies = directDependencies.size
- val numTransitiveDependencies = dependencyStats.size
- val transitiveSize = selfSize.getOrElse(0L) + dependencyStats.map(_._2.selfSize.getOrElse(0L)).sum
-
- ModuleStats(moduleId, numDirectDependencies, numTransitiveDependencies, selfSize, transitiveSize, dependencyStats)
- }
-
- def format(stats: ModuleStats): String = {
- import stats._
- def mb(bytes: Long): Double = bytes.toDouble / 1000000
- val selfSize =
- stats.selfSize match {
- case Some(size) ⇒ f"${mb(size)}%7.3f"
- case None ⇒ "-------"
- }
- f"${mb(transitiveSize)}%7.3f MB $selfSize MB $numTransitiveDependencies%4d $numDirectDependencies%4d ${id.idString}%s"
- }
-
- val allStats =
- graph.roots.flatMap(r ⇒ statsFor(r.id).transitiveStatsWithSelf).toMap.values.toSeq
- .sortBy(s ⇒ (-s.transitiveSize, -s.numTransitiveDependencies))
-
- val header = " TotSize JarSize #TDe #Dep Module\n"
-
- header +
- allStats.map(format).mkString("\n") +
- """
- |
- |Columns are
- | - Jar-Size including dependencies
- | - Jar-Size
- | - Number of transitive dependencies
- | - Number of direct dependencies
- | - ModuleID""".stripMargin
- }
-}
diff --git a/sbt-dependency-graph/src/main/scala/net/virtualvoid/sbt/graph/rendering/TreeView.scala b/sbt-dependency-graph/src/main/scala/net/virtualvoid/sbt/graph/rendering/TreeView.scala
deleted file mode 100644
index 582202def..000000000
--- a/sbt-dependency-graph/src/main/scala/net/virtualvoid/sbt/graph/rendering/TreeView.scala
+++ /dev/null
@@ -1,42 +0,0 @@
-package net.virtualvoid.sbt.graph.rendering
-
-import java.io.File
-import java.net.URI
-
-import net.virtualvoid.sbt.graph.util.IOUtil
-import net.virtualvoid.sbt.graph.{ Module, ModuleGraph }
-
-import scala.util.parsing.json.{ JSONArray, JSONObject }
-
-object TreeView {
- def createJson(graph: ModuleGraph): String = {
- val trees = graph.roots
- .map(module ⇒ processSubtree(graph, module))
- .toList
- JSONArray(trees).toString
- }
-
- def createLink(graphJson: String, targetDirectory: File): URI = {
- targetDirectory.mkdirs()
- val graphHTML = new File(targetDirectory, "tree.html")
- IOUtil.saveResource("tree.html", graphHTML)
- IOUtil.writeToFile(graphJson, new File(targetDirectory, "tree.json"))
- IOUtil.writeToFile(s"tree_data = $graphJson;", new File(targetDirectory, "tree.data.js"))
- new URI(graphHTML.toURI.toString)
- }
-
- private def processSubtree(graph: ModuleGraph, module: Module): JSONObject = {
- val children = graph.dependencyMap
- .getOrElse(module.id, List())
- .map(module ⇒ processSubtree(graph, module))
- .toList
- moduleAsJson(module, children)
- }
-
- private def moduleAsJson(module: Module, children: List[JSONObject]): JSONObject = {
- val eviction = module.evictedByVersion.map(version ⇒ s" (evicted by $version)").getOrElse("")
- val error = module.error.map(err ⇒ s" (errors: $err)").getOrElse("")
- val text = module.id.idString + eviction + error
- JSONObject(Map("text" -> text, "children" -> JSONArray(children)))
- }
-}
diff --git a/sbt-dependency-graph/src/main/scala/net/virtualvoid/sbt/graph/util/AsciiTreeLayout.scala b/sbt-dependency-graph/src/main/scala/net/virtualvoid/sbt/graph/util/AsciiTreeLayout.scala
deleted file mode 100644
index 746dab6df..000000000
--- a/sbt-dependency-graph/src/main/scala/net/virtualvoid/sbt/graph/util/AsciiTreeLayout.scala
+++ /dev/null
@@ -1,62 +0,0 @@
-/* sbt -- Simple Build Tool
- * Copyright 2011 Mark Harrah, Eugene Yokota
- *
- * Copied from sbt 0.12 source code
- */
-package net.virtualvoid.sbt.graph.util
-
-import sbt.dependencygraph.SbtAccess
-
-object AsciiTreeLayout {
- // [info] foo
- // [info] +-bar
- // [info] | +-baz
- // [info] |
- // [info] +-quux
- def toAscii[A](
- top: A,
- children: A ⇒ Seq[A],
- display: A ⇒ String,
- maxColumn: Int = defaultColumnSize): String = {
- val twoSpaces = " " + " " // prevent accidentally being converted into a tab
- def limitLine(s: String): String =
- if (s.length > maxColumn) s.slice(0, maxColumn - 2) + ".."
- else s
- def insertBar(s: String, at: Int): String =
- if (at < s.length)
- s.slice(0, at) +
- (s(at).toString match {
- case " " ⇒ "|"
- case x ⇒ x
- }) +
- s.slice(at + 1, s.length)
- else s
- def toAsciiLines(node: A, level: Int, parents: Set[A]): Vector[String] =
- if (parents contains node) // cycle
- Vector(limitLine((twoSpaces * level) + "#-" + display(node) + " (cycle)"))
- else {
- val line = limitLine((twoSpaces * level) + (if (level == 0) "" else "+-") + display(node))
- val cs = Vector(children(node): _*)
- val childLines = cs map {
- toAsciiLines(_, level + 1, parents + node)
- }
- val withBar = childLines.zipWithIndex flatMap {
- case (lines, pos) if pos < (cs.size - 1) ⇒ lines map {
- insertBar(_, 2 * (level + 1))
- }
- case (lines, pos) ⇒
- if (lines.last.trim != "") lines ++ Vector(twoSpaces * (level + 1))
- else lines
- }
- line +: withBar
- }
-
- toAsciiLines(top, 0, Set.empty).mkString("\n")
- }
-
- def defaultColumnSize: Int = {
- val termWidth = SbtAccess.getTerminalWidth
- if (termWidth > 20) termWidth - 8
- else 80 // ignore termWidth
- }
-}
diff --git a/sbt-dependency-graph/src/main/scala/net/virtualvoid/sbt/graph/util/ConsoleUtils.scala b/sbt-dependency-graph/src/main/scala/net/virtualvoid/sbt/graph/util/ConsoleUtils.scala
deleted file mode 100644
index ceba7da65..000000000
--- a/sbt-dependency-graph/src/main/scala/net/virtualvoid/sbt/graph/util/ConsoleUtils.scala
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
- * Copyright 2015 Johannes Rudolph
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package net.virtualvoid.sbt.graph.util
-
-import sbt.ConsoleLogger
-
-object ConsoleUtils {
- def red(str: String, doRed: Boolean): String =
- if (ConsoleLogger.formatEnabled && doRed)
- Console.RED + str + Console.RESET
- else
- str
-}
diff --git a/sbt-dependency-graph/src/main/scala/net/virtualvoid/sbt/graph/util/IOUtil.scala b/sbt-dependency-graph/src/main/scala/net/virtualvoid/sbt/graph/util/IOUtil.scala
deleted file mode 100644
index c9b8ebbf5..000000000
--- a/sbt-dependency-graph/src/main/scala/net/virtualvoid/sbt/graph/util/IOUtil.scala
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * Copyright 2015 Johannes Rudolph
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package net.virtualvoid.sbt.graph.util
-
-import java.io.{ OutputStream, InputStream, FileOutputStream, File }
-import java.nio.charset.Charset
-
-import scala.annotation.tailrec
-
-object IOUtil {
- val utf8 = Charset.forName("utf8")
-
- def writeToFile(string: String, file: File): Unit =
- sbt.IO.write(file, string, utf8)
-
- def saveResource(resourcePath: String, to: File): Unit = {
- val is = getClass.getClassLoader.getResourceAsStream(resourcePath)
- require(is ne null, s"Couldn't load '$resourcePath' from classpath.")
-
- val fos = new FileOutputStream(to)
- try copy(is, fos)
- finally {
- is.close()
- fos.close()
- }
- }
-
- def copy(from: InputStream, to: OutputStream): Unit = {
- val buffer = new Array[Byte](65536)
-
- @tailrec def rec(): Unit = {
- val read = from.read(buffer)
- if (read > 0) {
- to.write(buffer, 0, read)
- rec()
- } else if (read == 0)
- throw new IllegalStateException("InputStream.read returned 0")
- }
- rec()
- }
-}
diff --git a/sbt-dependency-graph/src/main/scala/sbt/dependencygraph/SbtAccess.scala b/sbt-dependency-graph/src/main/scala/sbt/dependencygraph/SbtAccess.scala
deleted file mode 100644
index d1f4e596e..000000000
--- a/sbt-dependency-graph/src/main/scala/sbt/dependencygraph/SbtAccess.scala
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * Copyright 2015 Johannes Rudolph
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package sbt
-package dependencygraph
-
-import Def._
-
-/** Accessors to private[sbt] symbols. */
-object SbtAccess {
- val unmanagedScalaInstanceOnly = Defaults.unmanagedScalaInstanceOnly
-
- def getTerminalWidth: Int = sbt.internal.util.JLine.usingTerminal(_.getWidth)
-
- def inTask[T](t: Scoped, i: Initialize[T]): Initialize[T] = _root_.sbt.inTask(t, i)
-}
diff --git a/sbt-dependency-graph/src/sbt-test/sbt-dependency-graph/cachedResolution/project/plugins.sbt b/sbt-dependency-graph/src/sbt-test/sbt-dependency-graph/cachedResolution/project/plugins.sbt
deleted file mode 100644
index 6fdebb6d6..000000000
--- a/sbt-dependency-graph/src/sbt-test/sbt-dependency-graph/cachedResolution/project/plugins.sbt
+++ /dev/null
@@ -1 +0,0 @@
-addSbtPlugin("net.virtual-void" % "sbt-dependency-graph" % sys.props("project.version"))
diff --git a/sbt-dependency-graph/src/sbt-test/sbt-dependency-graph/ignoreScalaLibrary/project/plugins.sbt b/sbt-dependency-graph/src/sbt-test/sbt-dependency-graph/ignoreScalaLibrary/project/plugins.sbt
deleted file mode 120000
index 0caf1de77..000000000
--- a/sbt-dependency-graph/src/sbt-test/sbt-dependency-graph/ignoreScalaLibrary/project/plugins.sbt
+++ /dev/null
@@ -1 +0,0 @@
-../../plugins.sbt
\ No newline at end of file
diff --git a/sbt-dependency-graph/src/sbt-test/sbt-dependency-graph/intervalRangedVersions/build.sbt b/sbt-dependency-graph/src/sbt-test/sbt-dependency-graph/intervalRangedVersions/build.sbt
deleted file mode 100644
index b417c9e3b..000000000
--- a/sbt-dependency-graph/src/sbt-test/sbt-dependency-graph/intervalRangedVersions/build.sbt
+++ /dev/null
@@ -1,25 +0,0 @@
-scalaVersion := "2.9.1"
-
-resolvers += "typesafe maven" at "https://repo.typesafe.com/typesafe/maven-releases/"
-
-libraryDependencies ++= Seq(
- "com.codahale" % "jerkson_2.9.1" % "0.5.0"
-)
-
-TaskKey[Unit]("check") := {
- val report = (ivyReport in Test).value
- val graph = (asciiTree in Test).value
-
- def sanitize(str: String): String = str.split('\n').drop(1).map(_.trim).mkString("\n")
- val expectedGraph =
- """default:default-dbc48d_2.9.2:0.1-SNAPSHOT [S]
- | +-com.codahale:jerkson_2.9.1:0.5.0 [S]
- | +-org.codehaus.jackson:jackson-core-asl:1.9.11
- | +-org.codehaus.jackson:jackson-mapper-asl:1.9.11
- | +-org.codehaus.jackson:jackson-core-asl:1.9.11
- | """.stripMargin
- IO.writeLines(file("/tmp/blib"), sanitize(graph).split("\n"))
- IO.writeLines(file("/tmp/blub"), sanitize(expectedGraph).split("\n"))
- require(sanitize(graph) == sanitize(expectedGraph), "Graph for report %s was '\n%s' but should have been '\n%s'" format (report, sanitize(graph), sanitize(expectedGraph)))
- ()
-}
diff --git a/sbt-dependency-graph/src/sbt-test/sbt-dependency-graph/intervalRangedVersions/project/plugins.sbt b/sbt-dependency-graph/src/sbt-test/sbt-dependency-graph/intervalRangedVersions/project/plugins.sbt
deleted file mode 120000
index 0caf1de77..000000000
--- a/sbt-dependency-graph/src/sbt-test/sbt-dependency-graph/intervalRangedVersions/project/plugins.sbt
+++ /dev/null
@@ -1 +0,0 @@
-../../plugins.sbt
\ No newline at end of file
diff --git a/sbt-dependency-graph/src/sbt-test/sbt-dependency-graph/plugins.sbt b/sbt-dependency-graph/src/sbt-test/sbt-dependency-graph/plugins.sbt
deleted file mode 100644
index 6fdebb6d6..000000000
--- a/sbt-dependency-graph/src/sbt-test/sbt-dependency-graph/plugins.sbt
+++ /dev/null
@@ -1 +0,0 @@
-addSbtPlugin("net.virtual-void" % "sbt-dependency-graph" % sys.props("project.version"))
diff --git a/sbt-dependency-graph/src/sbt-test/sbt-dependency-graph/showMissingUpdates/project/plugins.sbt b/sbt-dependency-graph/src/sbt-test/sbt-dependency-graph/showMissingUpdates/project/plugins.sbt
deleted file mode 120000
index 0caf1de77..000000000
--- a/sbt-dependency-graph/src/sbt-test/sbt-dependency-graph/showMissingUpdates/project/plugins.sbt
+++ /dev/null
@@ -1 +0,0 @@
-../../plugins.sbt
\ No newline at end of file
diff --git a/sbt-dependency-graph/src/sbt-test/sbt-dependency-graph/showMissingUpdates/test b/sbt-dependency-graph/src/sbt-test/sbt-dependency-graph/showMissingUpdates/test
deleted file mode 100644
index a5912a391..000000000
--- a/sbt-dependency-graph/src/sbt-test/sbt-dependency-graph/showMissingUpdates/test
+++ /dev/null
@@ -1 +0,0 @@
-> check
\ No newline at end of file
diff --git a/sbt-dependency-graph/src/sbt-test/sbt-dependency-graph/testDotFileGeneration/build.sbt b/sbt-dependency-graph/src/sbt-test/sbt-dependency-graph/testDotFileGeneration/build.sbt
deleted file mode 100644
index bb8469447..000000000
--- a/sbt-dependency-graph/src/sbt-test/sbt-dependency-graph/testDotFileGeneration/build.sbt
+++ /dev/null
@@ -1,68 +0,0 @@
-import collection.mutable.ListBuffer
-
-import net.virtualvoid.sbt.graph.DependencyGraphKeys.dependencyDot
-
-import scala.collection.mutable.ListBuffer
-
-def defaultSettings =
- Seq(
- scalaVersion := "2.9.2",
- version := "0.1-SNAPSHOT"
- )
-
-lazy val justATransiviteDependencyEndpointProject =
- Project("just-a-transitive-dependency-endpoint", file("a"))
- .settings(defaultSettings: _*)
-
-lazy val justATransitiveDependencyProject =
- Project("just-a-transitive-dependency", file("b"))
- .settings(defaultSettings: _*)
- .dependsOn(justATransiviteDependencyEndpointProject)
-
-lazy val justADependencyProject =
- Project("just-a-dependency", file("c"))
- .settings(defaultSettings: _*)
-
-lazy val test_project =
- Project("test-dot-file-generation", file("d"))
- .settings(defaultSettings: _*)
- .settings(
- TaskKey[Unit]("check") := {
- val dotFile = (dependencyDot in Compile).value
- val expectedGraph =
- """digraph "dependency-graph" {
- | graph[rankdir="LR"]
- | edge [
- | arrowtail="none"
- | ]
- | "test-dot-file-generation:test-dot-file-generation_2.9.2:0.1-SNAPSHOT"[label=test-dot-file-generation_2.9.2 0.1-SNAPSHOT> style=""]
- | "just-a-transitive-dependency:just-a-transitive-dependency_2.9.2:0.1-SNAPSHOT"[label=just-a-transitive-dependency_2.9.2 0.1-SNAPSHOT> style=""]
- | "just-a-transitive-dependency-endpoint:just-a-transitive-dependency-endpoint_2.9.2:0.1-SNAPSHOT"[label=just-a-transitive-dependency-endpoint_2.9.2 0.1-SNAPSHOT> style=""]
- | "just-a-dependency:just-a-dependency_2.9.2:0.1-SNAPSHOT"[label=just-a-dependency_2.9.2 0.1-SNAPSHOT> style=""]
- | "test-dot-file-generation:test-dot-file-generation_2.9.2:0.1-SNAPSHOT" -> "just-a-transitive-dependency:just-a-transitive-dependency_2.9.2:0.1-SNAPSHOT"
- | "just-a-transitive-dependency:just-a-transitive-dependency_2.9.2:0.1-SNAPSHOT" -> "just-a-transitive-dependency-endpoint:just-a-transitive-dependency-endpoint_2.9.2:0.1-SNAPSHOT"
- | "test-dot-file-generation:test-dot-file-generation_2.9.2:0.1-SNAPSHOT" -> "just-a-dependency:just-a-dependency_2.9.2:0.1-SNAPSHOT"
- |}
- """.stripMargin
-
- val graph : String = scala.io.Source.fromFile(dotFile.getAbsolutePath).mkString
- val errors = compareByLine(graph, expectedGraph)
- require(errors.isEmpty , errors.mkString("\n"))
- ()
- }
- )
- .dependsOn(justADependencyProject, justATransitiveDependencyProject)
-
-def compareByLine(got : String, expected : String) : Seq[String] = {
- val errors = ListBuffer[String]()
- got.split("\n").zip(expected.split("\n").toSeq).zipWithIndex.foreach { case((got_line : String, expected_line : String), i : Int) =>
- if(got_line != expected_line) {
- errors.append(
- """not matching lines at line %s
- |expected: %s
- |got: %s
- |""".stripMargin.format(i,expected_line, got_line))
- }
- }
- errors
-}
\ No newline at end of file
diff --git a/sbt-dependency-graph/src/sbt-test/sbt-dependency-graph/testDotFileGeneration/project/plugins.sbt b/sbt-dependency-graph/src/sbt-test/sbt-dependency-graph/testDotFileGeneration/project/plugins.sbt
deleted file mode 120000
index 0caf1de77..000000000
--- a/sbt-dependency-graph/src/sbt-test/sbt-dependency-graph/testDotFileGeneration/project/plugins.sbt
+++ /dev/null
@@ -1 +0,0 @@
-../../plugins.sbt
\ No newline at end of file
diff --git a/sbt-dependency-graph/src/sbt-test/sbt-dependency-graph/testDotFileGeneration/test b/sbt-dependency-graph/src/sbt-test/sbt-dependency-graph/testDotFileGeneration/test
deleted file mode 100644
index f9fa19e83..000000000
--- a/sbt-dependency-graph/src/sbt-test/sbt-dependency-graph/testDotFileGeneration/test
+++ /dev/null
@@ -1,2 +0,0 @@
-> project test-dot-file-generation
-> check
diff --git a/sbt-dependency-graph/src/sbt-test/sbt-dependency-graph/toFileSubTask/expected/licenses.txt b/sbt-dependency-graph/src/sbt-test/sbt-dependency-graph/toFileSubTask/expected/licenses.txt
deleted file mode 100644
index 826ed0153..000000000
--- a/sbt-dependency-graph/src/sbt-test/sbt-dependency-graph/toFileSubTask/expected/licenses.txt
+++ /dev/null
@@ -1,9 +0,0 @@
-No license specified
- org.example:blubber_2.12:0.1
-
-The Apache Software License, Version 2.0
- org.codehaus.jackson:jackson-mapper-asl:1.9.11
- org.codehaus.jackson:jackson-core-asl:1.9.11
-
-The MIT License
- com.codahale:jerkson_2.9.1:0.5.0
\ No newline at end of file
diff --git a/sbt-dependency-graph/src/sbt-test/sbt-dependency-graph/toFileSubTask/expected/list.txt b/sbt-dependency-graph/src/sbt-test/sbt-dependency-graph/toFileSubTask/expected/list.txt
deleted file mode 100644
index 4bf401868..000000000
--- a/sbt-dependency-graph/src/sbt-test/sbt-dependency-graph/toFileSubTask/expected/list.txt
+++ /dev/null
@@ -1,4 +0,0 @@
-com.codahale:jerkson_2.9.1:0.5.0
-org.codehaus.jackson:jackson-core-asl:1.9.11
-org.codehaus.jackson:jackson-mapper-asl:1.9.11
-org.example:blubber_2.12:0.1
\ No newline at end of file
diff --git a/sbt-dependency-graph/src/sbt-test/sbt-dependency-graph/toFileSubTask/expected/stats.txt b/sbt-dependency-graph/src/sbt-test/sbt-dependency-graph/toFileSubTask/expected/stats.txt
deleted file mode 100644
index 6a76e3522..000000000
--- a/sbt-dependency-graph/src/sbt-test/sbt-dependency-graph/toFileSubTask/expected/stats.txt
+++ /dev/null
@@ -1,12 +0,0 @@
- TotSize JarSize #TDe #Dep Module
- 1.754 MB ------- MB 3 1 org.example:blubber_2.12:0.1
- 1.754 MB 0.741 MB 2 2 com.codahale:jerkson_2.9.1:0.5.0
- 1.013 MB 0.780 MB 1 1 org.codehaus.jackson:jackson-mapper-asl:1.9.11
- 0.232 MB 0.232 MB 0 0 org.codehaus.jackson:jackson-core-asl:1.9.11
-
-Columns are
- - Jar-Size including dependencies
- - Jar-Size
- - Number of transitive dependencies
- - Number of direct dependencies
- - ModuleID
\ No newline at end of file
diff --git a/sbt-dependency-graph/src/sbt-test/sbt-dependency-graph/toFileSubTask/expected/tree.txt b/sbt-dependency-graph/src/sbt-test/sbt-dependency-graph/toFileSubTask/expected/tree.txt
deleted file mode 100644
index 5b1f1aa5e..000000000
--- a/sbt-dependency-graph/src/sbt-test/sbt-dependency-graph/toFileSubTask/expected/tree.txt
+++ /dev/null
@@ -1,6 +0,0 @@
-org.example:blubber_2.12:0.1 [S]
- +-com.codahale:jerkson_2.9.1:0.5.0 [S]
- +-org.codehaus.jackson:jackson-core-asl:1.9.11
- +-org.codehaus.jackson:jackson-mapper-asl:1.9.11
- +-org.codehaus.jackson:jackson-core-asl:1.9.11
-
\ No newline at end of file
diff --git a/sbt-dependency-graph/src/sbt-test/sbt-dependency-graph/toFileSubTask/project/plugins.sbt b/sbt-dependency-graph/src/sbt-test/sbt-dependency-graph/toFileSubTask/project/plugins.sbt
deleted file mode 100644
index 6fdebb6d6..000000000
--- a/sbt-dependency-graph/src/sbt-test/sbt-dependency-graph/toFileSubTask/project/plugins.sbt
+++ /dev/null
@@ -1 +0,0 @@
-addSbtPlugin("net.virtual-void" % "sbt-dependency-graph" % sys.props("project.version"))
diff --git a/sbt-dependency-graph/src/sbt-test/sbt-dependency-graph/toFileSubTask/test b/sbt-dependency-graph/src/sbt-test/sbt-dependency-graph/toFileSubTask/test
deleted file mode 100644
index 83d872e3e..000000000
--- a/sbt-dependency-graph/src/sbt-test/sbt-dependency-graph/toFileSubTask/test
+++ /dev/null
@@ -1,5 +0,0 @@
-> dependencyTree::toFile target/tree.txt
-> dependencyList::toFile target/list.txt
-> dependencyStats::toFile target/stats.txt
-> dependencyLicenseInfo::toFile target/licenses.txt
-> check
diff --git a/sbt-dependency-graph/src/sbt-test/sbt-dependency-graph/whatDependsOn-without-previous-initialization/project/plugins.sbt b/sbt-dependency-graph/src/sbt-test/sbt-dependency-graph/whatDependsOn-without-previous-initialization/project/plugins.sbt
deleted file mode 100644
index 6fdebb6d6..000000000
--- a/sbt-dependency-graph/src/sbt-test/sbt-dependency-graph/whatDependsOn-without-previous-initialization/project/plugins.sbt
+++ /dev/null
@@ -1 +0,0 @@
-addSbtPlugin("net.virtual-void" % "sbt-dependency-graph" % sys.props("project.version"))
diff --git a/sbt-dependency-graph/src/sbt-test/sbt-dependency-graph/whatDependsOn/project/plugins.sbt b/sbt-dependency-graph/src/sbt-test/sbt-dependency-graph/whatDependsOn/project/plugins.sbt
deleted file mode 100644
index 6fdebb6d6..000000000
--- a/sbt-dependency-graph/src/sbt-test/sbt-dependency-graph/whatDependsOn/project/plugins.sbt
+++ /dev/null
@@ -1 +0,0 @@
-addSbtPlugin("net.virtual-void" % "sbt-dependency-graph" % sys.props("project.version"))
diff --git a/sbt-dependency-graph/src/test/scala/net/virtualvoid/sbt/graph/util/AsciiTreeLayoutSpecs.scala b/sbt-dependency-graph/src/test/scala/net/virtualvoid/sbt/graph/util/AsciiTreeLayoutSpecs.scala
deleted file mode 100644
index 097b7adf6..000000000
--- a/sbt-dependency-graph/src/test/scala/net/virtualvoid/sbt/graph/util/AsciiTreeLayoutSpecs.scala
+++ /dev/null
@@ -1,94 +0,0 @@
-package net.virtualvoid.sbt.graph.util
-
-import org.specs2.mutable.Specification
-
-class AsciiTreeLayoutSpecs extends Specification {
- sealed trait Tree
- case class Branch(left: Tree, right: Tree) extends Tree
- case class Leaf(i: Int) extends Tree
-
- def children(t: Tree): Seq[Tree] = t match {
- case Branch(left, right) ⇒ Seq(left, right)
- case _: Leaf ⇒ Nil
- }
- def display(t: Tree): String = t match {
- case Branch(left, right) ⇒ "Branch"
- case Leaf(value) ⇒ value.toString * value
- }
-
- "Graph" should {
- "layout simple graphs" in {
- val simple = Branch(Branch(Leaf(1), Leaf(2)), Leaf(3))
- AsciiTreeLayout.toAscii(simple, children, display, 20) ===
- """Branch
- | +-Branch
- | | +-1
- | | +-22
- | |\u0020
- | +-333
- | """.stripMargin
- }
- "add separator lines where applicable" in {
- val simple = Branch(Branch(Leaf(1), Branch(Leaf(2), Leaf(3))), Leaf(4))
- AsciiTreeLayout.toAscii(simple, children, display, 20) ===
- """Branch
- | +-Branch
- | | +-1
- | | +-Branch
- | | +-22
- | | +-333
- | |\u0020\u0020\u0020
- | +-4444
- | """.stripMargin
- }
- "layout deep graphs" in {
- val simple = Branch(Branch(Branch(Branch(Branch(Branch(Leaf(1), Leaf(1)), Leaf(1)), Leaf(1)), Leaf(2)), Leaf(3)), Leaf(4))
- AsciiTreeLayout.toAscii(simple, children, display, 10) ===
- """Branch
- | +-Branch
- | | +-Br..
- | | | +-..
- | | | | ..
- | | | | ..
- | | | | ..
- | | | | ..
- | | | | | |\u0020
- | | | | ..
- | | | | |\u0020
- | | | | ..
- | | | |\u0020
- | | | +-22
- | | |\u0020
- | | +-333
- | |\u0020
- | +-4444
- | """.stripMargin
- }
- "cut off cycles" in {
- AsciiTreeLayout.toAscii[Int](1, Map(
- 1 -> Seq(2, 3, 4),
- 2 -> Seq(4, 5),
- 3 -> Seq(),
- 4 -> Seq(3),
- 5 -> Seq(1, 4, 6, 7),
- 6 -> Seq(),
- 7 -> Seq()), _.toString).trim ===
- """1
- | +-2
- | | +-4
- | | | +-3
- | | |\u0020
- | | +-5
- | | #-1 (cycle)
- | | +-4
- | | | +-3
- | | |\u0020
- | | +-6
- | | +-7
- | |\u0020\u0020\u0020
- | +-3
- | +-4
- | +-3""".stripMargin.trim
- }
- }
-}
diff --git a/sbt-dependency-graph/src/sbt-test/sbt-dependency-graph/cachedResolution/build.sbt b/sbt/src/sbt-test/dependency-graph/cachedResolution/build.sbt
similarity index 85%
rename from sbt-dependency-graph/src/sbt-test/sbt-dependency-graph/cachedResolution/build.sbt
rename to sbt/src/sbt-test/dependency-graph/cachedResolution/build.sbt
index e9aef9b55..82144c4a0 100644
--- a/sbt-dependency-graph/src/sbt-test/sbt-dependency-graph/cachedResolution/build.sbt
+++ b/sbt/src/sbt-test/dependency-graph/cachedResolution/build.sbt
@@ -4,8 +4,8 @@ libraryDependencies += "org.slf4j" % "slf4j-api" % "1.7.28"
updateOptions := updateOptions.value.withCachedResolution(true)
TaskKey[Unit]("check") := {
- val report = (ivyReport in Test).value
- val graph = (asciiTree in Test).value
+ val report = (Test / ivyReport).value
+ val graph = (Test / dependencyTree / asString).value
def sanitize(str: String): String = str.split('\n').drop(1).mkString("\n")
val expectedGraph =
diff --git a/sbt-dependency-graph/src/sbt-test/sbt-dependency-graph/cachedResolution/test b/sbt/src/sbt-test/dependency-graph/cachedResolution/test
similarity index 100%
rename from sbt-dependency-graph/src/sbt-test/sbt-dependency-graph/cachedResolution/test
rename to sbt/src/sbt-test/dependency-graph/cachedResolution/test
diff --git a/sbt-dependency-graph/src/sbt-test/sbt-dependency-graph/ignoreScalaLibrary/build.sbt b/sbt/src/sbt-test/dependency-graph/ignoreScalaLibrary/build.sbt
similarity index 91%
rename from sbt-dependency-graph/src/sbt-test/sbt-dependency-graph/ignoreScalaLibrary/build.sbt
rename to sbt/src/sbt-test/dependency-graph/ignoreScalaLibrary/build.sbt
index 1d004c5b6..7e9f4cce2 100644
--- a/sbt-dependency-graph/src/sbt-test/sbt-dependency-graph/ignoreScalaLibrary/build.sbt
+++ b/sbt/src/sbt-test/dependency-graph/ignoreScalaLibrary/build.sbt
@@ -6,8 +6,8 @@ libraryDependencies ++= Seq(
)
TaskKey[Unit]("check") := {
- val report = (ivyReport in Test).value
- val graph = (asciiTree in Test).value
+ val report = updateFull.value
+ val graph = (Test / dependencyTree / asString).value
def sanitize(str: String): String = str.split('\n').drop(1).map(_.trim).mkString("\n")
val expectedGraph =
"""default:default-e95e05_2.9.2:0.1-SNAPSHOT [S]
diff --git a/sbt-dependency-graph/src/sbt-test/sbt-dependency-graph/ignoreScalaLibrary/test b/sbt/src/sbt-test/dependency-graph/ignoreScalaLibrary/test
similarity index 100%
rename from sbt-dependency-graph/src/sbt-test/sbt-dependency-graph/ignoreScalaLibrary/test
rename to sbt/src/sbt-test/dependency-graph/ignoreScalaLibrary/test
diff --git a/sbt-dependency-graph/src/sbt-test/sbt-dependency-graph/showMissingUpdates/build.sbt b/sbt/src/sbt-test/dependency-graph/showMissingUpdates/build.sbt
similarity index 86%
rename from sbt-dependency-graph/src/sbt-test/sbt-dependency-graph/showMissingUpdates/build.sbt
rename to sbt/src/sbt-test/dependency-graph/showMissingUpdates/build.sbt
index da6ad1a2a..192ecb0a9 100644
--- a/sbt-dependency-graph/src/sbt-test/sbt-dependency-graph/showMissingUpdates/build.sbt
+++ b/sbt/src/sbt-test/dependency-graph/showMissingUpdates/build.sbt
@@ -4,8 +4,8 @@ libraryDependencies +=
"at.blub" % "blib" % "1.2.3" % "test"
TaskKey[Unit]("check") := {
- val report = (ivyReport in Test).value
- val graph = (asciiTree in Test).value
+ val report = updateFull.value
+ val graph = (Test / dependencyTree / asString).value
def sanitize(str: String): String = str.split('\n').drop(1).mkString("\n")
val expectedGraph =
diff --git a/sbt-dependency-graph/src/sbt-test/sbt-dependency-graph/intervalRangedVersions/test b/sbt/src/sbt-test/dependency-graph/showMissingUpdates/disabled
similarity index 100%
rename from sbt-dependency-graph/src/sbt-test/sbt-dependency-graph/intervalRangedVersions/test
rename to sbt/src/sbt-test/dependency-graph/showMissingUpdates/disabled
diff --git a/sbt/src/sbt-test/dependency-graph/testDotFileGeneration/build.sbt b/sbt/src/sbt-test/dependency-graph/testDotFileGeneration/build.sbt
new file mode 100644
index 000000000..313bcc9d7
--- /dev/null
+++ b/sbt/src/sbt-test/dependency-graph/testDotFileGeneration/build.sbt
@@ -0,0 +1,53 @@
+import scala.collection.mutable.ListBuffer
+
+ThisBuild / scalaVersion := "2.9.2"
+ThisBuild / version := "0.1-SNAPSHOT"
+
+lazy val justATransiviteDependencyEndpointProject = project
+
+lazy val justATransitiveDependencyProject = project
+ .dependsOn(justATransiviteDependencyEndpointProject)
+
+lazy val justADependencyProject = project
+
+lazy val test_project = project
+ .dependsOn(justADependencyProject, justATransitiveDependencyProject)
+ .settings(
+ TaskKey[Unit]("check") := {
+ val dotFile = (dependencyDot in Compile).value
+ val expectedGraph =
+ """digraph "dependency-graph" {
+ | graph[rankdir="LR"]
+ | edge [
+ | arrowtail="none"
+ | ]
+ | "test_project:test_project_2.9.2:0.1-SNAPSHOT"[label=test_project_2.9.2 0.1-SNAPSHOT> style=""]
+ | "justatransitivedependencyproject:justatransitivedependencyproject_2.9.2:0.1-SNAPSHOT"[label=justatransitivedependencyproject_2.9.2 0.1-SNAPSHOT> style=""]
+ | "justatransivitedependencyendpointproject:justatransivitedependencyendpointproject_2.9.2:0.1-SNAPSHOT"[label=justatransivitedependencyendpointproject_2.9.2 0.1-SNAPSHOT> style=""]
+ | "justadependencyproject:justadependencyproject_2.9.2:0.1-SNAPSHOT"[label=justadependencyproject_2.9.2 0.1-SNAPSHOT> style=""]
+ | "test_project:test_project_2.9.2:0.1-SNAPSHOT" -> "justatransitivedependencyproject:justatransitivedependencyproject_2.9.2:0.1-SNAPSHOT"
+ | "justatransitivedependencyproject:justatransitivedependencyproject_2.9.2:0.1-SNAPSHOT" -> "justatransivitedependencyendpointproject:justatransivitedependencyendpointproject_2.9.2:0.1-SNAPSHOT"
+ | "test_project:test_project_2.9.2:0.1-SNAPSHOT" -> "justadependencyproject:justadependencyproject_2.9.2:0.1-SNAPSHOT"
+ |}
+ """.stripMargin
+
+ val graph : String = scala.io.Source.fromFile(dotFile.getAbsolutePath).mkString
+ val errors = compareByLine(graph, expectedGraph)
+ require(errors.isEmpty , errors.mkString("\n"))
+ ()
+ }
+ )
+
+def compareByLine(got : String, expected : String) : Seq[String] = {
+ val errors = ListBuffer[String]()
+ got.split("\n").zip(expected.split("\n").toSeq).zipWithIndex.foreach { case((got_line : String, expected_line : String), i : Int) =>
+ if(got_line != expected_line) {
+ errors.append(
+ """not matching lines at line %s
+ |expected: %s
+ |got: %s
+ |""".stripMargin.format(i,expected_line, got_line))
+ }
+ }
+ errors
+}
\ No newline at end of file
diff --git a/sbt/src/sbt-test/dependency-graph/testDotFileGeneration/test b/sbt/src/sbt-test/dependency-graph/testDotFileGeneration/test
new file mode 100644
index 000000000..cc5aac014
--- /dev/null
+++ b/sbt/src/sbt-test/dependency-graph/testDotFileGeneration/test
@@ -0,0 +1 @@
+> test_project/check
diff --git a/sbt-dependency-graph/src/sbt-test/sbt-dependency-graph/toFileSubTask/build.sbt b/sbt/src/sbt-test/dependency-graph/toFileSubTask/build.sbt
similarity index 73%
rename from sbt-dependency-graph/src/sbt-test/sbt-dependency-graph/toFileSubTask/build.sbt
rename to sbt/src/sbt-test/dependency-graph/toFileSubTask/build.sbt
index d34ee89e9..6b66e7321 100644
--- a/sbt-dependency-graph/src/sbt-test/sbt-dependency-graph/toFileSubTask/build.sbt
+++ b/sbt/src/sbt-test/dependency-graph/toFileSubTask/build.sbt
@@ -1,15 +1,10 @@
-scalaVersion := "2.12.6"
-
-organization := "org.example"
+// ThisBuild / useCoursier := false
+ThisBuild / scalaVersion := "2.12.6"
+ThisBuild / organization := "org.example"
+ThisBuild / version := "0.1"
name := "blubber"
-
-version := "0.1"
-
-libraryDependencies ++= Seq(
- "com.codahale" % "jerkson_2.9.1" % "0.5.0"
-)
-
+libraryDependencies += "org.typelevel" %% "cats-effect" % "2.2.0"
TaskKey[Unit]("check") := {
val candidates = "tree list stats licenses".split(' ').map(_.trim)
candidates.foreach { c =>
diff --git a/sbt/src/sbt-test/dependency-graph/toFileSubTask/expected/licenses.txt b/sbt/src/sbt-test/dependency-graph/toFileSubTask/expected/licenses.txt
new file mode 100644
index 000000000..012b770f5
--- /dev/null
+++ b/sbt/src/sbt-test/dependency-graph/toFileSubTask/expected/licenses.txt
@@ -0,0 +1,9 @@
+No license specified
+ org.example:blubber_2.12:0.1
+
+Apache-2.0
+ org.typelevel:cats-effect_2.12:2.2.0
+
+MIT
+ org.typelevel:cats-kernel_2.12:2.2.0
+ org.typelevel:cats-core_2.12:2.2.0
\ No newline at end of file
diff --git a/sbt/src/sbt-test/dependency-graph/toFileSubTask/expected/list.txt b/sbt/src/sbt-test/dependency-graph/toFileSubTask/expected/list.txt
new file mode 100644
index 000000000..1a356d64b
--- /dev/null
+++ b/sbt/src/sbt-test/dependency-graph/toFileSubTask/expected/list.txt
@@ -0,0 +1,4 @@
+org.example:blubber_2.12:0.1
+org.typelevel:cats-core_2.12:2.2.0
+org.typelevel:cats-effect_2.12:2.2.0
+org.typelevel:cats-kernel_2.12:2.2.0
\ No newline at end of file
diff --git a/sbt/src/sbt-test/dependency-graph/toFileSubTask/expected/stats.txt b/sbt/src/sbt-test/dependency-graph/toFileSubTask/expected/stats.txt
new file mode 100644
index 000000000..3f3c415f0
--- /dev/null
+++ b/sbt/src/sbt-test/dependency-graph/toFileSubTask/expected/stats.txt
@@ -0,0 +1,12 @@
+ TotSize JarSize #TDe #Dep Module
+ 11.177 MB ------- MB 3 1 org.example:blubber_2.12:0.1
+ 11.177 MB 1.185 MB 2 1 org.typelevel:cats-effect_2.12:2.2.0
+ 9.992 MB 5.034 MB 1 1 org.typelevel:cats-core_2.12:2.2.0
+ 4.958 MB 4.958 MB 0 0 org.typelevel:cats-kernel_2.12:2.2.0
+
+Columns are
+ - Jar-Size including dependencies
+ - Jar-Size
+ - Number of transitive dependencies
+ - Number of direct dependencies
+ - ModuleID
\ No newline at end of file
diff --git a/sbt/src/sbt-test/dependency-graph/toFileSubTask/expected/tree.txt b/sbt/src/sbt-test/dependency-graph/toFileSubTask/expected/tree.txt
new file mode 100644
index 000000000..d639a0acb
--- /dev/null
+++ b/sbt/src/sbt-test/dependency-graph/toFileSubTask/expected/tree.txt
@@ -0,0 +1,5 @@
+org.example:blubber_2.12:0.1 [S]
+ +-org.typelevel:cats-effect_2.12:2.2.0 [S]
+ +-org.typelevel:cats-core_2.12:2.2.0 [S]
+ +-org.typelevel:cats-kernel_2.12:2.2.0 [S]
+
\ No newline at end of file
diff --git a/sbt/src/sbt-test/dependency-graph/toFileSubTask/test b/sbt/src/sbt-test/dependency-graph/toFileSubTask/test
new file mode 100644
index 000000000..b905a41b8
--- /dev/null
+++ b/sbt/src/sbt-test/dependency-graph/toFileSubTask/test
@@ -0,0 +1,5 @@
+> dependencyTree/toFile target/tree.txt
+> dependencyList/toFile target/list.txt
+> dependencyStats/toFile target/stats.txt
+> dependencyLicenseInfo/toFile target/licenses.txt
+> check
diff --git a/sbt-dependency-graph/src/sbt-test/sbt-dependency-graph/whatDependsOn-without-previous-initialization/build.sbt b/sbt/src/sbt-test/dependency-graph/whatDependsOn-without-previous-initialization/build.sbt
similarity index 98%
rename from sbt-dependency-graph/src/sbt-test/sbt-dependency-graph/whatDependsOn-without-previous-initialization/build.sbt
rename to sbt/src/sbt-test/dependency-graph/whatDependsOn-without-previous-initialization/build.sbt
index 92bb3b2dd..0586054cd 100644
--- a/sbt-dependency-graph/src/sbt-test/sbt-dependency-graph/whatDependsOn-without-previous-initialization/build.sbt
+++ b/sbt/src/sbt-test/dependency-graph/whatDependsOn-without-previous-initialization/build.sbt
@@ -1,3 +1,5 @@
+ThisBuild / useCoursier := false
+
version := "0.1.0-SNAPSHOT"
organization := "default"
diff --git a/sbt-dependency-graph/src/sbt-test/sbt-dependency-graph/whatDependsOn-without-previous-initialization/test b/sbt/src/sbt-test/dependency-graph/whatDependsOn-without-previous-initialization/test
similarity index 100%
rename from sbt-dependency-graph/src/sbt-test/sbt-dependency-graph/whatDependsOn-without-previous-initialization/test
rename to sbt/src/sbt-test/dependency-graph/whatDependsOn-without-previous-initialization/test
diff --git a/sbt-dependency-graph/src/sbt-test/sbt-dependency-graph/whatDependsOn/build.sbt b/sbt/src/sbt-test/dependency-graph/whatDependsOn/build.sbt
similarity index 58%
rename from sbt-dependency-graph/src/sbt-test/sbt-dependency-graph/whatDependsOn/build.sbt
rename to sbt/src/sbt-test/dependency-graph/whatDependsOn/build.sbt
index 19c9108a1..8b3a0d5e1 100644
--- a/sbt-dependency-graph/src/sbt-test/sbt-dependency-graph/whatDependsOn/build.sbt
+++ b/sbt/src/sbt-test/dependency-graph/whatDependsOn/build.sbt
@@ -1,6 +1,7 @@
-version := "0.1.0-SNAPSHOT"
+ThisBuild / version := "0.1.0-SNAPSHOT"
+ThisBuild / scalaVersion := "2.9.1"
-scalaVersion := "2.9.1"
+name := "whatDependsOn"
resolvers += "typesafe maven" at "https://repo.typesafe.com/typesafe/maven-releases/"
@@ -18,18 +19,18 @@ check := {
val withVersion =
(whatDependsOn in Compile)
- .toTask(" org.codehaus.jackson jackson-core-asl 1.9.11")
+ .toTask(" org.codehaus.jackson jackson-core-asl 1.9.10")
.value
val expectedGraphWithVersion =
- """org.codehaus.jackson:jackson-core-asl:1.9.11
+ """org.codehaus.jackson:jackson-core-asl:1.9.10
| +-com.codahale:jerkson_2.9.1:0.5.0 [S]
- | | +-default:whatdependson_2.9.1:0.1.0-SNAPSHOT [S]
+ | | +-whatdependson:whatdependson_2.9.1:0.1.0-SNAPSHOT [S]
| |
- | +-org.codehaus.jackson:jackson-mapper-asl:1.9.11
+ | +-org.codehaus.jackson:jackson-mapper-asl:1.9.10
| +-com.codahale:jerkson_2.9.1:0.5.0 [S]
- | | +-default:whatdependson_2.9.1:0.1.0-SNAPSHOT [S]
+ | | +-whatdependson:whatdependson_2.9.1:0.1.0-SNAPSHOT [S]
| |
- | +-default:whatdependson_2.9.1:0.1.0-SNAPSHOT [S]
+ | +-whatdependson:whatdependson_2.9.1:0.1.0-SNAPSHOT [S]
| """.stripMargin
checkOutput(withVersion, expectedGraphWithVersion)
@@ -39,14 +40,15 @@ check := {
.toTask(" org.codehaus.jackson jackson-mapper-asl")
.value
val expectedGraphWithoutVersion =
- """org.codehaus.jackson:jackson-mapper-asl:1.9.11
+ """org.codehaus.jackson:jackson-mapper-asl:1.9.10
| +-com.codahale:jerkson_2.9.1:0.5.0 [S]
- | | +-default:whatdependson_2.9.1:0.1.0-SNAPSHOT [S]
+ | | +-whatdependson:whatdependson_2.9.1:0.1.0-SNAPSHOT [S]
| |
- | +-default:whatdependson_2.9.1:0.1.0-SNAPSHOT [S]
+ | +-whatdependson:whatdependson_2.9.1:0.1.0-SNAPSHOT [S]
|
- |org.codehaus.jackson:jackson-mapper-asl:1.9.10 (evicted by: 1.9.11)
- | +-default:whatdependson_2.9.1:0.1.0-SNAPSHOT [S]
+ |org.codehaus.jackson:jackson-mapper-asl:[1.9.0,2.0.0) (evicted by: 1.9.10)
+ | +-com.codahale:jerkson_2.9.1:0.5.0 [S]
+ | +-whatdependson:whatdependson_2.9.1:0.1.0-SNAPSHOT [S]
| """.stripMargin
checkOutput(withoutVersion, expectedGraphWithoutVersion)
}
diff --git a/sbt-dependency-graph/src/sbt-test/sbt-dependency-graph/whatDependsOn/test b/sbt/src/sbt-test/dependency-graph/whatDependsOn/test
similarity index 100%
rename from sbt-dependency-graph/src/sbt-test/sbt-dependency-graph/whatDependsOn/test
rename to sbt/src/sbt-test/dependency-graph/whatDependsOn/test