From 271db4b0f2f3dee52a1e718b9fdeb82eb5fe1dfc Mon Sep 17 00:00:00 2001 From: Ryan Williams Date: Fri, 8 Dec 2017 00:10:36 +0000 Subject: [PATCH] add file-output option to dependencyTree --- README.md | 1 + .../sbt/graph/DependencyGraphKeys.scala | 4 +-- .../sbt/graph/DependencyGraphSettings.scala | 32 +++++++++++++++---- .../dependencyTreeFile/build.sbt | 30 +++++++++++++++++ .../dependencyTreeFile/project/plugins.sbt | 1 + .../dependencyTreeFile/test | 2 ++ 6 files changed, 62 insertions(+), 8 deletions(-) create mode 100644 src/sbt-test/sbt-dependency-graph/dependencyTreeFile/build.sbt create mode 100644 src/sbt-test/sbt-dependency-graph/dependencyTreeFile/project/plugins.sbt create mode 100644 src/sbt-test/sbt-dependency-graph/dependencyTreeFile/test diff --git a/README.md b/README.md index e4ad588..db5a5ff 100644 --- a/README.md +++ b/README.md @@ -22,6 +22,7 @@ the notes of version [0.8.2](https://github.com/jrudolph/sbt-dependency-graph/tr ## Main Tasks * `dependencyTree`: Shows an ASCII tree representation of the project's dependencies + * write output to a file by passing `-o ` arguments * `dependencyBrowseGraph`: Opens a browser window with a visualization of the dependency graph (courtesy of graphlib-dot + dagre-d3). * `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 diff --git a/src/main/scala/net/virtualvoid/sbt/graph/DependencyGraphKeys.scala b/src/main/scala/net/virtualvoid/sbt/graph/DependencyGraphKeys.scala index ace01d1..c3484d4 100644 --- a/src/main/scala/net/virtualvoid/sbt/graph/DependencyGraphKeys.scala +++ b/src/main/scala/net/virtualvoid/sbt/graph/DependencyGraphKeys.scala @@ -51,7 +51,7 @@ trait DependencyGraphKeys { "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", + val dependencyTree = InputKey[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") @@ -74,4 +74,4 @@ trait DependencyGraphKeys { private[graph] val crossProjectId = SettingKey[ModuleID]("dependency-graph-cross-project-id") } -object DependencyGraphKeys extends DependencyGraphKeys \ No newline at end of file +object DependencyGraphKeys extends DependencyGraphKeys diff --git a/src/main/scala/net/virtualvoid/sbt/graph/DependencyGraphSettings.scala b/src/main/scala/net/virtualvoid/sbt/graph/DependencyGraphSettings.scala index 2bf7a13..cacad47 100644 --- a/src/main/scala/net/virtualvoid/sbt/graph/DependencyGraphSettings.scala +++ b/src/main/scala/net/virtualvoid/sbt/graph/DependencyGraphSettings.scala @@ -17,6 +17,8 @@ package net.virtualvoid.sbt.graph import scala.language.reflectiveCalls +import java.nio.file.Files.newOutputStream +import java.nio.file.{ Path, Paths } import sbt._ import Keys._ @@ -25,7 +27,6 @@ import net.virtualvoid.sbt.graph.backend.{ IvyReport, SbtUpdateReport } import net.virtualvoid.sbt.graph.rendering.{ AsciiGraph, DagreHTML } import net.virtualvoid.sbt.graph.util.IOUtil import internal.librarymanagement._ -import librarymanagement._ import sbt.dependencygraph.DependencyGraphSbtCompat import sbt.dependencygraph.DependencyGraphSbtCompat.Implicits._ @@ -45,7 +46,7 @@ object DependencyGraphSettings { Seq(Compile, Test, IntegrationTest, Runtime, Provided, Optional).flatMap(ivyReportForConfig) def ivyReportForConfig(config: Configuration) = inConfig(config)(Seq( - ivyReport := { Def.task { ivyReportFunction.value.apply(config.toString) } dependsOn (ignoreMissingUpdate) }.value, + 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), @@ -66,7 +67,19 @@ object DependencyGraphSettings { }, moduleGraphStore := (moduleGraph storeAs moduleGraphStore triggeredBy moduleGraph).value, asciiTree := rendering.AsciiTree.asciiTree(moduleGraph.value), - dependencyTree := print(asciiTree).value, + dependencyTree := { + val tree = asciiTree.value + dependencyTreeOutputPathParser.parsed match { + case Some(path) ⇒ + streams.value.log.info(s"Writing dependency-tree to path: $path") + val os = newOutputStream(path) + os.write(tree.getBytes) + os.close() + case _ ⇒ + streams.value.log.info(tree) + } + + }, dependencyGraphMLFile := { target.value / "dependencies-%s.graphml".format(config.toString) }, dependencyGraphML := dependencyGraphMLTask.value, dependencyDotFile := { target.value / "dependencies-%s.dot".format(config.toString) }, @@ -152,13 +165,20 @@ object DependencyGraphSettings { streams.log.info(output) } - import Project._ + import sbt.complete.DefaultParsers._ val shouldForceParser: State ⇒ Parser[Boolean] = { (state: State) ⇒ - import sbt.complete.DefaultParsers._ - (Space ~> token("--force")).?.map(_.isDefined) } + val dependencyTreeOutputPathParser: State ⇒ Parser[Option[Path]] = { (state: State) ⇒ + ( + Space ~ + (token("--out") | token("-o")) ~ Space ~> + StringBasic) + .map(Paths.get(_)) + .? + } + val artifactIdParser: Def.Initialize[State ⇒ Parser[ModuleId]] = resolvedScoped { ctx ⇒ (state: State) ⇒ diff --git a/src/sbt-test/sbt-dependency-graph/dependencyTreeFile/build.sbt b/src/sbt-test/sbt-dependency-graph/dependencyTreeFile/build.sbt new file mode 100644 index 0000000..67e2cdb --- /dev/null +++ b/src/sbt-test/sbt-dependency-graph/dependencyTreeFile/build.sbt @@ -0,0 +1,30 @@ +import java.nio.file.{ Files, Paths } + +import scala.io.Source + +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" +) + +InputKey[Unit]("check") := { + val is = Files.newInputStream(Paths.get("foo")) + val tree = Source.fromInputStream(is).mkString + is.close() + + require( + tree == + """default:dependencytreefile_2.9.1: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, + s"Tree didn't match expected:\n$tree" + ) + () +} diff --git a/src/sbt-test/sbt-dependency-graph/dependencyTreeFile/project/plugins.sbt b/src/sbt-test/sbt-dependency-graph/dependencyTreeFile/project/plugins.sbt new file mode 100644 index 0000000..6fdebb6 --- /dev/null +++ b/src/sbt-test/sbt-dependency-graph/dependencyTreeFile/project/plugins.sbt @@ -0,0 +1 @@ +addSbtPlugin("net.virtual-void" % "sbt-dependency-graph" % sys.props("project.version")) diff --git a/src/sbt-test/sbt-dependency-graph/dependencyTreeFile/test b/src/sbt-test/sbt-dependency-graph/dependencyTreeFile/test new file mode 100644 index 0000000..c13eff4 --- /dev/null +++ b/src/sbt-test/sbt-dependency-graph/dependencyTreeFile/test @@ -0,0 +1,2 @@ +> dependencyTree -o foo +> check