Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

#28 Support multiple licenses; add more attributes to json #29

Merged
merged 3 commits into from
Jan 9, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 23 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -96,19 +96,35 @@ dependencies {
[
{
"project": "Android GIF Drawable Library",
"developers": "Karol Wrótniak",
"url": "https://github.com/koral--/android-gif-drawable.git",
"description": "Views and Drawable for displaying animated GIFs for Android",
"version": "1.2.10",
"developers": [
"Karol Wrótniak"
],
"url": "https://github.com/koral--/android-gif-drawable",
"year": null,
"license": "The MIT License",
"license_url": "http://opensource.org/licenses/MIT"
"licenses": [
{
"license": "The MIT License",
"license_url": "http://opensource.org/licenses/MIT"
}
]
},
{
"project": "Design",
"developers": null,
"description": null,
"version": "27.0.2",
"developers": [

],
"url": null,
"year": null,
"license": "The Apache Software License",
"license_url": "http://www.apache.org/licenses/LICENSE-2.0.txt"
"licenses": [
{
"license": "The Apache Software License",
"license_url": "http://www.apache.org/licenses/LICENSE-2.0.txt"
}
]
}
]
```
Expand Down
149 changes: 77 additions & 72 deletions src/main/groovy/com/jaredsburrows/license/LicenseReportTask.groovy
Original file line number Diff line number Diff line change
Expand Up @@ -110,88 +110,44 @@ class LicenseReportTask extends DefaultTask {
final pomFile = pom.file
final pomText = new XmlParser().parse(pomFile)

// POM file information
def hasParent = pomText.parent != null

// License information
def name = pomText.name?.text() ? pomText.name?.text() : pomText.artifactId?.text()
def developers = pomText.developers?.developer?.collect { developer ->
new Developer(name: developer?.name?.text()?.trim())
def name = getName(pomText)
def version = pomText.version?.text()
def description = pomText.description?.text()
def developers = []
if (pomText.developers) {
developers = pomText.developers.developer?.collect { developer ->
new Developer(name: developer?.name?.text()?.trim())
}
}
def url = pomText.scm?.url?.text()

def url = pomText.url?.text()
def year = pomText.inceptionYear?.text()
def licenseName = null
def licenseURL = null
if (pomText?.licenses?.license) {
licenseName = pomText.licenses?.license[0]?.name?.text()
licenseURL = pomText.licenses?.license[0]?.url?.text()
}

// Clean up
name = name?.trim()

// Clean up and format
name = name?.capitalize()
version = version?.trim()
description = description?.trim()
url = url?.trim()
year = year?.trim()
licenseName = licenseName?.trim()
licenseURL = licenseURL?.trim()

// If the POM is missing a name, do not record it
if (!name) {
logger.log(LogLevel.WARN, String.format("POM file is missing a name: %s", pomFile))
def licenses = findLicenses(pomFile)
if (!licenses) {
logger.log(LogLevel.WARN, String.format("%s dependency does not have a license.", name))
return
}

// For all "com.android.support" libraries, use Apache 2
if (!licenseName || !licenseURL) {
logger.log(LogLevel.INFO, String.format("Project, %s, has no license in POM file.", name))

if (ANDROID_SUPPORT_GROUP_ID == pomText.groupId?.text()) {
licenseName = APACHE_LICENSE_NAME
licenseURL = APACHE_LICENSE_URL
} else {
if (hasParent && pomText) {
def parentPomText = getParentPom(pomText)

// License information
if (parentPomText?.licenses?.license) {
licenseName = parentPomText?.licenses?.license[0]?.name?.text()
licenseURL = parentPomText?.licenses?.license[0]?.url?.text()
}

// Clean up
licenseName = licenseName?.trim()
licenseURL = licenseURL?.trim()

if (!licenseName || !licenseURL) {
logger.log(LogLevel.WARN, String.format("%s dependency does not have a license.", name))
return
}
} else {
logger.log(LogLevel.WARN, String.format("%s dependency does not have a license.", name))
return
}
}
}

// If the POM is missing a license, do not record it
try {
new URL(licenseURL)
} catch (Exception ignore) {
logger.log(LogLevel.WARN, String.format("%s dependency does not have a valid license URL.", name))
return
}

// Update formatting
name = name?.capitalize()
licenseName = licenseName?.capitalize()

// Store the information that we need
final license = new License(name: licenseName,
url: licenseURL)
final project = new Project(name: name,
final project = new Project(
name: name,
description: description,
version: version,
developers: developers,
license: license,
licenses: licenses,
url: url,
year: year)
year: year
)

projects << project
}
Expand All @@ -200,10 +156,59 @@ class LicenseReportTask extends DefaultTask {
projects.sort { project -> project.name }
}

def getName(def pomText) {
def name = pomText.name?.text() ? pomText.name?.text() : pomText.artifactId?.text()
return name?.trim()
}

def findLicenses(File pomFile) {
if (!pomFile) {
return null
}
final pomText = new XmlParser().parse(pomFile)

// If the POM is missing a name, do not record it
final name = getName(pomText)
if (!name) {
logger.log(LogLevel.WARN, String.format("POM file is missing a name: %s", pomFile))
return null
}

if (ANDROID_SUPPORT_GROUP_ID == pomText.groupId?.text()) {
return [ new License(name: APACHE_LICENSE_NAME, url: APACHE_LICENSE_URL) ]
}

// License information found
if (pomText.licenses) {
def licenses = []
pomText.licenses[0].license.each { license ->
def licenseName = license.name?.text()
def licenseUrl = license.url?.text()
try {
new URL(licenseUrl)
licenseName = licenseName?.trim().capitalize()
licenseUrl = licenseUrl?.trim()
licenses << new License(name: licenseName, url: licenseUrl)
} catch (Exception ignore) {
logger.log(LogLevel.WARN, String.format("%s dependency has an invalid license URL; skipping license", name))
}
}
return licenses
}
logger.log(LogLevel.INFO, String.format("Project, %s, has no license in POM file.", name))

final hasParent = pomText.parent != null
if (hasParent) {
final parentPomFile = getParentPomFile(pomText)
return findLicenses(parentPomFile)
}
return null
}

/**
* Use Parent POM information when individual dependency license information is missing.
*/
def getParentPom(def pomText) {
def getParentPomFile(def pomText) {
// Get parent POM information
def groupId = pomText?.parent?.groupId?.text()
def artifactId = pomText?.parent?.artifactId?.text()
Expand All @@ -216,12 +221,12 @@ class LicenseReportTask extends DefaultTask {
project.dependencies.add(TEMP_POM_CONFIGURATION, dependency)
)

def pomFile = project.configurations."$TEMP_POM_CONFIGURATION".resolvedConfiguration.lenientConfiguration.artifacts?.file
def pomFile = project.configurations."$TEMP_POM_CONFIGURATION".resolvedConfiguration.lenientConfiguration.artifacts?.file[0]

// Reset dependencies in temporary configuration
project.configurations.remove(project.configurations."$TEMP_POM_CONFIGURATION")

return pomFile ? new XmlParser().parse(pomFile) : null
return pomFile
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,9 @@ package com.jaredsburrows.license.internal.pom
*/
final class Project {
String name
License license
String description
String version
List<License> licenses
String url
List<Developer> developers
String year
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ final class HtmlReport {
def openSourceHtml() {
final writer = new StringWriter()
final markup = new MarkupBuilder(writer)
final Set<License> licenses = new HashSet<>()
final Set<License> licenses = new LinkedHashSet<>()
markup.html {
head {
style(CSS_STYLE)
Expand All @@ -56,9 +56,9 @@ final class HtmlReport {
h3(NOTICE_LIBRARIES)
ul {
projects.each { project ->
licenses << project.license
licenses << project.licenses[0]
li {
a(href: String.format("%s%s", "#", project.license.hashCode()), project.name)
a(href: String.format("%s%s", "#", project.licenses[0].hashCode()), project.name)
}
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,19 +1,24 @@
package com.jaredsburrows.license.internal.report

import com.jaredsburrows.license.internal.pom.Project
import com.jaredsburrows.license.internal.pom.License
import groovy.json.JsonBuilder

/**
* @author <a href="mailto:[email protected]">Jared Burrows</a>
*/
final class JsonReport {
final static PROJECT = "project"
final static DESCRIPTION = "description"
final static VERSION = "version"
final static DEVELOPERS = "developers"
final static URL = "url"
final static YEAR = "year"
final static LICENSES = "licenses"
final static LICENSE = "license"
final static LICENSE_URL = "license_url"
final static EMPTY_JSON_ARRAY = "[]"
final List<License> licenses
final List<Project> projects

JsonReport(projects) {
Expand All @@ -26,13 +31,18 @@ final class JsonReport {
@SuppressWarnings("GroovyGStringKey")
def jsonArray() {
new JsonBuilder(projects.collect { project ->
def licensesJson = []
project.licenses.each { license ->
licensesJson << [ "$LICENSE": license.name, "$LICENSE_URL": license.url]
}
[
"$PROJECT" : project.name ? project.name : null,
"$DEVELOPERS" : project.developers ? project.developers.collect { developer -> developer?.name }?.join(", ") : null,
"$DESCRIPTION": project.description ? project.description : null,
"$VERSION" : project.version ? project.version : null,
"$DEVELOPERS" : project.developers*.name,
"$URL" : project.url ? project.url : null,
"$YEAR" : project.year ? project.year : null,
"$LICENSE" : project.license?.name ? project.license?.name : null,
"$LICENSE_URL": project.license?.url ? project.license?.url : null
"$LICENSES" : licensesJson
]
})
}
Expand Down
Loading