diff --git a/CHANGELOG.md b/CHANGELOG.md index 364ce5e..674d7c1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,6 @@ +* Support animalsniffer messages for field violations (#25) +* Always put line number in file report, even if it wasn't declared (consistency with console reporting) + ### 1.6.0 (2022-08-20) * Update animalsniffer 1.20 -> 1.22 (java 9 support) * Fix configuration cache support for check tasks (#26) diff --git a/src/main/groovy/ru/vyarus/gradle/plugin/animalsniffer/report/ReportMessage.groovy b/src/main/groovy/ru/vyarus/gradle/plugin/animalsniffer/report/ReportMessage.groovy index 835ae97..10618aa 100644 --- a/src/main/groovy/ru/vyarus/gradle/plugin/animalsniffer/report/ReportMessage.groovy +++ b/src/main/groovy/ru/vyarus/gradle/plugin/animalsniffer/report/ReportMessage.groovy @@ -13,6 +13,7 @@ class ReportMessage { String signature String source String line + String field String code boolean parseFail } diff --git a/src/main/groovy/ru/vyarus/gradle/plugin/animalsniffer/util/FormatUtils.groovy b/src/main/groovy/ru/vyarus/gradle/plugin/animalsniffer/util/FormatUtils.groovy index 14955c4..bcb2559 100644 --- a/src/main/groovy/ru/vyarus/gradle/plugin/animalsniffer/util/FormatUtils.groovy +++ b/src/main/groovy/ru/vyarus/gradle/plugin/animalsniffer/util/FormatUtils.groovy @@ -15,10 +15,14 @@ class FormatUtils { private static final String LINE_SEP = ':' private static final String NL = String.format('%n') private static final String UND_REF = 'Undefined reference:' + private static final String FIELD_REF = ' Field ' /** * Parse animasniffer ant task error. * Error format: file_path:lineNum: Undefined reference: type source line + *

+ * In case of fields, it is impossible (for animalsniffer) to detect source line, instead, it would add field name + * in the message: file_path Field 'name': Undefined reference: type source line * * @param message animalsniffer error * @param roots source directories (roots) @@ -30,7 +34,20 @@ class FormatUtils { // try to look for first space (this will lead to wrong result if file path contain space) msgStartIdx = message.indexOf(' ') } - String vclass = message[0..(msgStartIdx - 1)].trim() + String position = message[0..(msgStartIdx - 1)].trim() + int fieldIdx = position.indexOf(FIELD_REF) + String vclass + String field = null + if (fieldIdx > 0) { + // -2 to cut off trailing ':' + vclass = position[0..(fieldIdx - 1)].trim() + field = position[fieldIdx..-2].trim() + // use "field" instead of "Field" + field = field.uncapitalize() + } else { + vclass = position + } + if (vclass.endsWith(LINE_SEP)) { // case when line number is not specified vclass = vclass[0..(vclass.length() - 2)] @@ -42,7 +59,7 @@ class FormatUtils { } String code = message[msgStartIdx..-1] code = code.replace(UND_REF, '').trim() - return new ReportMessage(source: vclass, line: line, code: code) + return new ReportMessage(source: vclass, line: line, field: field, code: code) } /** @@ -60,9 +77,10 @@ class FormatUtils { idx = 0 } String sig = showSignature ? " (${msg.signature})" : '' - String srcLine = msg.line ? - "${msg.source[0..(idx - 1)]}:${msg.line}" : - "${msg.source[0..(idx - 1)]}" + String srcLine = "${msg.source[0..(idx - 1)]}:${msg.line ? msg.line : 1}" + if (msg.field) { + srcLine += ' (' + msg.field + ')' + } return "$srcLine Undefined reference$sig: ${msg.code}" } @@ -85,6 +103,9 @@ class FormatUtils { String srcLine = clsIdx > 0 ? "${msg.source[0..clsIdx]}(${msg.source[(clsIdx + 1)..-1]}:${msg.line ?: 1})" : "${msg.source}${msg.line ? LINE_SEP + msg.line : ''}" + if (msg.field) { + srcLine += " $msg.field" + } return "[Undefined reference$sig] $srcLine$NL" + " >> ${msg.code}$NL" } diff --git a/src/test/groovy/ru/vyarus/gradle/plugin/animalsniffer/ErrorFormatTest.groovy b/src/test/groovy/ru/vyarus/gradle/plugin/animalsniffer/ErrorFormatTest.groovy index ddadac7..675e5d1 100644 --- a/src/test/groovy/ru/vyarus/gradle/plugin/animalsniffer/ErrorFormatTest.groovy +++ b/src/test/groovy/ru/vyarus/gradle/plugin/animalsniffer/ErrorFormatTest.groovy @@ -78,6 +78,25 @@ class ErrorFormatTest extends Specification { !msg.parseFail msg.code == 'java.util.function.Consumer' FormatUtils.formatForConsole(msg, false).replaceAll('\r', '') == '[Undefined reference] retrolambda.(Sample.java:1)\n >> java.util.function.Consumer\n' - FormatUtils.formatForFile(msg, false) == 'retrolambda.Sample Undefined reference: java.util.function.Consumer' + FormatUtils.formatForFile(msg, false) == 'retrolambda.Sample:1 Undefined reference: java.util.function.Consumer' + } + + def "Check field reference support"() { + + Set roots = [new File("/opt/foo") ] + + when: "line with field" + ReportMessage msg = FormatUtils.parse( + '/opt/foo/invalid/Sample.java Field \'field\': Undefined reference: java.nio.file.Path' + , roots) + then: "parsed" + msg.source == 'invalid.Sample.java' + msg.line == null + msg.field == 'field \'field\'' + msg.code == 'java.nio.file.Path' + + then: "formatting" + FormatUtils.formatForFile(msg, false) == "invalid.Sample:1 (field 'field') Undefined reference: java.nio.file.Path" + FormatUtils.formatForConsole(msg, false) == "[Undefined reference] invalid.(Sample.java:1) field 'field'\n >> java.nio.file.Path\n" } } \ No newline at end of file diff --git a/src/test/groovy/ru/vyarus/gradle/plugin/animalsniffer/FailKitTest.groovy b/src/test/groovy/ru/vyarus/gradle/plugin/animalsniffer/FailKitTest.groovy index 8a1fd09..b0420e9 100644 --- a/src/test/groovy/ru/vyarus/gradle/plugin/animalsniffer/FailKitTest.groovy +++ b/src/test/groovy/ru/vyarus/gradle/plugin/animalsniffer/FailKitTest.groovy @@ -56,6 +56,53 @@ class FailKitTest extends AbstractKitTest { ] } + def "Check field type violation"() { + setup: + build """ + plugins { + id 'java' + id 'ru.vyarus.animalsniffer' + } + + animalsniffer { + ignoreFailures = true + } + + repositories { mavenCentral()} + dependencies { + signature 'org.codehaus.mojo.signature:java16-sun:1.0@signature' + implementation 'org.slf4j:slf4j-api:1.7.25' + } + + """ + fileFromClasspath('src/main/java/invalid/Sample.java', '/ru/vyarus/gradle/plugin/animalsniffer/java/field/Sample.java') +// debug() + + when: "run task" + BuildResult result = run('check') + + then: "task successful" + result.task(':check').outcome == TaskOutcome.SUCCESS + + then: "found 2 violations" + result.output.contains("2 AnimalSniffer violations were found in 1 files") + result.output.replaceAll('\r', '').contains( + """[Undefined reference] invalid.(Sample.java:1) + >> java.nio.file.Path + +[Undefined reference] invalid.(Sample.java:13) + >> int Boolean.compare(boolean, boolean) +""") + + then: "report correct" + File file = file('/build/reports/animalsniffer/main.text') + file.exists() + file.readLines() == [ + "invalid.Sample:1 Undefined reference: java.nio.file.Path", + "invalid.Sample:13 Undefined reference: int Boolean.compare(boolean, boolean)" + ] + } + def "Check multiple signatures"() { setup: diff --git a/src/test/groovy/ru/vyarus/gradle/plugin/animalsniffer/MsgFormatTest.groovy b/src/test/groovy/ru/vyarus/gradle/plugin/animalsniffer/MsgFormatTest.groovy index a534ba6..55513b0 100644 --- a/src/test/groovy/ru/vyarus/gradle/plugin/animalsniffer/MsgFormatTest.groovy +++ b/src/test/groovy/ru/vyarus/gradle/plugin/animalsniffer/MsgFormatTest.groovy @@ -27,12 +27,12 @@ class MsgFormatTest extends Specification { when: "no line" res = FormatUtils.formatForFile(new ReportMessage(source: "some.Sample.java", code: 'bla'), false) then: "correct" - res == 'some.Sample Undefined reference: bla' + res == 'some.Sample:1 Undefined reference: bla' when: "incorrect source" res = FormatUtils.formatForFile(new ReportMessage(source: "failed source", code: 'bla'), false) then: "correct" - res == 'failed source Undefined reference: bla' + res == 'failed source:1 Undefined reference: bla' when: "failed parse" res = FormatUtils.formatForFile(new ReportMessage(parseFail: true, code: 'bla bla'), false) diff --git a/src/test/resources/ru/vyarus/gradle/plugin/animalsniffer/java/field/Sample.java b/src/test/resources/ru/vyarus/gradle/plugin/animalsniffer/java/field/Sample.java new file mode 100644 index 0000000..48e9ece --- /dev/null +++ b/src/test/resources/ru/vyarus/gradle/plugin/animalsniffer/java/field/Sample.java @@ -0,0 +1,15 @@ +package invalid; + +import org.slf4j.LoggerFactory; + +import java.nio.file.Path; + +public class Sample { + + private Path field; + + public static void main(String[] args) { + // method added in 1.7 + Boolean.compare(true, true); + } +} \ No newline at end of file