]> source.dussan.org Git - sonarqube.git/commitdiff
Make Xoo a SonarLint plugin 1096/head
authorJulien HENRY <julien.henry@sonarsource.com>
Mon, 11 Jul 2016 15:46:57 +0000 (17:46 +0200)
committerJulien HENRY <julien.henry@sonarsource.com>
Tue, 12 Jul 2016 09:21:35 +0000 (11:21 +0200)
plugins/sonar-xoo-plugin/pom.xml
plugins/sonar-xoo-plugin/src/main/java/org/sonar/xoo/XooPlugin.java
plugins/sonar-xoo-plugin/src/main/java/org/sonar/xoo/rule/AbstractXooRuleSensor.java [new file with mode: 0644]
plugins/sonar-xoo-plugin/src/main/java/org/sonar/xoo/rule/HasTagSensor.java
plugins/sonar-xoo-plugin/src/main/java/org/sonar/xoo/rule/NoSonarSensor.java [new file with mode: 0644]
plugins/sonar-xoo-plugin/src/main/java/org/sonar/xoo/rule/XooRulesDefinition.java
plugins/sonar-xoo-plugin/src/test/java/org/sonar/xoo/XooPluginTest.java
pom.xml

index 6145bee37ea09651b1e33f9a9da03394074e1abc..5240a80f49949581015742b7ab73071d63f8fc20 100644 (file)
@@ -67,6 +67,7 @@
           <pluginKey>xoo</pluginKey>
           <pluginName>Xoo</pluginName>
           <pluginClass>org.sonar.xoo.XooPlugin</pluginClass>
+          <sonarLintSupported>true</sonarLintSupported>
         </configuration>
       </plugin>
     </plugins>
index c1d757812a7da09230e8c971caa5cf24ba29fa50..9b443628856a31b98a63b6bb56e88be7f724aba8 100644 (file)
@@ -40,6 +40,7 @@ import org.sonar.xoo.rule.CustomMessageSensor;
 import org.sonar.xoo.rule.DeprecatedResourceApiSensor;
 import org.sonar.xoo.rule.HasTagSensor;
 import org.sonar.xoo.rule.MultilineIssuesSensor;
+import org.sonar.xoo.rule.NoSonarSensor;
 import org.sonar.xoo.rule.OneBlockerIssuePerFileSensor;
 import org.sonar.xoo.rule.OneBugIssuePerLineSensor;
 import org.sonar.xoo.rule.OneDayDebtPerFileSensor;
@@ -62,7 +63,7 @@ import org.sonar.xoo.scm.XooScmProvider;
 import org.sonar.xoo.test.CoveragePerTestSensor;
 import org.sonar.xoo.test.TestExecutionSensor;
 
-import static org.sonar.api.SonarQubeVersion.V5_5;
+import static org.sonar.api.SonarRuntime.V5_5;
 
 /**
  * Plugin entry-point, as declared in pom.xml.
@@ -99,6 +100,7 @@ public class XooPlugin implements Plugin {
       ChecksSensor.class,
       RandomAccessSensor.class,
       SaveDataTwiceSensor.class,
+      NoSonarSensor.class,
 
       OneBlockerIssuePerFileSensor.class,
       OneIssuePerLineSensor.class,
@@ -128,8 +130,8 @@ public class XooPlugin implements Plugin {
       // Other
       XooProjectBuilder.class,
       XooPostJob.class);
-    
-    if(context.getRuntimeProduct() != SonarProduct.SONARLINT) {
+
+    if (context.getRuntimeProduct() != SonarProduct.SONARLINT) {
       context.addExtensions(MeasureSensor.class,
         DeprecatedResourceApiSensor.class);
     }
diff --git a/plugins/sonar-xoo-plugin/src/main/java/org/sonar/xoo/rule/AbstractXooRuleSensor.java b/plugins/sonar-xoo-plugin/src/main/java/org/sonar/xoo/rule/AbstractXooRuleSensor.java
new file mode 100644 (file)
index 0000000..b1fa099
--- /dev/null
@@ -0,0 +1,66 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2016 SonarSource SA
+ * mailto:contact AT sonarsource DOT com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+package org.sonar.xoo.rule;
+
+import org.sonar.api.batch.fs.FileSystem;
+import org.sonar.api.batch.fs.InputFile;
+import org.sonar.api.batch.rule.ActiveRules;
+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.rule.RuleKey;
+import org.sonar.xoo.Xoo;
+
+public abstract class AbstractXooRuleSensor implements Sensor {
+
+  private final FileSystem fs;
+  private final ActiveRules activeRules;
+
+  public AbstractXooRuleSensor(FileSystem fs, ActiveRules activeRules) {
+    this.fs = fs;
+    this.activeRules = activeRules;
+  }
+
+  protected abstract String getRuleKey();
+
+  @Override
+  public void describe(SensorDescriptor descriptor) {
+    descriptor
+      .onlyOnLanguage(Xoo.KEY)
+      .createIssuesForRuleRepository(XooRulesDefinition.XOO_REPOSITORY);
+  }
+
+  @Override
+  public void execute(SensorContext context) {
+    doAnalyse(context, Xoo.KEY);
+  }
+
+  private void doAnalyse(SensorContext context, String languageKey) {
+    RuleKey ruleKey = RuleKey.of(XooRulesDefinition.XOO_REPOSITORY, getRuleKey());
+    if (activeRules.find(ruleKey) == null) {
+      return;
+    }
+    for (InputFile inputFile : fs.inputFiles(fs.predicates().hasLanguage(languageKey))) {
+      processFile(inputFile, context, ruleKey, languageKey);
+    }
+  }
+
+  protected abstract void processFile(InputFile inputFile, SensorContext context, RuleKey ruleKey, String languageKey);
+}
index 465d3105172cf7d5a93d90b2f549d4f1feab8174..9f030e6db69fe2e3f37f5a19e2bdffd8fea5481a 100644 (file)
 package org.sonar.xoo.rule;
 
 import java.io.IOException;
-import java.util.List;
-import org.apache.commons.io.FileUtils;
-import org.sonar.api.batch.SensorContext;
+import java.nio.file.Files;
 import org.sonar.api.batch.fs.FileSystem;
 import org.sonar.api.batch.fs.InputFile;
 import org.sonar.api.batch.rule.ActiveRules;
-import org.sonar.api.component.ResourcePerspectives;
-import org.sonar.api.config.Settings;
-import org.sonar.api.issue.Issuable;
+import org.sonar.api.batch.sensor.SensorContext;
+import org.sonar.api.batch.sensor.issue.NewIssue;
 import org.sonar.api.rule.RuleKey;
 
 /**
  * Generate issues on all the occurrences of a given tag in xoo sources.
  */
-public class HasTagSensor extends AbstractDeprecatedXooRuleSensor {
+public class HasTagSensor extends AbstractXooRuleSensor {
 
   public static final String RULE_KEY = "HasTag";
 
   private static final String EFFORT_TO_FIX_PROPERTY = "sonar.hasTag.effortToFix";
 
-  private final ResourcePerspectives perspectives;
-  private final Settings settings;
   private final ActiveRules activeRules;
 
-  private FileSystem fs;
-
-  public HasTagSensor(FileSystem fs, ResourcePerspectives perspectives, Settings settings, ActiveRules activeRules) {
+  public HasTagSensor(FileSystem fs, ActiveRules activeRules) {
     super(fs, activeRules);
-    this.fs = fs;
-    this.perspectives = perspectives;
-    this.settings = settings;
     this.activeRules = activeRules;
   }
 
@@ -60,24 +50,28 @@ public class HasTagSensor extends AbstractDeprecatedXooRuleSensor {
   }
 
   @Override
-  protected void processFile(InputFile inputFile, org.sonar.api.resources.File sonarFile, SensorContext context, RuleKey ruleKey, String languageKey) {
+  protected void processFile(InputFile inputFile, SensorContext context, RuleKey ruleKey, String languageKey) {
     org.sonar.api.batch.rule.ActiveRule activeRule = activeRules.find(ruleKey);
     String tag = activeRule.param("tag");
     if (tag == null) {
       throw new IllegalStateException("Rule is badly configured. The parameter 'tag' is missing.");
     }
     try {
-      Issuable issuable = perspectives.as(Issuable.class, sonarFile);
-      List<String> lines = FileUtils.readLines(inputFile.file(), fs.encoding().name());
-      for (int index = 0; index < lines.size(); index++) {
-        if (lines.get(index).contains(tag)) {
-          issuable.addIssue(issuable.newIssueBuilder()
-            .effortToFix(settings.getDouble(EFFORT_TO_FIX_PROPERTY))
-            .line(index + 1)
-            .ruleKey(ruleKey)
-            .build());
+      int[] lineCounter = {1};
+      Files.lines(inputFile.path(), context.fileSystem().encoding()).forEachOrdered(lineStr -> {
+        int startIndex = -1;
+        while ((startIndex = lineStr.indexOf(tag, startIndex + 1)) != -1) {
+          NewIssue newIssue = context.newIssue();
+          newIssue
+            .forRule(ruleKey)
+            .gap(context.settings().getDouble(EFFORT_TO_FIX_PROPERTY))
+            .at(newIssue.newLocation()
+              .on(inputFile)
+              .at(inputFile.newRange(lineCounter[0], startIndex, lineCounter[0], startIndex + tag.length())))
+            .save();
         }
-      }
+        lineCounter[0]++;
+      });
     } catch (IOException e) {
       throw new IllegalStateException("Fail to process " + inputFile, e);
     }
diff --git a/plugins/sonar-xoo-plugin/src/main/java/org/sonar/xoo/rule/NoSonarSensor.java b/plugins/sonar-xoo-plugin/src/main/java/org/sonar/xoo/rule/NoSonarSensor.java
new file mode 100644 (file)
index 0000000..45d6b9d
--- /dev/null
@@ -0,0 +1,71 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2016 SonarSource SA
+ * mailto:contact AT sonarsource DOT com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+package org.sonar.xoo.rule;
+
+import java.io.IOException;
+import java.nio.file.Files;
+import java.util.HashSet;
+import java.util.Set;
+import org.sonar.api.batch.Phase;
+import org.sonar.api.batch.fs.InputFile;
+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.issue.NoSonarFilter;
+import org.sonar.xoo.Xoo;
+
+@Phase(name = Phase.Name.PRE)
+public class NoSonarSensor implements Sensor {
+
+  private NoSonarFilter noSonarFilter;
+
+  public NoSonarSensor(NoSonarFilter noSonarFilter) {
+    this.noSonarFilter = noSonarFilter;
+  }
+
+  @Override
+  public void describe(SensorDescriptor descriptor) {
+    descriptor
+      .onlyOnLanguage(Xoo.KEY);
+  }
+
+  @Override
+  public void execute(SensorContext context) {
+    for (InputFile inputFile : context.fileSystem().inputFiles(context.fileSystem().predicates().hasLanguage(Xoo.KEY))) {
+      processFile(inputFile, context);
+    }
+  }
+
+  private void processFile(InputFile inputFile, SensorContext context) {
+    try {
+      Set<Integer> noSonarLines = new HashSet<>();
+      int[] lineCounter = {1};
+      Files.lines(inputFile.path(), context.fileSystem().encoding()).forEachOrdered(lineStr -> {
+        if (lineStr.contains("//NOSONAR")) {
+          noSonarLines.add(lineCounter[0]);
+        }
+        lineCounter[0]++;
+      });
+      noSonarFilter.noSonarInFile(inputFile, noSonarLines);
+    } catch (IOException e) {
+      throw new IllegalStateException("Fail to process " + inputFile, e);
+    }
+  }
+}
index 3233ab2d369e134244cf64a15abe57cd9763d66b..0940a41eec236dc8964965e9e6909e9fb2567720 100644 (file)
@@ -62,6 +62,7 @@ public class XooRulesDefinition implements RulesDefinition {
     new RulesDefinitionAnnotationLoader().load(repo, Check.ALL);
 
     NewRule hasTag = repo.createRule(HasTagSensor.RULE_KEY).setName("Has Tag")
+      .setActivatedByDefault(true)
       .setHtmlDescription("Search for a given tag in Xoo files");
     hasTag
       .setDebtRemediationFunction(hasTag.debtRemediationFunctions().constantPerIssue("2min"));
@@ -80,7 +81,7 @@ public class XooRulesDefinition implements RulesDefinition {
     NewRule oneIssuePerLine = repo.createRule(OneIssuePerLineSensor.RULE_KEY).setName("One Issue Per Line")
       .setHtmlDescription("Generate an issue on each line of a file. It requires the metric \"lines\".");
     oneIssuePerLine
-      .setDebtRemediationFunction(hasTag.debtRemediationFunctions().linear("1min"))
+      .setDebtRemediationFunction(oneIssuePerLine.debtRemediationFunctions().linear("1min"))
       .setGapDescription("It takes about 1 minute to an experienced software craftsman to remove a line of code");
 
     repo.createRule(OneIssueOnDirPerFileSensor.RULE_KEY).setName("One Issue On Dir Per File")
@@ -88,16 +89,16 @@ public class XooRulesDefinition implements RulesDefinition {
 
     NewRule oneIssuePerFile = repo.createRule(OneIssuePerFileSensor.RULE_KEY).setName("One Issue Per File")
       .setHtmlDescription("Generate an issue on each file");
-    oneIssuePerFile.setDebtRemediationFunction(hasTag.debtRemediationFunctions().linear("10min"));
+    oneIssuePerFile.setDebtRemediationFunction(oneIssuePerFile.debtRemediationFunctions().linear("10min"));
 
     NewRule oneDayDebtPerFile = repo.createRule(OneDayDebtPerFileSensor.RULE_KEY).setName("One Day Debt Per File")
       .setHtmlDescription("Generate an issue on each file with a debt of one day");
-    oneDayDebtPerFile.setDebtRemediationFunction(hasTag.debtRemediationFunctions().linear("1d"));
+    oneDayDebtPerFile.setDebtRemediationFunction(oneDayDebtPerFile.debtRemediationFunctions().linear("1d"));
 
     NewRule oneIssuePerModule = repo.createRule(OneIssuePerModuleSensor.RULE_KEY).setName("One Issue Per Module")
       .setHtmlDescription("Generate an issue on each module");
     oneIssuePerModule
-      .setDebtRemediationFunction(hasTag.debtRemediationFunctions().linearWithOffset("25min", "1h"))
+      .setDebtRemediationFunction(oneIssuePerModule.debtRemediationFunctions().linearWithOffset("25min", "1h"))
       .setGapDescription("A certified architect will need roughly half an hour to start working on removal of modules, " +
         "then it's about one hour per module.");
 
@@ -120,13 +121,13 @@ public class XooRulesDefinition implements RulesDefinition {
       .setHtmlDescription("Generate a bug issue on each line of a file. It requires the metric \"lines\".")
       .setType(RuleType.BUG);
     oneBugIssuePerLine
-      .setDebtRemediationFunction(hasTag.debtRemediationFunctions().linear("5min"));
+      .setDebtRemediationFunction(oneBugIssuePerLine.debtRemediationFunctions().linear("5min"));
 
     NewRule oneVulnerabilityIssuePerModule = repo.createRule(OneVulnerabilityIssuePerModuleSensor.RULE_KEY).setName("One Vulnerability Issue Per Module")
       .setHtmlDescription("Generate an issue on each module")
       .setType(RuleType.VULNERABILITY);
     oneVulnerabilityIssuePerModule
-      .setDebtRemediationFunction(hasTag.debtRemediationFunctions().linearWithOffset("25min", "1h"))
+      .setDebtRemediationFunction(oneVulnerabilityIssuePerModule.debtRemediationFunctions().linearWithOffset("25min", "1h"))
       .setGapDescription("A certified architect will need roughly half an hour to start working on removal of modules, " +
         "then it's about one hour per module.");
 
index 33ec8a591679bd85254e10615b390f7c329bbe4c..6a0507af8d1086528ea5fcfa09038034020e54fe 100644 (file)
@@ -35,10 +35,10 @@ public class XooPluginTest {
   public void provide_extensions_for_5_5() {
     Plugin.Context context = new Plugin.Context(new SonarRuntime(Version.parse("5.5"), SonarProduct.SONARQUBE, SonarQubeSide.SCANNER));
     new XooPlugin().define(context);
-    assertThat(context.getExtensions()).hasSize(42).contains(CpdTokenizerSensor.class);
+    assertThat(context.getExtensions()).hasSize(43).contains(CpdTokenizerSensor.class);
 
     context = new Plugin.Context(new SonarRuntime(Version.parse("5.4"), SonarProduct.SONARLINT, null));
     new XooPlugin().define(context);
-    assertThat(context.getExtensions()).hasSize(39).doesNotContain(CpdTokenizerSensor.class);
+    assertThat(context.getExtensions()).hasSize(40).doesNotContain(CpdTokenizerSensor.class);
   }
 }
diff --git a/pom.xml b/pom.xml
index ee93ce5e762fbc8b2a65e2c1c2b4ec2bf6f98375..41c85feded256cc07dfd38319346a84e1d19712e 100644 (file)
--- a/pom.xml
+++ b/pom.xml
         <plugin>
           <groupId>org.sonarsource.sonar-packaging-maven-plugin</groupId>
           <artifactId>sonar-packaging-maven-plugin</artifactId>
-          <version>1.15</version>
+          <version>1.17-build269</version>
         </plugin>
         <plugin>
           <groupId>org.owasp</groupId>