diff --git a/README.md b/README.md index f8eb74b2d..798dadee2 100644 --- a/README.md +++ b/README.md @@ -47,6 +47,9 @@ Tasks & Settings * `dependency-tree`: Shows an ASCII tree representation of the project's dependencies * `what-depends-on `: Find out what depends on an artifact. Shows a reverse dependency tree for the selected module. + * `filter-scala-library`: 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) * `dependency-graph-ml-file`: a setting which allows configuring the output path of `dependency-graph-ml`. * `ivy-report`: let's ivy generate the resolution report for you project. Use `show ivy-report` for the filename of the generated report diff --git a/notes/0.7.0.markdown b/notes/0.7.0.markdown index a4e96c1a4..dab5287a3 100644 --- a/notes/0.7.0.markdown +++ b/notes/0.7.0.markdown @@ -6,5 +6,7 @@ New features in this version: * 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. diff --git a/src/main/scala/net/virtualvoid/sbt/graph/IvyGraphMLDependencies.scala b/src/main/scala/net/virtualvoid/sbt/graph/IvyGraphMLDependencies.scala index 335345655..efcb1d143 100644 --- a/src/main/scala/net/virtualvoid/sbt/graph/IvyGraphMLDependencies.scala +++ b/src/main/scala/net/virtualvoid/sbt/graph/IvyGraphMLDependencies.scala @@ -34,6 +34,7 @@ object IvyGraphMLDependencies extends App { def idString: String = organisation+":"+name+":"+version } case class Module(id: ModuleId, + extraInfo: String = "", evictedByVersion: Option[String] = None, error: Option[String] = None) { def hadError: Boolean = error.isDefined @@ -113,6 +114,24 @@ object IvyGraphMLDependencies extends App { ModuleGraph(nodes.toSeq, edges) } + def ignoreScalaLibrary(scalaVersion: String, graph: ModuleGraph): ModuleGraph = { + val scalaLibraryId = ModuleId("org.scala-lang", "scala-library", scalaVersion) + + def dependsOnScalaLibrary(m: Module): Boolean = + graph.dependencyMap(m.id).map(_.id).contains(scalaLibraryId) + + def addScalaLibraryAnnotation(m: Module): Module = { + if (dependsOnScalaLibrary(m)) + m.copy(extraInfo = m.extraInfo + " [S]") + else + m + } + + val newNodes = graph.nodes.map(addScalaLibraryAnnotation).filterNot(_.id == scalaLibraryId) + val newEdges = graph.edges.filterNot(_._2 == scalaLibraryId) + ModuleGraph(newNodes, newEdges) + } + def asciiGraph(graph: ModuleGraph): String = Layouter.renderGraph(buildAsciiGraph(graph)) @@ -128,12 +147,13 @@ object IvyGraphMLDependencies extends App { 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) private def buildAsciiGraph(moduleGraph: ModuleGraph): layout.Graph[String] = { def renderVertex(module: Module): String = - module.id.name + "\n" + + module.id.name + module.extraInfo + "\n" + module.id.organisation + "\n" + module.id.version + module.error.map("\nerror: "+_).getOrElse("") + @@ -200,6 +220,6 @@ object ModuleGraphProtocol extends 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] = asProduct3(Module)(Module.unapply(_).get) + implicit val ModuleFormat: Format[Module] = asProduct4(Module)(Module.unapply(_).get) implicit val ModuleGraphFormat: Format[ModuleGraph] = asProduct2(ModuleGraph)(ModuleGraph.unapply(_).get) } diff --git a/src/main/scala/net/virtualvoid/sbt/graph/Plugin.scala b/src/main/scala/net/virtualvoid/sbt/graph/Plugin.scala index 3d1547661..5dd18b33f 100755 --- a/src/main/scala/net/virtualvoid/sbt/graph/Plugin.scala +++ b/src/main/scala/net/virtualvoid/sbt/graph/Plugin.scala @@ -44,6 +44,9 @@ object Plugin extends sbt.Plugin { "A task which returns the location of the ivy report file for a given configuration (default `compile`).") val ignoreMissingUpdate = TaskKey[UpdateReport]("update-ignore-missing", "A copy of the update task which ignores missing artifacts") + val filterScalaLibrary = SettingKey[Boolean]("filter-scala-library", + "Specifies if scala dependency should be filtered in dependency-* output" + ) // internal import ModuleGraphProtocol._ @@ -63,12 +66,19 @@ object Plugin extends sbt.Plugin { val home = config.provider.scalaProvider.launcher.ivyHome (c: String) => file("%s/cache/%s-%s-%s.xml" format (home, projectID.organization, crossName(ivyModule), c)) } - } + }, + filterScalaLibrary in Global := true ) ++ Seq(Compile, Test, Runtime, Provided, Optional).flatMap(ivyReportForConfig) def ivyReportForConfig(config: Configuration) = inConfig(config)(seq( ivyReport <<= ivyReportFunction map (_(config.toString)) dependsOn(ignoreMissingUpdate), moduleGraph <<= ivyReport map (absoluteReportPath.andThen(IvyGraphMLDependencies.graph)), + moduleGraph <<= (scalaVersion, moduleGraph, filterScalaLibrary) map { (scalaV, graph, filter) => + if (filter) + IvyGraphMLDependencies.ignoreScalaLibrary(scalaV, graph) + else + graph + }, moduleGraphStore <<= moduleGraph storeAs moduleGraphStore triggeredBy moduleGraph, asciiGraph <<= moduleGraph map IvyGraphMLDependencies.asciiGraph, dependencyGraph <<= InputTask(shouldForceParser) { force =>