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

Ignore fatal errors in POMs of transitive dependencies #106

Merged
merged 3 commits into from
Jun 6, 2016
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
1 change: 1 addition & 0 deletions README.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -258,6 +258,7 @@ The `downloadLicense` task has a set of properties, most can be set in the exten
[cols="h,d"]
|====
|includeProjectDependencies |true if you want to include the transitive dependencies of your project dependencies
|ignoreFatalParseErrors |true if you want to ignore fatal errors when parsing POMs of transitive dependencies
|licenses |a pre-defined mapping of a dependency to a license; useful if the external repositories do not have license information available
|aliases |a mapping between licenses; useful to consolidate the various POM definitions of different spelled/named licenses
|excludeDependencies |a List of dependencies that are to be excluded from reporting
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,11 @@ public class DownloadLicenses extends ConventionTask {
*/
@Input boolean includeProjectDependencies

/**
* Ignore fatal errors when parsing POMs of transitive dependencies.
*/
@Input boolean ignoreFatalParseErrors

/**
* List of dependencies that will be omitted in the report.
*/
Expand Down Expand Up @@ -88,6 +93,7 @@ public class DownloadLicenses extends ConventionTask {
def dependencyLicensesSet = {
def licenseResolver = new LicenseResolver(project: project,
includeProjectDependencies: getIncludeProjectDependencies(),
ignoreFatalParseErrors: getIgnoreFatalParseErrors(),
aliases: aliases.collectEntries {
new MapEntry(resolveAliasKey(it.key), it.value)
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,11 @@ class DownloadLicensesExtension {
*/
boolean includeProjectDependencies

/**
* Ignore fatal errors when parsing POMs of transitive dependencies.
*/
boolean ignoreFatalParseErrors

/**
* File name for reports by dependency.
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,7 @@ class LicensePlugin implements Plugin<Project> {
reportByDependency = true
reportByLicenseType = true
includeProjectDependencies = false
ignoreFatalParseErrors = false
reportByDependencyFileName = DEFAULT_FILE_NAME_FOR_REPORTS_BY_DEPENDENCY
reportByLicenseFileName = DEFAULT_FILE_NAME_FOR_REPORTS_BY_LICENSE
excludeDependencies = []
Expand Down Expand Up @@ -183,6 +184,7 @@ class LicensePlugin implements Plugin<Project> {
reportByDependencyFileName = { downloadLicensesExtension.reportByDependencyFileName }
reportByLicenseFileName = { downloadLicensesExtension.reportByLicenseFileName }
includeProjectDependencies = {downloadLicensesExtension.includeProjectDependencies}
ignoreFatalParseErrors = {downloadLicensesExtension.ignoreFatalParseErrors}
licenses = { downloadLicensesExtension.licenses }
aliases = {downloadLicensesExtension.aliases }
xml = { downloadLicensesExtension.report.xml.enabled }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import org.gradle.api.artifacts.FileCollectionDependency
import org.gradle.api.artifacts.ResolvedArtifact
import org.gradle.api.logging.Logger
import org.gradle.api.logging.Logging
import org.gradle.api.tasks.TaskExecutionException

import static DependencyMetadata.noLicenseMetaData

Expand All @@ -27,6 +28,7 @@ class LicenseResolver {
private List<String> dependenciesToIgnore
private boolean includeProjectDependencies
private String dependencyConfiguration
private boolean ignoreFatalParseErrors

/**
* Provide set with dependencies metadata.
Expand Down Expand Up @@ -127,8 +129,8 @@ class LicenseResolver {
def subprojects = project.rootProject.subprojects.groupBy { Project p -> "$p.group:$p.name:$p.version".toString()}

if (project.configurations.any { it.name == dependencyConfiguration }) {
def runtimeConfiguration = project.configurations.getByName(dependencyConfiguration)
runtimeConfiguration.resolvedConfiguration.resolvedArtifacts.each { ResolvedArtifact d ->
def configuration = project.configurations.getByName(dependencyConfiguration)
configuration.resolvedConfiguration.resolvedArtifacts.each { ResolvedArtifact d ->
String dependencyDesc = "$d.moduleVersion.id.group:$d.moduleVersion.id.name:$d.moduleVersion.id.version".toString()
if(!dependenciesToIgnore.contains(dependencyDesc)) {
Project subproject = subprojects[dependencyDesc]?.first()
Expand Down Expand Up @@ -205,7 +207,20 @@ class LicenseResolver {

XmlSlurper slurper = new XmlSlurper(true, false)
slurper.setErrorHandler(new org.xml.sax.helpers.DefaultHandler())
GPathResult xml = slurper.parse(pStream)

GPathResult xml
try {
xml = slurper.parse(pStream)
} catch (org.xml.sax.SAXParseException e) {
// Fatal errors are still throw by DefaultHandler, so handle them here.
logger.warn("Unable to parse POM file for $dependencyDesc")
if (ignoreFatalParseErrors) {
return noLicenseMetaData(dependencyDesc)
} else {
throw new TaskExecutionException(e.getMessage())
}
}

DependencyMetadata pomData = new DependencyMetadata(dependency: initialDependency)

xml.licenses.license.each {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,25 @@ class DownloadLicensesIntegTest extends Specification {

}

def "Test that ignoring fatal pom parse errors works"() {
setup:
project.dependencies {
// This depends on "org.codehouse.plexus:plexus:1.0.4" whose POM is malformed.
compile "org.apache.maven:maven-ant-tasks:2.1.3"
}
downloadLicenses.ignoreFatalParseErrors = true

when:
downloadLicenses.execute()

then:
File f = getLicenseReportFolder()
assertLicenseReportsExist(f)

def xmlByDependency = xml4LicenseByDependencyReport(f)
dependenciesInReport(xmlByDependency) == 24
}

def "Test that report generating in multi module build include subprojects dependencies"() {
setup:
subproject.dependencies {
Expand Down