From 27cb8301ca8f04f343fdbcb191380c5b84d0069c Mon Sep 17 00:00:00 2001 From: Ladislav Skokan Date: Tue, 24 May 2016 09:48:43 +0200 Subject: [PATCH] new task dependencyHomepageInfo and filtering by regexp --- README.md | 2 ++ .../sbt/graph/DependencyGraphKeys.scala | 5 ++++ .../sbt/graph/DependencyGraphSettings.scala | 27 ++++++++++++++----- .../sbt/graph/backend/SbtUpdateReport.scala | 1 + .../net/virtualvoid/sbt/graph/model.scala | 3 ++- 5 files changed, 30 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index c44ec50..760e98a 100644 --- a/README.md +++ b/README.md @@ -29,6 +29,7 @@ This plugin is an auto-plugin which will be automatically enabled starting from * `whatDependsOn `: Find out what depends on an artifact. Shows a reverse dependency tree for the selected module. * `dependencyLicenseInfo`: show dependencies grouped by declared license + * `dependencyHomepageInfo`: show dependencies' homepage info * `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. @@ -46,6 +47,7 @@ assumed as usual. * `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) + * `dependencyFilter`: defines regexp expression to list dependencies for task `dependencyHomepageInfo` * `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). diff --git a/src/main/scala/net/virtualvoid/sbt/graph/DependencyGraphKeys.scala b/src/main/scala/net/virtualvoid/sbt/graph/DependencyGraphKeys.scala index ace01d1..7dc1de0 100644 --- a/src/main/scala/net/virtualvoid/sbt/graph/DependencyGraphKeys.scala +++ b/src/main/scala/net/virtualvoid/sbt/graph/DependencyGraphKeys.scala @@ -64,10 +64,15 @@ trait DependencyGraphKeys { val ignoreMissingUpdate = Keys.update in ivyReport val filterScalaLibrary = SettingKey[Boolean]("filter-scala-library", "Specifies if scala dependency should be filtered in dependency-* output") + val dependencyFilter = SettingKey[String]("filter-dependencies", + "Specifies regex expression to filter dependencies listed") val licenseInfo = TaskKey[Unit]("dependency-license-info", "Aggregates and shows information about the licenses of dependencies") + val homepageInfo = TaskKey[Unit]("dependency-homepage-info", + "Homepage information about dependencies") + // internal private[graph] val moduleGraphStore = TaskKey[ModuleGraph]("module-graph-store", "The stored module-graph from the last run") private[graph] val whatDependsOn = InputKey[Unit]("what-depends-on", "Shows information about what depends on the given module") diff --git a/src/main/scala/net/virtualvoid/sbt/graph/DependencyGraphSettings.scala b/src/main/scala/net/virtualvoid/sbt/graph/DependencyGraphSettings.scala index 7535365..85364b3 100644 --- a/src/main/scala/net/virtualvoid/sbt/graph/DependencyGraphSettings.scala +++ b/src/main/scala/net/virtualvoid/sbt/graph/DependencyGraphSettings.scala @@ -18,17 +18,15 @@ package net.virtualvoid.sbt.graph import sbt._ import Keys._ - import CrossVersion._ - import sbt.complete.Parser - import org.apache.ivy.core.resolve.ResolveOptions - import net.virtualvoid.sbt.graph.backend.{ IvyReport, SbtUpdateReport } import net.virtualvoid.sbt.graph.rendering.DagreHTML import net.virtualvoid.sbt.graph.util.IOUtil +import scala.util.matching.Regex + object DependencyGraphSettings { import DependencyGraphKeys._ import ModuleGraphProtocol._ @@ -37,7 +35,8 @@ object DependencyGraphSettings { ivyReportFunction <<= ivyReportFunctionTask, updateConfiguration in ignoreMissingUpdate <<= updateConfiguration(config ⇒ new UpdateConfiguration(config.retrieve, true, config.logging)), ignoreMissingUpdateT, - filterScalaLibrary in Global := true) ++ Seq(Compile, Test, Runtime, Provided, Optional).flatMap(ivyReportForConfig) + filterScalaLibrary in Global := true, + dependencyFilter in Global := ".*") ++ Seq(Compile, Test, Runtime, Provided, Optional).flatMap(ivyReportForConfig) def ivyReportForConfig(config: Configuration) = inConfig(config)(Seq( ivyReport <<= ivyReportFunction map (_(config.toString)) dependsOn (ignoreMissingUpdate), @@ -101,7 +100,8 @@ object DependencyGraphSettings { streams.log.info(rendering.AsciiTree.asciiTree(GraphTransformations.reverseGraphStartingAt(graph, module))) } }, - licenseInfo <<= (moduleGraph, streams) map showLicenseInfo)) + licenseInfo <<= (moduleGraph, streams) map showLicenseInfo, + homepageInfo <<= (moduleGraph, streams, dependencyFilter) map showHomepageInfo)) def ivyReportFunctionTask = (sbtVersion, target, projectID, ivyModule, appConfiguration, streams) map { (sbtV, target, projectID, ivyModule, config, streams) ⇒ @@ -164,7 +164,7 @@ object DependencyGraphSettings { (streams, moduleGraph) map ((streams, graph) ⇒ streams.log.info(f(graph))) def showLicenseInfo(graph: ModuleGraph, streams: TaskStreams) { - val output = + val output: String = graph.nodes.filter(_.isUsed).groupBy(_.license).toSeq.sortBy(_._1).map { case (license, modules) ⇒ license.getOrElse("No license specified") + "\n" + @@ -173,6 +173,19 @@ object DependencyGraphSettings { streams.log.info(output) } + def showHomepageInfo(graph: ModuleGraph, streams: TaskStreams, filter: String) { + val output: Seq[String] = + graph.nodes.filter(_.isUsed).map { + case x: Any ⇒ x.id + " - " + x.homepage.getOrElse("None") + } + val f = filter.r + streams.log.info(message = output.distinct.filter(x ⇒ f.findFirstIn(x).isDefined).mkString("\n")) + } + + def logme(graph: ModuleGraph, streams: TaskStreams) = { + streams.log.info(graph.toString) + } + import Project._ val shouldForceParser: State ⇒ Parser[Boolean] = { (state: State) ⇒ import sbt.complete.DefaultParsers._ diff --git a/src/main/scala/net/virtualvoid/sbt/graph/backend/SbtUpdateReport.scala b/src/main/scala/net/virtualvoid/sbt/graph/backend/SbtUpdateReport.scala index f559626..7abd8bf 100644 --- a/src/main/scala/net/virtualvoid/sbt/graph/backend/SbtUpdateReport.scala +++ b/src/main/scala/net/virtualvoid/sbt/graph/backend/SbtUpdateReport.scala @@ -38,6 +38,7 @@ object SbtUpdateReport { (Module( id = report.module, license = report.licenses.headOption.map(_._1), + homepage = report.homepage, evictedByVersion = evictedByVersion, jarFile = jarFile, error = report.problem), diff --git a/src/main/scala/net/virtualvoid/sbt/graph/model.scala b/src/main/scala/net/virtualvoid/sbt/graph/model.scala index 06c2b5b..781f1fe 100644 --- a/src/main/scala/net/virtualvoid/sbt/graph/model.scala +++ b/src/main/scala/net/virtualvoid/sbt/graph/model.scala @@ -27,6 +27,7 @@ case class ModuleId(organisation: String, } case class Module(id: ModuleId, license: Option[String] = None, + homepage: Option[String] = None, extraInfo: String = "", evictedByVersion: Option[String] = None, jarFile: Option[File] = None, @@ -65,6 +66,6 @@ import sbinary.{ Format, DefaultProtocol } 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] = asProduct6(Module)(Module.unapply(_).get) + implicit val ModuleFormat: Format[Module] = asProduct7(Module)(Module.unapply(_).get) implicit val ModuleGraphFormat: Format[ModuleGraph] = asProduct2(ModuleGraph.apply _)(ModuleGraph.unapply(_).get) }