diff --git a/src/main/scala/sbtlicensereport/SbtLicenseReport.scala b/src/main/scala/sbtlicensereport/SbtLicenseReport.scala
index 6299b11..6c17f48 100644
--- a/src/main/scala/sbtlicensereport/SbtLicenseReport.scala
+++ b/src/main/scala/sbtlicensereport/SbtLicenseReport.scala
@@ -16,7 +16,9 @@ object SbtLicenseReport extends AutoPlugin {
type TargetLanguage = sbtlicensereport.license.TargetLanguage
type LicenseReportConfiguration = sbtlicensereport.license.LicenseReportConfiguration
type DepModuleInfo = sbtlicensereport.license.DepModuleInfo
+ type Column = sbtlicensereport.license.Column
val DepModuleInfo = sbtlicensereport.license.DepModuleInfo
+ val Column = sbtlicensereport.license.Column
def LicenseReportConfiguration = sbtlicensereport.license.LicenseReportConfiguration
def Html = sbtlicensereport.license.Html
def MarkDown = sbtlicensereport.license.MarkDown
@@ -34,6 +36,8 @@ object SbtLicenseReport extends AutoPlugin {
val dumpLicenseReportAnyProject = taskKey[File](
"Dumps a report file against all projects of the license report (using the target language) and combines it into a single file."
)
+ val licenseReportColumns =
+ settingKey[Seq[Column]]("Additional columns to be added to the final report")
val licenseReportDir = settingKey[File]("The location where we'll write the license reports.")
val licenseReportStyleRules = settingKey[Option[String]]("The style rules for license report styling.")
val licenseReportTitle = settingKey[String]("The name of the license report.")
@@ -75,12 +79,14 @@ object SbtLicenseReport extends AutoPlugin {
val ignore = update.value
val overrides = licenseOverrides.value.lift
val depExclusions = licenseDepExclusions.value.lift
+ val originatingModule = DepModuleInfo(organization.value, name.value, version.value)
license.LicenseReport.makeReport(
ivyModule.value,
licenseConfigurations.value,
licenseSelection.value,
overrides,
depExclusions,
+ originatingModule,
streams.value.log
)
},
@@ -101,7 +107,8 @@ object SbtLicenseReport extends AutoPlugin {
notesLookup,
licenseFilter.value,
dir,
- styleRules
+ styleRules,
+ licenseReportColumns.value
)
Seq(config)
},
@@ -137,6 +144,7 @@ object SbtLicenseReport extends AutoPlugin {
licenseDepExclusions := PartialFunction.empty,
licenseFilter := TypeFunctions.const(true),
licenseReportStyleRules := None,
- licenseReportTypes := Seq(MarkDown, Html, Csv)
+ licenseReportTypes := Seq(MarkDown, Html, Csv),
+ licenseReportColumns := Seq(Column.Category, Column.License, Column.Dependency)
)
}
diff --git a/src/main/scala/sbtlicensereport/license/Column.scala b/src/main/scala/sbtlicensereport/license/Column.scala
new file mode 100644
index 0000000..3f0fa47
--- /dev/null
+++ b/src/main/scala/sbtlicensereport/license/Column.scala
@@ -0,0 +1,48 @@
+package sbtlicensereport.license
+
+trait Column {
+ def columnName: String
+
+ def render(depLicense: DepLicense, language: TargetLanguage): String
+}
+
+object Column {
+ case object Category extends Column {
+ override val columnName: String = "Category"
+
+ override def render(depLicense: DepLicense, language: TargetLanguage): String =
+ depLicense.license.category.name
+ }
+
+ case object License extends Column {
+ override val columnName: String = "License"
+
+ override def render(depLicense: DepLicense, language: TargetLanguage): String =
+ language.createHyperLink(depLicense.license.url, depLicense.license.name)
+ }
+
+ case object Dependency extends Column {
+ override val columnName: String = "Dependency"
+
+ override def render(depLicense: DepLicense, language: TargetLanguage): String =
+ depLicense.homepage match {
+ case None => depLicense.module.toString
+ case Some(url) => language.createHyperLink(url.toExternalForm, depLicense.module.toString)
+ }
+ }
+
+ case object Configuration extends Column {
+ override val columnName: String = "Maven/Ivy Configurations"
+
+ override def render(depLicense: DepLicense, language: TargetLanguage): String = {
+ depLicense.configs.mkString(",")
+ }
+ }
+
+ case object OriginatingArtifactName extends Column {
+ override val columnName: String = "Originating Artifact"
+
+ override def render(depLicense: DepLicense, language: TargetLanguage): String =
+ depLicense.originatingModule.name
+ }
+}
diff --git a/src/main/scala/sbtlicensereport/license/LicenseReport.scala b/src/main/scala/sbtlicensereport/license/LicenseReport.scala
index 44c7101..352bc56 100644
--- a/src/main/scala/sbtlicensereport/license/LicenseReport.scala
+++ b/src/main/scala/sbtlicensereport/license/LicenseReport.scala
@@ -10,7 +10,13 @@ import sbtlicensereport.SbtCompat._
case class DepModuleInfo(organization: String, name: String, version: String) {
override def toString = s"${organization} # ${name} # ${version}"
}
-case class DepLicense(module: DepModuleInfo, license: LicenseInfo, homepage: Option[URL], configs: Set[String]) {
+case class DepLicense(
+ module: DepModuleInfo,
+ license: LicenseInfo,
+ homepage: Option[URL],
+ configs: Set[String],
+ originatingModule: DepModuleInfo
+) {
override def toString =
s"$module ${homepage.map(url => s" from $url")} on $license in ${configs.mkString("(", ",", ")")}"
}
@@ -54,18 +60,17 @@ object LicenseReport {
withPrintableFile(reportFile) { print =>
print(language.documentStart(title, reportStyleRules))
print(makeHeader(language))
- print(language.tableHeader("Category", "License", "Dependency", "Notes"))
+ print(language.tableHeader("Notes", config.licenseReportColumns.map(_.columnName): _*))
val rendered = (ordered map { dep =>
- val licenseLink = language.createHyperLink(dep.license.url, dep.license.name)
- val moduleLink = dep.homepage match {
- case None => dep.module.toString
- case Some(url) => language.createHyperLink(url.toExternalForm, dep.module.toString)
- }
- (dep.license.category.name, licenseLink, moduleLink, notes(dep.module) getOrElse "")
+ val notesRendered = notes(dep.module) getOrElse ""
+ (
+ notesRendered,
+ config.licenseReportColumns map (_.render(dep, language))
+ )
}).distinct
- for ((name, licenseLink, moduleLink, notes) <- rendered) {
- print(language.tableRow(name, licenseLink, moduleLink, notes))
+ for ((notes, rest) <- rendered) {
+ print(language.tableRow(notes, rest: _*))
}
print(language.tableEnd)
print(language.documentEnd)
@@ -84,11 +89,12 @@ object LicenseReport {
licenseSelection: Seq[LicenseCategory],
overrides: DepModuleInfo => Option[LicenseInfo],
exclusions: DepModuleInfo => Option[Boolean],
+ originatingModule: DepModuleInfo,
log: Logger
): LicenseReport = {
val (report, err) = resolve(module, log)
err foreach (x => throw x) // Bail on error
- makeReportImpl(report, configs, licenseSelection, overrides, exclusions, log)
+ makeReportImpl(report, configs, licenseSelection, overrides, exclusions, originatingModule, log)
}
/**
@@ -118,7 +124,8 @@ object LicenseReport {
private def pickLicenseForDep(
dep: IvyNode,
configs: Set[String],
- categories: Seq[LicenseCategory]
+ categories: Seq[LicenseCategory],
+ originatingModule: DepModuleInfo
): Option[DepLicense] =
for {
d <- Option(dep)
@@ -138,17 +145,24 @@ object LicenseReport {
.apply(Some(url(loc)))
)
// TODO - grab configurations.
- } yield DepLicense(getModuleInfo(dep), pickLicense(categories)(licenses), homepage, filteredConfigs)
+ } yield DepLicense(
+ getModuleInfo(dep),
+ pickLicense(categories)(licenses),
+ homepage,
+ filteredConfigs,
+ originatingModule
+ )
private def getLicenses(
report: ResolveReport,
configs: Set[String] = Set.empty,
- categories: Seq[LicenseCategory] = LicenseCategory.all
+ categories: Seq[LicenseCategory] = LicenseCategory.all,
+ originatingModule: DepModuleInfo
): Seq[DepLicense] = {
import collection.JavaConverters._
for {
dep <- report.getDependencies.asInstanceOf[java.util.List[IvyNode]].asScala
- report <- pickLicenseForDep(dep, configs, categories)
+ report <- pickLicenseForDep(dep, configs, categories, originatingModule)
} yield report
}
@@ -158,9 +172,10 @@ object LicenseReport {
categories: Seq[LicenseCategory],
overrides: DepModuleInfo => Option[LicenseInfo],
exclusions: DepModuleInfo => Option[Boolean],
+ originatingModule: DepModuleInfo,
log: Logger
): LicenseReport = {
- val licenses = getLicenses(report, configs, categories) filterNot { dep =>
+ val licenses = getLicenses(report, configs, categories, originatingModule) filterNot { dep =>
exclusions(dep.module).getOrElse(false)
} map { l =>
overrides(l.module) match {
diff --git a/src/main/scala/sbtlicensereport/license/LicenseReportConfiguration.scala b/src/main/scala/sbtlicensereport/license/LicenseReportConfiguration.scala
index ed0603a..f82b48c 100644
--- a/src/main/scala/sbtlicensereport/license/LicenseReportConfiguration.scala
+++ b/src/main/scala/sbtlicensereport/license/LicenseReportConfiguration.scala
@@ -10,5 +10,6 @@ case class LicenseReportConfiguration(
notes: DepModuleInfo => Option[String],
licenseFilter: LicenseCategory => Boolean,
reportDir: File,
- reportStyleRules: Option[String] = None
+ reportStyleRules: Option[String] = None,
+ licenseReportColumns: Seq[Column]
)
diff --git a/src/main/scala/sbtlicensereport/license/TargetLanguage.scala b/src/main/scala/sbtlicensereport/license/TargetLanguage.scala
index 0e9fb39..72fa844 100644
--- a/src/main/scala/sbtlicensereport/license/TargetLanguage.scala
+++ b/src/main/scala/sbtlicensereport/license/TargetLanguage.scala
@@ -18,10 +18,10 @@ sealed trait TargetLanguage {
def header1(msg: String): String
/** The syntax for the header of a table. */
- def tableHeader(firstColumn: String, secondColumn: String, thirdColumn: String, fourthColumn: String): String
+ def tableHeader(notes: String, columns: String*): String
/** The syntax for a row of a table. */
- def tableRow(firstColumn: String, secondColumn: String, thirdColumn: String, fourthColumn: String): String
+ def tableRow(notes: String, columns: String*): String
/** And a "table" */
def tableEnd: String
@@ -38,13 +38,17 @@ case object MarkDown extends TargetLanguage {
s"[$content]($link)"
def blankLine(): String = "\n"
def header1(msg: String): String = s"# $msg\n"
- def tableHeader(firstColumn: String, secondColumn: String, thirdColumn: String, fourthColumn: String): String =
- s"""
-$firstColumn | $secondColumn | $thirdColumn | $fourthColumn
---- | --- | --- | ---
-"""
- def tableRow(firstColumn: String, secondColumn: String, thirdColumn: String, fourthColumn: String): String =
- s"$firstColumn | $secondColumn | $thirdColumn |
" def header1(msg: String): String = s"
$firstColumn | $secondColumn | $thirdColumn | $fourthColumn |
---|---|---|---|
${firstColumn} | ${secondColumn} | ${thirdColumn} | ${htmlEncode( - fourthColumn - )} |
""", """ | """, """ | """) + val notesEscaped = s"${htmlEncode( + notes + )} |