Sonar Web插件

时间:2013-09-04 20:33:45

标签: java sonarqube

有人能指出我为sonarqube网络插件添加自定义配置文件规则吗?

我在javascript中看过xpath规则,但是网页插件不包含这样的内容。

具体来说,我正在尝试编写一些规则来检查WCAG2.0A的合规性。我知道我缺少的第一条规则是在页面上检查重复的ID。

如果网络插件不支持自定义规则,是否有人可以提供有关如何从源代码构建插件的资源?

3 个答案:

答案 0 :(得分:0)

目前无法向Web插件添加自定义规则。 请随意讨论您希望在用户邮件列表中添加的新规则:user [at] sonar.codehaus.org。 构建它:mvn install

答案 1 :(得分:0)

SonarQube Web插件中提供了

模板,可以为HTML或JSP文档创建简单的规则。可以通过用户定义的参数自定义模板。 (这可以在SonarQube Web界面中完成,不需要任何编码)。

可用模板:(版本为sonar-web-plugin-2.6)

  • 跟踪缺少必需的子元素

  • 跟踪缺少必需的父元素

  • 跟踪禁止父元素的存在

  • 跟踪不允许属性的使用

  • 跟踪不允许的子元素的使用

模板规则示例:

  • 创建一个规则,检查HTML文档中的所有“area”元素是否具有“alt”子元素。

    1. 选择“跟踪缺少必需的子元素”模板。
    2. 点击自定义规则“创建”按钮。
    3. 在“自定义规则”对话框中,输入新规则的名称和说明。
    4. 输入父元素“area”和子元素“alt”。
    5. 保存规则。

Create Custom Rule 1 Create Custom Rule 2

要创建模板未提供的规则,您需要修改插件源代码(需要Java编码)。请参阅我的其他回复。

答案 2 :(得分:0)

这是一个关于向SonarQube web-plugin源代码添加新规则“empty-heading”的教程。您需要编写一些Java代码。

提示:可以通过自定义模板而无需任何编码来创建一些简单的规则。 (见我的第一个回复)

示例规则:

安装程序插件:

  1. 在开始之前,您需要在盒子上安装Java 8,Maven 3和Git。您还需要访问SonarQube服务器。您可以从这里下载服务器。 https://www.sonarqube.org/downloads/

  2. 下载SonarQube网络插件源代码。

    $ git clone https://github.com/SonarSource/sonar-web.git

  3. 使用Maven构建插件项目。

    $ mvn clean install

  4. 将Maven项目导入IDE进行开发。

  5. 添加代码到插件:

    1. 将规则类HeadingNotEmptyCheck.java添加到src / main / java
    2. /*
       * SonarSource :: Web :: Sonar Plugin
       * Copyright (c) 2010-2017 SonarSource SA and Matthijs Galesloot
       * sonarqube@googlegroups.com
       *
       * 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 org.sonar.plugins.web.checks.coding;
      
      import java.util.List;
      import org.apache.commons.lang.StringUtils;
      import org.sonar.check.Rule;
      import org.sonar.plugins.web.checks.AbstractPageCheck;
      import org.sonar.plugins.web.node.Node;
      import org.sonar.plugins.web.node.TagNode;
      import org.sonar.plugins.web.node.TextNode;
      
      @Rule(key = "HeadingNotEmptyCheck")
      public class HeadingNotEmptyCheck extends AbstractPageCheck {
      
          private static final String[] headingTagsArray = StringUtils.split("H1,H2,H3,H4,H5,H6", ',');
          private TagNode startHeadingNode;
          private TextNode textNode;
      
          @Override
          public void startDocument(List<Node> nodes) {
              startHeadingNode = null;
              textNode = null;
          }
      
          @Override
          public void startElement(TagNode element) {
              if (isHeading(element)) {
                  this.startHeadingNode = element;
                  this.textNode = null;
              }
          }
      
          @Override
          public void endElement(TagNode element) {
              if (isHeading(element)) {
                  if (startHeadingNode == null || !startHeadingNode.getNodeName().equals(element.getNodeName())) {
                      createViolation(element.getStartLinePosition(),
                              "The tag \"" + element.getNodeName() + "\" has no corresponding start tag.");
                      this.textNode = null;
                      return;
                  }
                  // found matching start tag for end tag
                  startHeadingNode = null;
      
                  if (textNode == null) {
                      createViolation(element.getStartLinePosition(),
                              "The tag \"" + element.getNodeName() + "\" heading must not be empty.");
                      return;
                  }
              }
          }
      
          @Override
          public void characters(TextNode textNode) {
              if (!textNode.isBlank()) {
                  this.textNode = textNode; 
              }
          }
      
          private boolean isHeading(TagNode node) {
              for (String headingTag : headingTagsArray) {
                  if (node.equalsElementName(headingTag)) {
                      return true;
                  }
              }
              return false;
          }
      }
      
      1. 更新CheckClasses.java以注册新规则类
      2. public final class CheckClasses {
        
          private static final List<Class> CLASSES = ImmutableList.of(
            ...,
            HeadingNotEmptyCheck.class,
            ...
        
        1. 将HeadingNotEmptyCheck.html规则说明添加到src / main / resources,org / sonar / l10n / web / rules / Web /文件夹。
        2. <p>When at least one heading element (marked by &lt;h1&gt; through &lt;h6&gt;) is present, it is a best practice to ensure it contains content.</p>
          <h2>Noncompliant Code Example</h2>
          <pre>
          &lt;div&gt;
            &lt;h1&gt;&lt;/h1&gt; &lt;!-- Noncompliant; empty content --&gt;
            &lt;h2&gt;&lt;/h2&gt; &lt;!-- Noncompliant; empty content --&gt;
          &lt;/div&gt;
          </pre>
          <h2>Compliant Solution</h2>
          <pre>
          &lt;div&gt;
            &lt;h1&gt;&lt;/h1&gt;
            &lt;h2&gt;&lt;/h2&gt;
          &lt;/div&gt;
          </pre>
          
          1. 将HeadingNotEmptyCheck.json规则描述添加到src / main / resources,org / sonar / l10n / web / rules / Web / folder
          2. {
              "title": "Headings must not be empty ",
              "type": "BUG",
              "status": "ready",
              "remediation": {
                "func": "Constant\/Issue",
                "constantCost": "2min"
              },
              "tags": [
                "accessibility",
                "bug"
              ],
              "defaultSeverity": "Minor"
            }
            
            1. 将JUnit测试HeadingNotEmptyCheckTest.java添加到src / test / java
            2. /*
               * SonarSource :: Web :: Sonar Plugin
               * Copyright (c) 2010-2017 SonarSource SA and Matthijs Galesloot
               * sonarqube@googlegroups.com
               *
               * 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 org.sonar.plugins.web.checks.coding;
              
              import java.io.File;
              
              import org.junit.Rule;
              import org.junit.Test;
              import org.sonar.plugins.web.checks.CheckMessagesVerifierRule;
              import org.sonar.plugins.web.checks.TestHelper;
              import org.sonar.plugins.web.visitor.WebSourceCode;
              
              public class HeadingNotEmptyCheckTest {
                  @Rule
                  public CheckMessagesVerifierRule checkMessagesVerifier = new CheckMessagesVerifierRule();
              
                  @Test
                  public void testRule() {
                      HeadingNotEmptyCheck check = new HeadingNotEmptyCheck();
              
                      WebSourceCode sourceCode = TestHelper.scan(new File("src/test/resources/checks/HeadingNotEmptyCheck.html"),
                              check);
              
                      checkMessagesVerifier.verify(sourceCode.getIssues()).next().atLine(8)
                              .withMessage("The tag \"h1\" heading must not be empty.").next().atLine(12)
                              .withMessage("The tag \"h2\" heading must not be empty.").next();
                  }
              }
              
              1. 将测试文件HeadingNotEmptyCheck.html添加到src / test / resources,检查/文件夹
              2. <!DOCTYPE html>
                <html>
                <head>
                <title>Title of the document</title>
                </head>
                <body>
                    <!-- invalid empty heading -->
                    <h1></h1>
                    <!-- valid heading -->
                    <h1>h1 has content</h1>
                    <!-- invalid empty heading -->
                    <h2></h2>
                    <!-- valid heading -->
                    <h2>h2 has content</h2>
                    <!-- invalid nested heading -->
                    <h1>h1 has content
                        <h2>h2 has content</h2>
                    </h1>
                </body>
                </html>
                

                测试并部署插件:

                1. 运行HeadingNotEmptyCheckTest JUnit测试用例。如果它有效,您就可以构建和部署插件了。

                2. 使用Maven构建插件项目。

                  $ mvn clean install

                3. 将插件构建工件复制到SonarQube插件文件夹。

                  GIT_REPO \ sonar-web \ sonar-web-plugin \ target \ sonar-web-plugin- [VERSION] .jar - &gt; \ sonarqube-6.2 \扩展\插件

                4. 重新启动SonarQube服务器

                5. 验证SonarQube服务器上的新规则

                  登录SonarQube,选择“规则”菜单,过滤语言“Web”,您应该看到新规则“标题不能为空”

                6. new rule: Headings must not be empty