diff --git a/.travis.yml b/.travis.yml index c0a6784d3..b77395cbd 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-graph/* dependency-management/* plugins/* project-load/* java/* run/* nio/*" + - SBT_CMD="dependencyTreeProj/publishLocal; 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/build.sbt b/build.sbt index 40902658f..e5e2e1b24 100644 --- a/build.sbt +++ b/build.sbt @@ -648,6 +648,15 @@ lazy val scriptedPluginProj = (project in file("scripted-plugin")) ), ) +lazy val dependencyTreeProj = (project in file("dependency-tree")) + .dependsOn(sbtProj) + .settings( + sbtPlugin := true, + baseSettings, + name := "sbt-dependency-tree", + // mimaSettings, + ) + // Implementation and support code for defining actions. lazy val actionsProj = (project in file("main-actions")) .dependsOn( @@ -1361,6 +1370,7 @@ def allProjects = scriptedSbtReduxProj, scriptedSbtOldProj, scriptedPluginProj, + dependencyTreeProj, protocolProj, actionsProj, commandProj, diff --git a/dependency-tree/src/main/scala/sbt/plugins/DependencyTreePlugin.scala b/dependency-tree/src/main/scala/sbt/plugins/DependencyTreePlugin.scala new file mode 100644 index 000000000..1fbaabd70 --- /dev/null +++ b/dependency-tree/src/main/scala/sbt/plugins/DependencyTreePlugin.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 plugins + +object DependencyTreePlugin extends AutoPlugin { + object autoImport extends DependencyTreeKeys + override def trigger = AllRequirements + override def requires = MiniDependencyTreePlugin + + val configurations = Vector(Compile, Test, IntegrationTest, Runtime, Provided, Optional) + + // MiniDependencyTreePlugin provides baseBasicReportingSettings for Compile and Test + override def projectSettings: Seq[Def.Setting[_]] = + ((configurations diff Vector(Compile, Test)) flatMap { config => + inConfig(config)(DependencyTreeSettings.baseBasicReportingSettings) + }) ++ + (configurations flatMap { config => + inConfig(config)(DependencyTreeSettings.baseFullReportingSettings) + }) +} diff --git a/main/src/main/scala/sbt/Defaults.scala b/main/src/main/scala/sbt/Defaults.scala index 73a951c8d..1fc41c277 100644 --- a/main/src/main/scala/sbt/Defaults.scala +++ b/main/src/main/scala/sbt/Defaults.scala @@ -3983,6 +3983,16 @@ trait BuildExtra extends BuildCommon with DefExtra { Seq(compose(onLoad, add), compose(onUnload, remove)) } + /** + * Adds Maven resolver plugin. + */ + def addDependencyTreePlugin: Setting[Seq[ModuleID]] = + libraryDependencies += sbtPluginExtra( + ModuleID("org.scala-sbt", "sbt-dependency-tree", sbtVersion.value), + sbtBinaryVersion.value, + scalaBinaryVersion.value + ) + /** * Adds Maven resolver plugin. */ diff --git a/main/src/main/scala/sbt/internal/PluginDiscovery.scala b/main/src/main/scala/sbt/internal/PluginDiscovery.scala index 3f6a9f450..0f3998fc5 100644 --- a/main/src/main/scala/sbt/internal/PluginDiscovery.scala +++ b/main/src/main/scala/sbt/internal/PluginDiscovery.scala @@ -52,7 +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, + "sbt.plugins.MiniDependencyTreePlugin" -> sbt.plugins.MiniDependencyTreePlugin, ) val detectedAutoPlugins = discover[AutoPlugin](AutoPlugins) val allAutoPlugins = (defaultAutoPlugins ++ detectedAutoPlugins.modules) map { diff --git a/main/src/main/scala/sbt/internal/graph/DependencyGraphKeys.scala b/main/src/main/scala/sbt/plugins/DependencyTreeKeys.scala similarity index 78% rename from main/src/main/scala/sbt/internal/graph/DependencyGraphKeys.scala rename to main/src/main/scala/sbt/plugins/DependencyTreeKeys.scala index a02ae6a87..d481fe66b 100644 --- a/main/src/main/scala/sbt/internal/graph/DependencyGraphKeys.scala +++ b/main/src/main/scala/sbt/plugins/DependencyTreeKeys.scala @@ -6,23 +6,36 @@ */ package sbt -package internal -package graph +package plugins import java.io.File import java.net.URI +import sbt.internal.graph._ import sbt.BuildSyntax._ import sbt.librarymanagement.{ ModuleID, UpdateReport } -trait DependencyGraphKeys { +trait MiniDependencyTreeKeys { + val dependencyTreeIncludeScalaLibrary = settingKey[Boolean]( + "Specifies if scala dependency should be included in dependencyTree output" + ) + val dependencyTree = taskKey[Unit]("Prints an ascii tree of all the dependencies to the console") 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" - ) + // 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 MiniDependencyTreeKeys extends MiniDependencyTreeKeys + +abstract class DependencyTreeKeys { val dependencyGraphMLFile = settingKey[File]("The location the graphml file should be generated at") val dependencyGraphML = @@ -59,37 +72,15 @@ trait DependencyGraphKeys { 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 dependencyTreeModuleGraph = taskKey[ModuleGraph]("The dependency graph for a project") + 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 +object DependencyTreeKeys extends DependencyTreeKeys diff --git a/main/src/main/scala/sbt/plugins/DependencyGraphPlugin.scala b/main/src/main/scala/sbt/plugins/DependencyTreeSettings.scala similarity index 57% rename from main/src/main/scala/sbt/plugins/DependencyGraphPlugin.scala rename to main/src/main/scala/sbt/plugins/DependencyTreeSettings.scala index dd546e5ab..957531a13 100644 --- a/main/src/main/scala/sbt/plugins/DependencyGraphPlugin.scala +++ b/main/src/main/scala/sbt/plugins/DependencyTreeSettings.scala @@ -13,43 +13,26 @@ 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.backend.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 { +object DependencyTreeSettings { import sjsonnew.BasicJsonProtocol._ + import MiniDependencyTreeKeys._ + import DependencyTreeKeys._ - 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 = + /** + * Core settings needed for any graphing tasks. + */ + def coreSettings = 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 @@ -73,102 +56,94 @@ object DependencyGraphPlugin extends AutoPlugin { }, ) - def reportSettings = - Seq(Compile, Test, IntegrationTest, Runtime, Provided, Optional).flatMap(ivyReportForConfig) - - val renderingAlternatives: Seq[(TaskKey[Unit], ModuleGraph => String)] = + /** + * MiniDependencyTreePlugin includes these settings for Compile and Test scopes + * to provide dependencyTree task. + */ + lazy val baseBasicReportingSettings: Seq[Def.Setting[_]] = Seq( - dependencyTree -> rendering.AsciiTree.asciiTree _, - dependencyList -> rendering.FlatList.render(_.id.idString), - dependencyStats -> rendering.Statistics.renderModuleStatsList _, - dependencyLicenseInfo -> rendering.LicenseInfo.render _ - ) + crossProjectId := CrossVersion(scalaVersion.value, scalaBinaryVersion.value)( + projectID.value + ), + dependencyTreeModuleGraph := { + val sv = scalaVersion.value + val g = ignoreMissingUpdate.value + .configuration(configuration.value) + .map(report => SbtUpdateReport.fromConfigurationReport(report, crossProjectId.value)) + .getOrElse(ModuleGraph.empty) + if (dependencyTreeIncludeScalaLibrary.value) g + else GraphTransformations.ignoreScalaLibrary(sv, g) + }, + moduleGraphStore := (dependencyTreeModuleGraph storeAs moduleGraphStore triggeredBy dependencyTreeModuleGraph).value, + ) ++ renderingTaskSettings(dependencyTree, rendering.AsciiTree.asciiTree _) - 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" { + /** + * This is the maximum strength settings for DependencyTreePlugin. + */ + lazy val baseFullReportingSettings: Seq[Def.Setting[_]] = + Seq( + // 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 := { + val config = configuration.value + target.value / "dependencies-%s.dot".format(config.toString) + }, + dependencyDot / asString := rendering.DOT.dotGraph( + dependencyTreeModuleGraph.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) + dependencyDotNodeLabel := { (organization: String, name: String, version: String) => + """%s
%s
%s""".format(organization, name, version) + }, + // GraphML support + dependencyGraphMLFile := { + val config = configuration.value + target.value / "dependencies-%s.graphml".format(config.toString) + }, + dependencyGraphML := dependencyGraphMLTask.value, + whatDependsOn := { + val ArtifactPattern(org, name, versionFilter) = artifactPatternParser.parsed + val graph = dependencyTreeModuleGraph.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)) } - val output = - modules - .map { module => - rendering.AsciiTree - .asciiTree(GraphTransformations.reverseGraphStartingAt(graph, module)) - } - .mkString("\n") + .mkString("\n") - streams.value.log.info(output) - output - }, - ) ++ - renderingAlternatives.flatMap((renderingTaskSettings _).tupled) + streams.value.log.info(output) + output + }, + ) ++ + renderingAlternatives.flatMap((renderingTaskSettings _).tupled) + + def renderingAlternatives: Seq[(TaskKey[Unit], ModuleGraph => String)] = + Seq( + dependencyList -> rendering.FlatList.render(_.id.idString), + dependencyStats -> rendering.Statistics.renderModuleStatsList _, + dependencyLicenseInfo -> rendering.LicenseInfo.render _ ) def renderingTaskSettings(key: TaskKey[Unit], renderer: ModuleGraph => String): Seq[Setting[_]] = @@ -178,37 +153,27 @@ object DependencyGraphPlugin extends AutoPlugin { val str = (key / asString).value s.log.info(str) }, - key / asString := renderer(moduleGraph.value), + key / asString := renderer(dependencyTreeModuleGraph.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) + val graph = dependencyTreeModuleGraph.value + rendering.GraphML.saveAsGraphML(graph, resultFile.getAbsolutePath) streams.value.log.info("Wrote dependency graph to '%s'" format resultFile) resultFile } def browseGraphHTMLTask = Def.task { + val graph = dependencyTreeModuleGraph.value val dotGraph = rendering.DOT.dotGraph( - moduleGraph.value, + graph, dependencyDotHeader.value, dependencyDotNodeLabel.value, rendering.DOT.LabelTypeHtml @@ -220,7 +185,8 @@ object DependencyGraphPlugin extends AutoPlugin { def browseTreeHTMLTask = Def.task { - val renderedTree = TreeView.createJson(moduleGraph.value) + val graph = dependencyTreeModuleGraph.value + val renderedTree = TreeView.createJson(graph) val link = TreeView.createLink(renderedTree, target.value) streams.value.log.info(s"HTML tree written to $link") link diff --git a/main/src/main/scala/sbt/plugins/MiniDependencyTreePlugin.scala b/main/src/main/scala/sbt/plugins/MiniDependencyTreePlugin.scala new file mode 100644 index 000000000..2236c21c9 --- /dev/null +++ b/main/src/main/scala/sbt/plugins/MiniDependencyTreePlugin.scala @@ -0,0 +1,27 @@ +/* + * sbt + * Copyright 2011 - 2018, Lightbend, Inc. + * Copyright 2008 - 2010, Mark Harrah + * Licensed under Apache License 2.0 (see LICENSE) + */ + +package sbt +package plugins + +import sbt.PluginTrigger.AllRequirements +import sbt.Project._ +import sbt.librarymanagement.Configurations.{ Compile, Test } + +object MiniDependencyTreePlugin extends AutoPlugin { + object autoImport extends MiniDependencyTreeKeys + + import autoImport._ + override def trigger: PluginTrigger = AllRequirements + override def globalSettings: Seq[Def.Setting[_]] = Seq( + dependencyTreeIncludeScalaLibrary := false + ) + override def projectSettings: Seq[Def.Setting[_]] = + DependencyTreeSettings.coreSettings ++ + inConfig(Compile)(DependencyTreeSettings.baseBasicReportingSettings) ++ + inConfig(Test)(DependencyTreeSettings.baseBasicReportingSettings) +} diff --git a/sbt/src/sbt-test/dependency-graph/cachedResolution/build.sbt b/sbt/src/sbt-test/dependency-graph/cachedResolution/build.sbt index 82144c4a0..e4d1990a8 100644 --- a/sbt/src/sbt-test/dependency-graph/cachedResolution/build.sbt +++ b/sbt/src/sbt-test/dependency-graph/cachedResolution/build.sbt @@ -4,7 +4,7 @@ libraryDependencies += "org.slf4j" % "slf4j-api" % "1.7.28" updateOptions := updateOptions.value.withCachedResolution(true) TaskKey[Unit]("check") := { - val report = (Test / ivyReport).value + val report = (Test / updateFull).value val graph = (Test / dependencyTree / asString).value def sanitize(str: String): String = str.split('\n').drop(1).mkString("\n") diff --git a/sbt/src/sbt-test/dependency-graph/testDotFileGeneration/project/plugins.sbt b/sbt/src/sbt-test/dependency-graph/testDotFileGeneration/project/plugins.sbt new file mode 100644 index 000000000..93c66d2a9 --- /dev/null +++ b/sbt/src/sbt-test/dependency-graph/testDotFileGeneration/project/plugins.sbt @@ -0,0 +1 @@ +addDependencyTreePlugin diff --git a/sbt/src/sbt-test/dependency-graph/toFileSubTask/project/plugins.sbt b/sbt/src/sbt-test/dependency-graph/toFileSubTask/project/plugins.sbt new file mode 100644 index 000000000..93c66d2a9 --- /dev/null +++ b/sbt/src/sbt-test/dependency-graph/toFileSubTask/project/plugins.sbt @@ -0,0 +1 @@ +addDependencyTreePlugin diff --git a/sbt/src/sbt-test/dependency-graph/whatDependsOn-without-previous-initialization/project/plugins.sbt b/sbt/src/sbt-test/dependency-graph/whatDependsOn-without-previous-initialization/project/plugins.sbt new file mode 100644 index 000000000..93c66d2a9 --- /dev/null +++ b/sbt/src/sbt-test/dependency-graph/whatDependsOn-without-previous-initialization/project/plugins.sbt @@ -0,0 +1 @@ +addDependencyTreePlugin diff --git a/sbt/src/sbt-test/dependency-graph/whatDependsOn/project/plugins.sbt b/sbt/src/sbt-test/dependency-graph/whatDependsOn/project/plugins.sbt new file mode 100644 index 000000000..93c66d2a9 --- /dev/null +++ b/sbt/src/sbt-test/dependency-graph/whatDependsOn/project/plugins.sbt @@ -0,0 +1 @@ +addDependencyTreePlugin diff --git a/sbt/src/sbt-test/dependency-graph/whatDependsOn/test b/sbt/src/sbt-test/dependency-graph/whatDependsOn/test index 961ba2cf3..9ec624418 100644 --- a/sbt/src/sbt-test/dependency-graph/whatDependsOn/test +++ b/sbt/src/sbt-test/dependency-graph/whatDependsOn/test @@ -1,3 +1,3 @@ # to initialize parser with deps -> compile:moduleGraph +> Compile/dependencyTreeModuleGraph > check \ No newline at end of file