From 11a6522f9eb113fc75c9648e7d1141d9364c7047 Mon Sep 17 00:00:00 2001 From: Jared Burrows Date: Sun, 27 Dec 2020 01:26:42 -0500 Subject: [PATCH] add csv report --- .../license/LicenseReportTask.kt | 50 +++++----- .../license/internal/report/CsvReport.kt | 93 +++++++++++++++++++ .../license/internal/report/JsonReport.kt | 2 +- .../license/internal/report/Report.kt | 4 +- .../internal/report/CsvReportSpec.groovy | 80 ++++++++++++++++ .../internal/report/JsonReportSpec.groovy | 15 ++- src/test/groovy/test/TestUtils.groovy | 2 +- 7 files changed, 212 insertions(+), 34 deletions(-) create mode 100644 src/main/kotlin/com/jaredsburrows/license/internal/report/CsvReport.kt create mode 100644 src/test/groovy/com/jaredsburrows/license/internal/report/CsvReportSpec.groovy diff --git a/src/main/kotlin/com/jaredsburrows/license/LicenseReportTask.kt b/src/main/kotlin/com/jaredsburrows/license/LicenseReportTask.kt index f1c62d94..56e19673 100644 --- a/src/main/kotlin/com/jaredsburrows/license/LicenseReportTask.kt +++ b/src/main/kotlin/com/jaredsburrows/license/LicenseReportTask.kt @@ -25,9 +25,7 @@ import java.net.URI import java.net.URL import java.util.UUID -/** - * A [Task] that creates HTML and JSON reports of the current projects dependencies. - */ +/** A [Task] that creates HTML and JSON reports of the current projects dependencies. */ open class LicenseReportTask : DefaultTask() { // tasks can't be final @Internal var projects = arrayListOf() @@ -402,6 +400,29 @@ open class LicenseReportTask : DefaultTask() { // tasks can't be final }.trim() } + private fun File?.isNullOrEmpty(): Boolean = this == null || this.length() == 0L + + private fun Node.getAt(name: String): NodeList { + val answer = NodeList() + val var3 = this.children().iterator() + + while (var3.hasNext()) { + val child = var3.next() + if (child is Node) { + val childNodeName = child.name() + if (childNodeName is QName) { + if (childNodeName.matches(name)) { + answer.add(child) + } + } else if (name == childNodeName) { + answer.add(child) + } + } + } + + return answer + } + companion object { private val xmlParser = XmlParser(false, false) private const val ANDROID_SUPPORT_GROUP_ID = "com.android.support" @@ -412,26 +433,3 @@ open class LicenseReportTask : DefaultTask() { // tasks can't be final const val JSON_EXT = ".json" } } - -private fun File?.isNullOrEmpty(): Boolean = this == null || this.length() == 0L - -private fun Node.getAt(name: String): NodeList { - val answer = NodeList() - val var3 = this.children().iterator() - - while (var3.hasNext()) { - val child = var3.next() - if (child is Node) { - val childNodeName = child.name() - if (childNodeName is QName) { - if (childNodeName.matches(name)) { - answer.add(child) - } - } else if (name == childNodeName) { - answer.add(child) - } - } - } - - return answer -} diff --git a/src/main/kotlin/com/jaredsburrows/license/internal/report/CsvReport.kt b/src/main/kotlin/com/jaredsburrows/license/internal/report/CsvReport.kt new file mode 100644 index 00000000..35db24ff --- /dev/null +++ b/src/main/kotlin/com/jaredsburrows/license/internal/report/CsvReport.kt @@ -0,0 +1,93 @@ +package com.jaredsburrows.license.internal.report + +import com.jaredsburrows.license.internal.pom.Project + +/** + * Generates CSV report of projects dependencies. + * + * @property projects list of [Project]s for thr CSV report. + */ +class CsvReport(private val projects: List) : Report { + + override fun toString(): String = report() + + override fun report(): String = if (projects.isEmpty()) emptyReport() else fullReport() + + override fun fullReport(): String { + val projectInfoList = arrayListOf() + projectInfoList.add(COLUMNS) + + projects.map { project -> + val projectInfo = arrayListOf().apply { + // Project Name + addCsvString(project.name) + + // Project Description + addCsvString(project.description) + + // Project Version + addCsvString(project.version) + + // Project Developers + addCsvList(project.developers) { it.name } + + // Project Url + addCsvString(project.url) + + // Project Year + addCsvString(project.year) + + // Project License Names + addCsvList(project.licenses) { it.name } + + // Project License Url + addCsvList(project.licenses) { it.url } + + // Project Dependency + addCsvString(project.gav) + } + + // Add each row to the list + projectInfoList.add(projectInfo.toCsv()) + } + + return projectInfoList.joinToString(separator = "\n") + } + + override fun emptyReport(): String = EMPTY_CSV + + private fun ArrayList.toCsv(): String = this.joinToString(separator = ",") + + private fun ArrayList.addCsvString(element: String): Boolean { + return this.add(element.toCsvString()) + } + + private fun ArrayList.addCsvList( + elements: List, + transform: ((T) -> CharSequence)? = null + ): Boolean { +// return when { +// elements.isEmpty() -> this.add(null) +// elements.size == 1 -> this.add(elements.joinToString(separator = ",", transform = transform)) +// else -> this.add("\"${elements.joinToString(separator = ",", transform = transform)}\"") +// } + + return when { + elements.isEmpty() -> this.add(null) + else -> { + val blah = elements.joinToString(separator = ",", transform = transform) + when (elements.size) { + 1 -> this.add(blah) + else -> this.add("\"${blah}\"") + } + } + } + } + + private fun String.toCsvString(): String? = if (this.isNotEmpty()) this else null + + companion object { + private const val COLUMNS = "project,description,version,developers,url,year,licenses,license urls,dependency" + private const val EMPTY_CSV = "" + } +} diff --git a/src/main/kotlin/com/jaredsburrows/license/internal/report/JsonReport.kt b/src/main/kotlin/com/jaredsburrows/license/internal/report/JsonReport.kt index a2082e63..59c2a0dd 100644 --- a/src/main/kotlin/com/jaredsburrows/license/internal/report/JsonReport.kt +++ b/src/main/kotlin/com/jaredsburrows/license/internal/report/JsonReport.kt @@ -56,8 +56,8 @@ class JsonReport(private val projects: List) : Report { private const val LICENSES = "licenses" private const val LICENSE = "license" private const val LICENSE_URL = "license_url" - private const val EMPTY_JSON = "[]" private const val DEPENDENCY = "dependency" + private const val EMPTY_JSON = "[]" private val gson = GsonBuilder() .setPrettyPrinting() .serializeNulls() diff --git a/src/main/kotlin/com/jaredsburrows/license/internal/report/Report.kt b/src/main/kotlin/com/jaredsburrows/license/internal/report/Report.kt index 04d9ec39..3523812f 100644 --- a/src/main/kotlin/com/jaredsburrows/license/internal/report/Report.kt +++ b/src/main/kotlin/com/jaredsburrows/license/internal/report/Report.kt @@ -1,8 +1,6 @@ package com.jaredsburrows.license.internal.report -/** - * Used to be the base configuration for each report. - */ +/** Used to be the base configuration for each report. */ interface Report { /** Return a pretty print of the report. */ override fun toString(): String diff --git a/src/test/groovy/com/jaredsburrows/license/internal/report/CsvReportSpec.groovy b/src/test/groovy/com/jaredsburrows/license/internal/report/CsvReportSpec.groovy new file mode 100644 index 00000000..03a9ae73 --- /dev/null +++ b/src/test/groovy/com/jaredsburrows/license/internal/report/CsvReportSpec.groovy @@ -0,0 +1,80 @@ +package com.jaredsburrows.license.internal.report + +import com.jaredsburrows.license.internal.pom.Developer +import com.jaredsburrows.license.internal.pom.License +import com.jaredsburrows.license.internal.pom.Project +import spock.lang.Specification + +final class CsvReportSpec extends Specification { + def 'no open source csv'() { + given: + def projects = [] + def sut = new CsvReport(projects) + + when: + def actual = sut.toString() + def expected = "" + + then: + actual == expected + } + + def 'open source csv - missing values'() { + given: + def developer = new Developer(name: 'name') + def project1 = new Project( + name: 'name', + developers: [], + gav: 'foo:bar:1.2.3' + ) + def project2 = new Project( + name: 'name', + developers: [developer, developer], + gav: 'foo:bar:1.2.3' + ) + def projects = [project1, project2] + def sut = new CsvReport(projects) + + when: + def actual = sut.toString() + def expected = + "project,description,version,developers,url,year,licenses,license urls,dependency\n" + + "name,null,null,null,null,null,null,null,foo:bar:1.2.3\n" + + "name,null,null,\"name,name\",null,null,null,null,foo:bar:1.2.3" + + then: + actual == expected + } + + def 'open source csv - all values'() { + given: + def developer = new Developer(name: 'name') + def developers = [developer, developer] + def license = new License( + name: 'name', + url: 'url' + ) + def project = new Project( + name: 'name', + description: 'description', + version: '1.0.0', + licenses: [license], + url: 'url', + developers: developers, + year: 'year', + gav: 'foo:bar:1.2.3' + ) + def projects = [project, project] + def sut = new CsvReport(projects) + + when: + def actual = sut.toString() + def expected = + "project,description,version,developers,url,year,licenses,license urls,dependency\n" + + "name,description,1.0.0,\"name,name\",url,year,name,url,foo:bar:1.2.3\n" + + "name,description,1.0.0,\"name,name\",url,year,name,url,foo:bar:1.2.3" + + then: + actual == expected + } +} diff --git a/src/test/groovy/com/jaredsburrows/license/internal/report/JsonReportSpec.groovy b/src/test/groovy/com/jaredsburrows/license/internal/report/JsonReportSpec.groovy index 96451c86..02a53f36 100644 --- a/src/test/groovy/com/jaredsburrows/license/internal/report/JsonReportSpec.groovy +++ b/src/test/groovy/com/jaredsburrows/license/internal/report/JsonReportSpec.groovy @@ -26,12 +26,18 @@ final class JsonReportSpec extends Specification { def 'open source json - missing values'() { given: - def project = new Project( + def developer = new Developer(name: 'name') + def project1 = new Project( name: 'name', developers: [], gav: 'foo:bar:1.2.3' ) - def projects = [project, project] + def project2 = new Project( + name: 'name', + developers: [developer, developer], + gav: 'foo:bar:1.2.3' + ) + def projects = [project1, project2] def sut = new JsonReport(projects) when: @@ -53,7 +59,10 @@ final class JsonReportSpec extends Specification { "project": "name", "description": null, "version": null, - "developers": [], + "developers": [ + "name", + "name" + ], "url": null, "year": null, "licenses": [], diff --git a/src/test/groovy/test/TestUtils.groovy b/src/test/groovy/test/TestUtils.groovy index e49e8d3c..11fc7bfd 100644 --- a/src/test/groovy/test/TestUtils.groovy +++ b/src/test/groovy/test/TestUtils.groovy @@ -26,7 +26,7 @@ final class TestUtils { } static def assertJson(def expected, def actual) { - return parser.parse(actual) == parser.parse(expected) + return parser.parseString(actual).toString() == parser.parseString(expected).toString() } static def htmlToXml(String text) {