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.
+