有人能指出我为sonarqube网络插件添加自定义配置文件规则吗?
我在javascript中看过xpath规则,但是网页插件不包含这样的内容。
具体来说,我正在尝试编写一些规则来检查WCAG2.0A的合规性。我知道我缺少的第一条规则是在页面上检查重复的ID。
如果网络插件不支持自定义规则,是否有人可以提供有关如何从源代码构建插件的资源?
答案 0 :(得分:0)
目前无法向Web插件添加自定义规则。 请随意讨论您希望在用户邮件列表中添加的新规则:user [at] sonar.codehaus.org。 构建它:mvn install
答案 1 :(得分:0)
模板,可以为HTML或JSP文档创建简单的规则。可以通过用户定义的参数自定义模板。 (这可以在SonarQube Web界面中完成,不需要任何编码)。
可用模板:(版本为sonar-web-plugin-2.6)
跟踪缺少必需的子元素
跟踪缺少必需的父元素
跟踪禁止父元素的存在
跟踪不允许属性的使用
跟踪不允许的子元素的使用
模板规则示例:
创建一个规则,检查HTML文档中的所有“area”元素是否具有“alt”子元素。
要创建模板未提供的规则,您需要修改插件源代码(需要Java编码)。请参阅我的其他回复。
答案 2 :(得分:0)
这是一个关于向SonarQube web-plugin源代码添加新规则“empty-heading”的教程。您需要编写一些Java代码。
提示:可以通过自定义模板而无需任何编码来创建一些简单的规则。 (见我的第一个回复)
在开始之前,您需要在盒子上安装Java 8,Maven 3和Git。您还需要访问SonarQube服务器。您可以从这里下载服务器。 https://www.sonarqube.org/downloads/
下载SonarQube网络插件源代码。
$ git clone https://github.com/SonarSource/sonar-web.git
使用Maven构建插件项目。
$ mvn clean install
将Maven项目导入IDE进行开发。
/*
* 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;
}
}
public final class CheckClasses {
private static final List<Class> CLASSES = ImmutableList.of(
...,
HeadingNotEmptyCheck.class,
...
<p>When at least one heading element (marked by <h1> through <h6>) is present, it is a best practice to ensure it contains content.</p>
<h2>Noncompliant Code Example</h2>
<pre>
<div>
<h1></h1> <!-- Noncompliant; empty content -->
<h2></h2> <!-- Noncompliant; empty content -->
</div>
</pre>
<h2>Compliant Solution</h2>
<pre>
<div>
<h1></h1>
<h2></h2>
</div>
</pre>
{
"title": "Headings must not be empty ",
"type": "BUG",
"status": "ready",
"remediation": {
"func": "Constant\/Issue",
"constantCost": "2min"
},
"tags": [
"accessibility",
"bug"
],
"defaultSeverity": "Minor"
}
/*
* 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();
}
}
<!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>
运行HeadingNotEmptyCheckTest JUnit测试用例。如果它有效,您就可以构建和部署插件了。
使用Maven构建插件项目。
$ mvn clean install
将插件构建工件复制到SonarQube插件文件夹。
GIT_REPO \ sonar-web \ sonar-web-plugin \ target \ sonar-web-plugin- [VERSION] .jar - &gt; \ sonarqube-6.2 \扩展\插件
重新启动SonarQube服务器
验证SonarQube服务器上的新规则
登录SonarQube,选择“规则”菜单,过滤语言“Web”,您应该看到新规则“标题不能为空”