diff --git a/.travis.yml b/.travis.yml index 49530a24..b0c24ef8 100644 --- a/.travis.yml +++ b/.travis.yml @@ -9,7 +9,7 @@ cache: - $HOME/.gradle/caches/ before_install: - test $TRAVIS_PULL_REQUEST = false && openssl aes-256-cbc -K $encrypted_5434d186515e_key -iv $encrypted_5434d186515e_iv - -in gradle.properties.enc -out gradle.properties -d + -in gradle.properties.enc -out gradle.properties -d || true after_success: - ./gradlew jacocoTestReport coveralls notifications: diff --git a/build.gradle b/build.gradle index dc96839d..08826aa1 100644 --- a/build.gradle +++ b/build.gradle @@ -17,12 +17,12 @@ plugins { id 'groovy' id 'jacoco' - id 'nebula.info' version '3.0.3' + id 'nebula.info' version '3.0.4' id 'nebula.contacts' version '3.0.1' id 'nebula.integtest' version '3.0.3' id 'nebula.maven-publish' version '4.4.4' - id 'nebula.nebula-release' version '3.1.1' - id 'nebula.nebula-bintray' version '3.2.0' + id 'nebula.nebula-release' version '4.0.1' + id 'nebula.nebula-bintray' version '3.3.4' id 'com.gradle.plugin-publish' version '0.9.2' id 'nebula.javadoc-jar' version '4.4.4' id 'nebula.source-jar' version '4.4.4' @@ -31,9 +31,7 @@ plugins { id 'nebula.provided-base' version '3.0.3' } -group 'com.netflix.nebula' - -apply from: 'https://raw.githubusercontent.com/nebula-plugins/nebula-core/b676bbc026d0053494b5439ba8ef147c16adabba/common.gradle' +apply from: 'https://raw.githubusercontent.com/nebula-plugins/nebula-core/59c9e15f561372a8a72bbe13e4fbb114d0ef16f8/common.gradle' description 'Pluggable and configurable linter tool for identifying and reporting on patterns of misuse or deprecations in Gradle scripts' @@ -50,13 +48,11 @@ repositories { } dependencies { - compile gradleApi() - compile localGroovy() - compile 'org.ow2.asm:asm:5.0.4' compile('org.codenarc:CodeNarc:latest.release') { transitive = false } + compile 'com.netflix.nebula:gradle-info-plugin:3.0.4' // these two dependencies exist so we can provide a test harness // to proprietary rule implementations packed in other jars diff --git a/src/main/groovy/com/netflix/nebula/lint/plugin/GradleLintTask.groovy b/src/main/groovy/com/netflix/nebula/lint/plugin/GradleLintTask.groovy index 512ff58c..fc0fea3f 100644 --- a/src/main/groovy/com/netflix/nebula/lint/plugin/GradleLintTask.groovy +++ b/src/main/groovy/com/netflix/nebula/lint/plugin/GradleLintTask.groovy @@ -2,6 +2,7 @@ package com.netflix.nebula.lint.plugin import com.netflix.nebula.lint.rule.GradleLintRule import com.netflix.nebula.lint.rule.GradleViolation +import nebula.plugin.info.InfoBrokerPlugin import org.codenarc.analyzer.StringSourceAnalyzer import org.codenarc.rule.Rule import org.gradle.api.DefaultTask @@ -27,6 +28,12 @@ class GradleLintTask extends DefaultTask { } } + void tryReportToBroker(List reportItems) { + project.getPlugins().withType(InfoBrokerPlugin) { + it.addReport('lintViolations', reportItems) + } + } + @TaskAction void lint() { def textOutput = textOutputFactory.create('lint') @@ -37,20 +44,20 @@ class GradleLintTask extends DefaultTask { def totalBySeverity = [warning: 0, error: 0] ([project] + project.subprojects).each { p -> - if(p.buildFile.exists()) { + if (p.buildFile.exists()) { def extension try { extension = p.extensions.getByType(GradleLintExtension) - } catch(UnknownDomainObjectException) { + } catch (UnknownDomainObjectException) { // if the subproject has not applied lint, use the extension configuration from the root project extension = p.rootProject.extensions.getByType(GradleLintExtension) } def ruleSet = RuleSetFactory.configureRuleSet(extension.rules.collect { registry.buildRules(it, p) } .flatten() as List) - if(taskLogger.isDebugEnabled()) { + if (taskLogger.isDebugEnabled()) { ruleSet.rules.each { - if(it instanceof GradleLintRule) + if (it instanceof GradleLintRule) taskLogger.debug('Executing {} against {}', it.ruleId, p.buildFile.path) } } @@ -80,18 +87,25 @@ class GradleLintTask extends DefaultTask { violationsByProject.entrySet().each { def buildFilePath = it.key.rootDir.toURI().relativize(it.key.buildFile.toURI()).toString() def violations = it.value + def violationReportItems = [] violations.each { v -> def severity = v.rule.priority <= 3 ? 'warning' : 'error' + def reportItem = new LintViolationReportItem(ruleId: v.rule.ruleId, + severity: severity, buildFilePath: buildFilePath) textOutput.withStyle(StyledTextOutput.Style.Failure).text(severity.padRight(10)) textOutput.text(v.rule.ruleId.padRight(35)) textOutput.withStyle(StyledTextOutput.Style.Description).println(v.message) - if(v.lineNumber) + if (v.lineNumber) { textOutput.withStyle(StyledTextOutput.Style.UserInput).println(buildFilePath + ':' + v.lineNumber) - if(v.sourceLine) + reportItem.lineNumber = v.lineNumber + } + if (v.sourceLine) { textOutput.println("$v.sourceLine") + reportItem.sourceLine = v.sourceLine + } if (v instanceof GradleViolation && v.isFixable() && v.addition) { if (v.addition) { @@ -101,14 +115,17 @@ class GradleLintTask extends DefaultTask { } textOutput.println() // extra space between violations + violationReportItems << reportItem } def errors = totalBySeverity.error ?: 0 def warnings = totalBySeverity.warning ?: 0 - if(!violations.isEmpty()) { + if (!violations.isEmpty()) { textOutput.withStyle(StyledTextOutput.Style.Failure) .println("\u2716 ${buildFilePath}: ${violations.size()} problem${violations.size() == 1 ? '' : 's'} ($errors error${errors == 1 ? '' : 's'}, $warnings warning${warnings == 1 ? '' : 's'})\n".toString()) } + + tryReportToBroker(violationReportItems) } if (!allViolations.isEmpty()) { diff --git a/src/main/groovy/com/netflix/nebula/lint/plugin/LintViolationReportItem.groovy b/src/main/groovy/com/netflix/nebula/lint/plugin/LintViolationReportItem.groovy new file mode 100644 index 00000000..7d6ee22b --- /dev/null +++ b/src/main/groovy/com/netflix/nebula/lint/plugin/LintViolationReportItem.groovy @@ -0,0 +1,12 @@ +package com.netflix.nebula.lint.plugin + +import groovy.transform.Canonical + +@Canonical +class LintViolationReportItem { + String buildFilePath = "unspecified" + String ruleId = "unspecified" + String severity = "unspecified" + Integer lineNumber = -1 + String sourceLine = "unspecified" +}