0

谁能指出我为 sonarqube Web 插件添加自定义配置文件规则的方向?

我在 javascript 中看到了 xpath 规则,但是 web 插件不包含类似的东西。

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

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

4

3 回答 3

0

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

于 2013-09-05T17:16:49.573 回答
0
于 2017-04-23T14:50:38.147 回答
0

这是关于向SonarQube 网络插件源代码添加新规则“空标题”的教程。您需要编写一些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 全新安装

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

将代码添加到插件:

  1. 将 Rule 类 HeadingNotEmptyCheck.java 添加到 src/main/java
/*
 * 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 以注册新的规则类
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/ 文件夹。
<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/ 文件夹
{
  "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
/*
 * 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, checks/ 文件夹
<!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 全新安装

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

    GIT_REPO\sonar-web\sonar-web-plugin\target\sonar-web-plugin-[版本].jar -> \sonarqube-6.2\extensions\plugins

  4. 重启 SonarQube 服务器

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

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

新规则:标题不能为空

于 2017-04-24T15:36:15.330 回答