From 04bafd05884de660810808f01e591f3fc76cc67f Mon Sep 17 00:00:00 2001 From: Nicolas Bihan Date: Wed, 5 Dec 2018 14:49:30 -0600 Subject: [PATCH] Add line count metric --- Jenkinsfile | 4 +- pom.xml | 24 ++++++- .../plugin/coldfusion/ColdFusionSensor.java | 4 +- .../coldfusion/cflint/CFLintAnalyzer.java | 5 +- .../cflint/CFlintAnalysisResultImporter.java | 43 ++++++++++- .../cflint/xml/CountsAttributes.java | 41 +++++++++++ .../cflint/xml/LocationAttributes.java | 6 +- .../coldfusion/cflint/xml/TagAttribute.java | 13 ++++ .../com/wellsky/ColdfusionPluginTest.java | 26 +++++++ .../com/wellsky/ColdfusionSensorTest.java | 72 +++++++++++++++++++ src/test/java/com/wellsky/OSValidator.java | 35 +++++++++ src/test/resources/testmetrics1.cfm | 8 +++ src/test/resources/testmetrics2.cfm | 9 +++ 13 files changed, 277 insertions(+), 13 deletions(-) create mode 100644 src/main/java/com/stepstone/sonar/plugin/coldfusion/cflint/xml/CountsAttributes.java create mode 100644 src/test/java/com/wellsky/ColdfusionPluginTest.java create mode 100644 src/test/java/com/wellsky/ColdfusionSensorTest.java create mode 100644 src/test/java/com/wellsky/OSValidator.java create mode 100644 src/test/resources/testmetrics1.cfm create mode 100644 src/test/resources/testmetrics2.cfm diff --git a/Jenkinsfile b/Jenkinsfile index 91c36a1..c37d6ec 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -1,5 +1,7 @@ pipeline { - agent any + agent { + label 'master' + } stages { stage('Clean') { steps { diff --git a/pom.xml b/pom.xml index 6d6806c..23836fb 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ com.stepstone.sonar.plugin sonar-coldfusion-plugin sonar-plugin - 1.6.3-SNAPSHOT + 1.6.4-SNAPSHOT SonarQube Coldfusion Analyzer Enables scanning of ColdFusion source files @@ -40,10 +40,30 @@ 1.8 1.8 6.7.5 - 1.2.3 + 1.4.0 + + junit + junit + 4.12 + test + + + org.mockito + mockito-all + 1.10.19 + test + + + + org.assertj + assertj-core + 3.11.1 + test + + org.sonarsource.sslr-squid-bridge sslr-squid-bridge diff --git a/src/main/java/com/stepstone/sonar/plugin/coldfusion/ColdFusionSensor.java b/src/main/java/com/stepstone/sonar/plugin/coldfusion/ColdFusionSensor.java index 3d74e98..78e325c 100644 --- a/src/main/java/com/stepstone/sonar/plugin/coldfusion/ColdFusionSensor.java +++ b/src/main/java/com/stepstone/sonar/plugin/coldfusion/ColdFusionSensor.java @@ -21,6 +21,7 @@ import com.stepstone.sonar.plugin.coldfusion.cflint.CFlintAnalysisResultImporter; import com.stepstone.sonar.plugin.coldfusion.cflint.CFlintConfigExporter; import org.sonar.api.batch.fs.FileSystem; +import org.sonar.api.batch.sensor.Sensor; import org.sonar.api.batch.sensor.SensorContext; import org.sonar.api.batch.sensor.SensorDescriptor; import org.sonar.api.profiles.RulesProfile; @@ -31,7 +32,7 @@ import java.io.File; import java.io.IOException; -public class ColdFusionSensor implements org.sonar.api.batch.sensor.Sensor { +public class ColdFusionSensor implements Sensor { private final FileSystem fs; private final RulesProfile ruleProfile; @@ -79,5 +80,6 @@ protected void importResults(SensorContext sensorContext) { LOGGER.error(",e"); } } + } diff --git a/src/main/java/com/stepstone/sonar/plugin/coldfusion/cflint/CFLintAnalyzer.java b/src/main/java/com/stepstone/sonar/plugin/coldfusion/cflint/CFLintAnalyzer.java index 0e1e3f0..ba9e88c 100644 --- a/src/main/java/com/stepstone/sonar/plugin/coldfusion/cflint/CFLintAnalyzer.java +++ b/src/main/java/com/stepstone/sonar/plugin/coldfusion/cflint/CFLintAnalyzer.java @@ -88,7 +88,7 @@ private class LogInfoStreamConsumer implements StreamConsumer { @Override public void consumeLine(String line) { - LOGGER.info(line); + LOGGER.info("Consuming line {}", line); } } @@ -97,9 +97,8 @@ private class LogErrorStreamConsumer implements StreamConsumer { @Override public void consumeLine(String line) { - LOGGER.error(line); + LOGGER.error("Error consuming line {}",line); } - } } diff --git a/src/main/java/com/stepstone/sonar/plugin/coldfusion/cflint/CFlintAnalysisResultImporter.java b/src/main/java/com/stepstone/sonar/plugin/coldfusion/cflint/CFlintAnalysisResultImporter.java index d4a5702..46ac65d 100644 --- a/src/main/java/com/stepstone/sonar/plugin/coldfusion/cflint/CFlintAnalysisResultImporter.java +++ b/src/main/java/com/stepstone/sonar/plugin/coldfusion/cflint/CFlintAnalysisResultImporter.java @@ -17,13 +17,16 @@ package com.stepstone.sonar.plugin.coldfusion.cflint; import com.stepstone.sonar.plugin.coldfusion.ColdFusionPlugin; +import com.stepstone.sonar.plugin.coldfusion.cflint.xml.CountsAttributes; import com.stepstone.sonar.plugin.coldfusion.cflint.xml.IssueAttributes; import com.stepstone.sonar.plugin.coldfusion.cflint.xml.LocationAttributes; import org.sonar.api.batch.fs.FileSystem; import org.sonar.api.batch.fs.InputFile; +import org.sonar.api.batch.measure.Metric; import org.sonar.api.batch.sensor.SensorContext; import org.sonar.api.batch.sensor.issue.NewIssue; import org.sonar.api.batch.sensor.issue.NewIssueLocation; +import org.sonar.api.measures.CoreMetrics; import org.sonar.api.rule.RuleKey; import org.sonar.api.utils.log.Logger; import org.sonar.api.utils.log.Loggers; @@ -53,6 +56,7 @@ public void parse(File file) throws IOException, XMLStreamException { try (FileReader reader = new FileReader(file)) { parse(reader); } catch (XMLStreamException | IOException e) { + LOGGER.error("", e); throw e; } finally { closeXmlStream(); @@ -72,26 +76,59 @@ private void parse() throws XMLStreamException { if ("issue".equals(tagName)) { handleIssueTag(new IssueAttributes(stream)); + } else if ("counts".equals(tagName)) { + handleCountsTag(new CountsAttributes(stream)); } } } } + private void handleCountsTag(CountsAttributes countsAttributes){ + Metric metricLines = new Metric() { + @Override + public String key() { + return CoreMetrics.LINES.key(); + } + + @Override + public Class valueType() { + return Integer.class; + } + }; + + Metric metricFiles = new Metric() { + @Override + public String key() { + return CoreMetrics.FILES.key(); + } + + @Override + public Class valueType() { + return Integer.class; + } + }; + LOGGER.info("CFLint analyzed {} lines for {} files", countsAttributes.getTotalLines(), countsAttributes.getTotalFiles()); + sensorContext.newMeasure().on(sensorContext.module()).forMetric(metricLines).withValue(countsAttributes.getTotalLines()).save(); + sensorContext.newMeasure().on(sensorContext.module()).forMetric(metricFiles).withValue(countsAttributes.getTotalFiles()).save(); + } + private void handleIssueTag(IssueAttributes issueAttributes) throws XMLStreamException { while (stream.hasNext()) { int next = stream.next(); if (next == XMLStreamConstants.END_ELEMENT && "issue".equals(stream.getLocalName())) { break; - } else if (next == XMLStreamConstants.START_ELEMENT) { + } + else if (next == XMLStreamConstants.START_ELEMENT) { String tagName = stream.getLocalName(); if ("location".equals(tagName)) { LocationAttributes locationAttributes = new LocationAttributes(stream); - InputFile inputFile = fs.inputFile(fs.predicates().hasAbsolutePath(locationAttributes.getFile().get())); + //InputFile inputFiletest = fs.inputFiles(fs.predicates().hasFilename()) + InputFile inputFile = fs.inputFile(fs.predicates().hasAbsolutePath(locationAttributes.getFile())); if(inputFile == null){ - LOGGER.error("File {} is null", locationAttributes.getFile().get()); + LOGGER.error("File {} is null", locationAttributes.getFile()); } createNewIssue(issueAttributes, locationAttributes, inputFile); } diff --git a/src/main/java/com/stepstone/sonar/plugin/coldfusion/cflint/xml/CountsAttributes.java b/src/main/java/com/stepstone/sonar/plugin/coldfusion/cflint/xml/CountsAttributes.java new file mode 100644 index 0000000..3beeb68 --- /dev/null +++ b/src/main/java/com/stepstone/sonar/plugin/coldfusion/cflint/xml/CountsAttributes.java @@ -0,0 +1,41 @@ +/* +Copyright 2016 StepStone GmbH + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package com.stepstone.sonar.plugin.coldfusion.cflint.xml; + +import com.google.common.base.Optional; + +import javax.xml.stream.XMLStreamReader; + +public class CountsAttributes extends TagAttribute { + + private Integer totallines; + private Integer totalfiles; + + public CountsAttributes(XMLStreamReader stream) { + this.totallines = getAttributeInteger("totallines", stream); + this.totalfiles = getAttributeInteger("totalfiles", stream); + } + + public Integer getTotalLines() { + return totallines; + } + + public Integer getTotalFiles() { + return totalfiles; + } + +} diff --git a/src/main/java/com/stepstone/sonar/plugin/coldfusion/cflint/xml/LocationAttributes.java b/src/main/java/com/stepstone/sonar/plugin/coldfusion/cflint/xml/LocationAttributes.java index 57cdfb4..c2d3018 100644 --- a/src/main/java/com/stepstone/sonar/plugin/coldfusion/cflint/xml/LocationAttributes.java +++ b/src/main/java/com/stepstone/sonar/plugin/coldfusion/cflint/xml/LocationAttributes.java @@ -23,12 +23,12 @@ public class LocationAttributes extends TagAttribute { - private final Optional file; + private final String file; private final Optional line; private final Optional message; public LocationAttributes(XMLStreamReader stream) { - file = getAttributeValue("file", stream); + file = getAttributeValue("file", stream).get(); message = getAttributeValue("message", stream); Optional line = getAttributeValue("line", stream); @@ -40,7 +40,7 @@ public LocationAttributes(XMLStreamReader stream) { } } - public Optional getFile() { + public String getFile() { return file; } diff --git a/src/main/java/com/stepstone/sonar/plugin/coldfusion/cflint/xml/TagAttribute.java b/src/main/java/com/stepstone/sonar/plugin/coldfusion/cflint/xml/TagAttribute.java index dfa828a..45ee2fa 100644 --- a/src/main/java/com/stepstone/sonar/plugin/coldfusion/cflint/xml/TagAttribute.java +++ b/src/main/java/com/stepstone/sonar/plugin/coldfusion/cflint/xml/TagAttribute.java @@ -35,4 +35,17 @@ protected Optional getAttributeValue(String name, XMLStreamReader stream return Optional.absent(); } + + + protected Integer getAttributeInteger(String name, XMLStreamReader stream) { + + for (int i = 0; i < stream.getAttributeCount(); i++) { + + if (name.equalsIgnoreCase(stream.getAttributeLocalName(i))) { + return Integer.valueOf(stream.getAttributeValue(i)); + } + } + + return Integer.valueOf(0); + } } diff --git a/src/test/java/com/wellsky/ColdfusionPluginTest.java b/src/test/java/com/wellsky/ColdfusionPluginTest.java new file mode 100644 index 0000000..9e01e11 --- /dev/null +++ b/src/test/java/com/wellsky/ColdfusionPluginTest.java @@ -0,0 +1,26 @@ +package com.wellsky; + +import com.stepstone.sonar.plugin.coldfusion.ColdFusionPlugin; +import org.junit.Assert; +import org.junit.Test; +import org.sonar.api.Plugin; +import org.sonar.api.SonarQubeSide; +import org.sonar.api.SonarRuntime; +import org.sonar.api.internal.SonarRuntimeImpl; +import org.sonar.api.utils.Version; + +public class ColdfusionPluginTest { + + + private static final Version VERSION_6_5 = Version.create(6, 5); + + @Test + public void testExtensions() { + ColdFusionPlugin plugin = new ColdFusionPlugin(); + SonarRuntime runtime = SonarRuntimeImpl.forSonarQube(VERSION_6_5, SonarQubeSide.SERVER); + Plugin.Context context = new Plugin.Context(runtime); + plugin.define(context); + + Assert.assertEquals(5, context.getExtensions().size()); + } +} diff --git a/src/test/java/com/wellsky/ColdfusionSensorTest.java b/src/test/java/com/wellsky/ColdfusionSensorTest.java new file mode 100644 index 0000000..c74603b --- /dev/null +++ b/src/test/java/com/wellsky/ColdfusionSensorTest.java @@ -0,0 +1,72 @@ +package com.wellsky; + +import com.stepstone.sonar.plugin.coldfusion.ColdFusionPlugin; +import com.stepstone.sonar.plugin.coldfusion.ColdFusionSensor; +import org.junit.Assert; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.TemporaryFolder; +import org.mockito.Mockito; +import org.sonar.api.SonarQubeSide; +import org.sonar.api.batch.fs.InputFile; +import org.sonar.api.batch.fs.internal.DefaultFileSystem; +import org.sonar.api.batch.sensor.internal.SensorContextTester; +import org.sonar.api.internal.SonarRuntimeImpl; +import org.sonar.api.internal.apachecommons.codec.Charsets; +import org.sonar.api.measures.CoreMetrics; +import org.sonar.api.measures.FileLinesContext; +import org.sonar.api.measures.FileLinesContextFactory; +import org.sonar.api.profiles.RulesProfile; +import org.sonar.api.utils.Version; +import org.sonar.api.utils.command.CommandExecutor; + +import java.io.File; +import java.io.IOException; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.Matchers.any; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +public class ColdfusionSensorTest { + + private RulesProfile rulesProfile = RulesProfile.create(RulesProfile.SONAR_WAY_NAME, ColdFusionPlugin.LANGUAGE_NAME); + + @Rule + public TemporaryFolder tmpFolder = new TemporaryFolder(); + + @Test + public void testBasicCFMAnalysis() throws IOException { + DefaultFileSystem fileSystem = new DefaultFileSystem(tmpFolder.getRoot()); + fileSystem.setEncoding(Charsets.UTF_8); + fileSystem.setWorkDir(tmpFolder.getRoot().toPath()); + + File sourceDir = new File("src/test/resources"); + SensorContextTester context = SensorContextTester.create(sourceDir.toPath()); + context.setFileSystem(fileSystem); + context.setRuntime(SonarRuntimeImpl.forSonarQube(Version.create(6, 7), SonarQubeSide.SCANNER)); + CommandExecutor commandExecutor = CommandExecutor.create(); + String javaHome = System.getProperty("java.home"); + Assert.assertTrue(javaHome!=null && !javaHome.equals("")); + //FIXME get Java on Linux too and check there is java Home set + if(OSValidator.isWindows()) { + context.settings().appendProperty(ColdFusionPlugin.CFLINT_JAVA, javaHome + "/bin/java.exe"); + } else { + context.settings().appendProperty(ColdFusionPlugin.CFLINT_JAVA, javaHome + "/bin/java"); + } + + context.settings().appendProperty("sonar.sources",sourceDir.getPath()); + // Mock visitor for metrics. + FileLinesContext fileLinesContext = mock(FileLinesContext.class); + FileLinesContextFactory fileLinesContextFactory = mock(FileLinesContextFactory.class); + when(fileLinesContextFactory.createFor(any(InputFile.class))).thenReturn(fileLinesContext); + context = Mockito.spy(context); + ColdFusionSensor sensor = new ColdFusionSensor(context.fileSystem(), rulesProfile); + sensor.execute(context); + + assertThat(context.measure(context.module().key(), CoreMetrics.FILES.key()).value()).isEqualTo(2); + + assertThat(context.measure(context.module().key(), CoreMetrics.LINES.key()).value()).isEqualTo(19); + } + +} diff --git a/src/test/java/com/wellsky/OSValidator.java b/src/test/java/com/wellsky/OSValidator.java new file mode 100644 index 0000000..25649de --- /dev/null +++ b/src/test/java/com/wellsky/OSValidator.java @@ -0,0 +1,35 @@ +package com.wellsky; + +public class OSValidator { + + private static String OS = System.getProperty("os.name").toLowerCase(); + + public static boolean isWindows() { + return (OS.contains("win")); + } + + public static boolean isMac() { + return (OS.contains("mac") ); + } + + public static boolean isUnix() { + return (OS.contains("nix") || OS.contains("nux") || OS.contains("aix")); + } + + public static boolean isSolaris() { + return (OS.contains("sunos") ); + } + public static String getOS(){ + if (isWindows()) { + return "win"; + } else if (isMac()) { + return "osx"; + } else if (isUnix()) { + return "uni"; + } else if (isSolaris()) { + return "sol"; + } else { + return "err"; + } + } +} diff --git a/src/test/resources/testmetrics1.cfm b/src/test/resources/testmetrics1.cfm new file mode 100644 index 0000000..c347d76 --- /dev/null +++ b/src/test/resources/testmetrics1.cfm @@ -0,0 +1,8 @@ + + Hello #firstName#! + This CFML tutorial was designed for + + you! + + the world to see. + diff --git a/src/test/resources/testmetrics2.cfm b/src/test/resources/testmetrics2.cfm new file mode 100644 index 0000000..0121007 --- /dev/null +++ b/src/test/resources/testmetrics2.cfm @@ -0,0 +1,9 @@ + + + Hello #firstName#! + This CFML tutorial was designed for + + you! + + the world to see. +