From 7c90d09d82f7464a70a630bc87a8f10e0b6696b7 Mon Sep 17 00:00:00 2001 From: Johannes Rudolph Date: Sat, 27 Oct 2012 12:28:40 +0200 Subject: [PATCH] refs #7: `dependency-license-info` show information about licenses --- README.md | 1 + notes/0.7.1.markdown | 3 +++ .../sbt/graph/IvyGraphMLDependencies.scala | 5 ++++- .../scala/net/virtualvoid/sbt/graph/Plugin.scala | 16 +++++++++++++++- 4 files changed, 23 insertions(+), 2 deletions(-) create mode 100644 notes/0.7.1.markdown diff --git a/README.md b/README.md index 89215283a..2ab25c75b 100644 --- a/README.md +++ b/README.md @@ -47,6 +47,7 @@ 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. + * `dependency-license-info`: show dependencies grouped by declared license * `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) diff --git a/notes/0.7.1.markdown b/notes/0.7.1.markdown new file mode 100644 index 000000000..c12b0e21a --- /dev/null +++ b/notes/0.7.1.markdown @@ -0,0 +1,3 @@ +New features in this version: + + * `dependency-license-info`: show dependencies grouped by declared license diff --git a/src/main/scala/net/virtualvoid/sbt/graph/IvyGraphMLDependencies.scala b/src/main/scala/net/virtualvoid/sbt/graph/IvyGraphMLDependencies.scala index efcb1d143..8408d03be 100644 --- a/src/main/scala/net/virtualvoid/sbt/graph/IvyGraphMLDependencies.scala +++ b/src/main/scala/net/virtualvoid/sbt/graph/IvyGraphMLDependencies.scala @@ -34,10 +34,12 @@ object IvyGraphMLDependencies extends App { def idString: String = organisation+":"+name+":"+version } case class Module(id: ModuleId, + license: Option[String] = None, extraInfo: String = "", evictedByVersion: Option[String] = None, error: Option[String] = None) { def hadError: Boolean = error.isDefined + def isUsed: Boolean = !evictedByVersion.isDefined } type Edge = (ModuleId, ModuleId) @@ -80,6 +82,7 @@ object IvyGraphMLDependencies extends App { 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, rev)) @@ -220,6 +223,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] = asProduct4(Module)(Module.unapply(_).get) + implicit val ModuleFormat: Format[Module] = asProduct5(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 0decf9a72..a1a325bd0 100755 --- a/src/main/scala/net/virtualvoid/sbt/graph/Plugin.scala +++ b/src/main/scala/net/virtualvoid/sbt/graph/Plugin.scala @@ -47,6 +47,9 @@ object Plugin extends sbt.Plugin { "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 import ModuleGraphProtocol._ val moduleGraphStore = TaskKey[IvyGraphMLDependencies.ModuleGraph]("module-graph-store", "The stored module-graph from the last run") @@ -105,7 +108,8 @@ object Plugin extends sbt.Plugin { (module, streams, moduleGraph) map { (module, streams, graph) => streams.log.info(IvyGraphMLDependencies.asciiTree(IvyGraphMLDependencies.reverseGraphStartingAt(graph, module))) } - } + }, + licenseInfo <<= (moduleGraph, streams) map showLicenseInfo )) def printAsciiGraphTask = @@ -123,6 +127,16 @@ object Plugin extends sbt.Plugin { def print(key: TaskKey[String]) = (streams, key) map (_.log.info(_)) + def showLicenseInfo(graph: ModuleGraph, streams: TaskStreams) { + val output = + 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") + streams.log.info(output) + } + import Project._ val shouldForceParser: State => Parser[Boolean] = { (state: State) => import complete.DefaultParsers._