Skip to content

Commit d96b9da

Browse files
committed
Fixes for #16 and for making plugin work with Sonar 9+ version
1 parent 5c612a1 commit d96b9da

32 files changed

+6371
-3146
lines changed

examples/1-tsql/00-installTools.ps1

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ function Setup-SqlCodeGuard {
2020
}
2121

2222
function Setup-SonarScanner {
23-
$url = "https://binaries.sonarsource.com/Distribution/sonar-scanner-cli/sonar-scanner-cli-3.3.0.1492-windows.zip"
23+
$url = "https://binaries.sonarsource.com/Distribution/sonar-scanner-cli/sonar-scanner-cli-4.6.2.2472-windows.zip"
2424
$output = "$baseToolsDir\scanner.zip";
2525
$outputDir = "$baseToolsDir\sonar-scanner"
2626
[Net.ServicePointManager]::SecurityProtocol = [System.Net.SecurityProtocolType]::Tls12

examples/1-tsql/02-runSonar.ps1

Lines changed: 58 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -1,45 +1,58 @@
1-
$sqlCodeGuard = "$PSScriptRoot\tools\SQLCodeGuardCmdLine\SqlCodeGuard30.Cmd.exe"
2-
3-
## Run tests with SQLCover
4-
$database = "ExampleDatabase"
5-
$server = ".\SQLEXPRESS01"
6-
$cloverDir = "$PSScriptRoot\tools\SQLCover"
7-
$coverageOutputDir = "$PSScriptRoot\build\sqlcoverresults"
8-
9-
. "$cloverDir\SQLCover.ps1"
10-
$results = Get-CoverTSql "$cloverDir\SQLCover.dll" "server=$server;initial catalog=$database;integrated security=sspi;" "$database " "exec tSQLt.RunAll"
11-
New-Item -ItemType Directory -Force -Path $coverageOutputDir
12-
Export-OpenXml $results "$coverageOutputDir"
13-
14-
15-
## Build and run code analysis
16-
$dbProject = "$PSScriptRoot\src\ExampleDatabase\ExampleDatabase.sln"
17-
$msbuildpath = Resolve-Path "C:\Program Files*\MSBuild\*\Bin\*\MSBuild.exe" | select -ExpandProperty Path -First 1
18-
19-
20-
&$msbuildpath "$dbProject" /t:build /p:RunSqlCodeAnalysis=True
21-
22-
23-
24-
25-
## Run sonar-scanner
26-
27-
28-
$sonarScanner = "$PSScriptRoot\tools\sonar-scanner\sonar-scanner-3.3.0.1492-windows\bin\sonar-scanner.bat"
29-
30-
$sonarArgs = @(
31-
"-Dsonar.host.url=http://localhost:9000"
32-
"-Dsonar.exclusions=**/bin/**/*.*,**/obj/**/*.*,**/*.sqlproj", # skip build files from analysis
33-
34-
# it is possible to specify absolute path to the SQLCover report or directory where file matching *Coverage.opencoverxml resides, by default plugin will try to find it in the base directory's subdirectories
35-
# "-Dsonar.sql.tsql.sqlcover.report=$coverageOutputDir\Coverage.opencoverxml",
36-
37-
# setting sql code guard path
38-
"-Dsonar.sql.tsql.cg.path=$sqlCodeGuard",
39-
"-X"
40-
41-
# it is possible to specify absolute path to the MSBuild code analysis report or directory where file matching *StaticCodeAnalysis.Results.xml resides, by default plugin will try to find it in the base directory's subdirectories
42-
#"-Dsonar.sql.tsql.ms.report=$PSScriptRoot\src\ExampleDatabase\ExampleDatabase\bin\Debug"
43-
44-
);
45-
&$sonarScanner $sonarArgs
1+
$baseToolsDir = "$PSScriptRoot\tools";
2+
New-Item -ItemType Directory -Force -Path $baseToolsDir
3+
4+
function Start-SQLCover {
5+
$database = "ExampleDatabase"
6+
$server = ".\SQLEXPRESS01"
7+
$cloverDir = "$PSScriptRoot\tools\SQLCover"
8+
$coverageOutputDir = "$PSScriptRoot\build\sqlcoverresults"
9+
10+
. "$cloverDir\SQLCover.ps1"
11+
$results = Get-CoverTSql "$cloverDir\SQLCover.dll" "server=$server;initial catalog=$database;integrated security=sspi;" "$database " "exec tSQLt.RunAll"
12+
New-Item -ItemType Directory -Force -Path $coverageOutputDir
13+
Export-OpenXml $results "$coverageOutputDir"
14+
}
15+
16+
function Start-MsBuild {
17+
$dbProject = "$PSScriptRoot\src\ExampleDatabase\ExampleDatabase.sln"
18+
$msbuildpath = Resolve-Path "C:\Program Files*\MSBuild\*\Bin\*\MSBuild.exe" | select -ExpandProperty Path -First 1
19+
&$msbuildpath "$dbProject" /t:build /p:RunSqlCodeAnalysis=True
20+
}
21+
22+
function Start-DotnetMsBuild {
23+
$dbProject = "$PSScriptRoot\src\ExampleDatabase\ExampleDatabase.sln"
24+
$msbuildpath = "dotnet"
25+
$msbuildArgs = @("msbuild", "$dbProject", "/t:build", "/p:RunSqlCodeAnalysis=True")
26+
Write-Output "$msbuildpath $msbuildArgs"
27+
&$msbuildpath $msbuildArgs
28+
}
29+
30+
31+
function Start-Sonar {
32+
$sqlCodeGuard = "$PSScriptRoot\tools\SQLCodeGuardCmdLine\SqlCodeGuard30.Cmd.exe"
33+
$sonarScanner = Resolve-Path "$PSScriptRoot\tools\sonar-scanner\*\bin\sonar-scanner.bat" | select -ExpandProperty Path -First 1
34+
35+
$sonarArgs = @(
36+
"-Dsonar.host.url=http://localhost:9000"
37+
"-Dsonar.exclusions=**/bin/**/*.*,**/obj/**/*.*,**/*.sqlproj", # skip build files from analysis
38+
39+
# it is possible to specify absolute path to the SQLCover report or directory where file matching *Coverage.opencoverxml resides, by default plugin will try to find it in the base directory's subdirectories
40+
# "-Dsonar.sql.tsql.sqlcover.report=$coverageOutputDir\Coverage.opencoverxml",
41+
42+
# setting sql code guard path
43+
"-Dsonar.sql.tsql.cg.path=$sqlCodeGuard",
44+
"-X"
45+
46+
# it is possible to specify absolute path to the MSBuild code analysis report or directory where file matching *StaticCodeAnalysis.Results.xml resides, by default plugin will try to find it in the base directory's subdirectories
47+
#"-Dsonar.sql.tsql.ms.report=$PSScriptRoot\src\ExampleDatabase\ExampleDatabase\bin\Debug"
48+
49+
);
50+
&$sonarScanner $sonarArgs
51+
}
52+
53+
## Uncomment where required
54+
55+
#Start-SQLCOver
56+
#Start-MsBuild
57+
#Start-DotnetMsBuild
58+
Start-Sonar

src/sonar-sql-plugin/pom.xml

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55

66
<groupId>org.sonar.plugins</groupId>
77
<artifactId>sonar-sql-plugin</artifactId>
8-
<version>1.1.1</version>
8+
<version>1.1.2</version>
99
<packaging>sonar-plugin</packaging>
1010

1111
<name>SQL language plugin</name>
@@ -14,11 +14,12 @@
1414
<url>https://github.com/gretard/sonar-sql-plugin</url>
1515

1616
<properties>
17-
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
18-
<sonar.apiVersion>7.4</sonar.apiVersion>
19-
<jdk.min.version>1.8</jdk.min.version>
20-
<maven.compiler.target>1.8</maven.compiler.target>
21-
<maven.source.target>1.8</maven.source.target>
17+
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
18+
<sonar.apiVersion>9.0.1.46107</sonar.apiVersion>
19+
20+
<jdk.min.version>1.9</jdk.min.version>
21+
<maven.compiler.target>1.9</maven.compiler.target>
22+
<maven.source.target>1.9</maven.source.target>
2223

2324
</properties>
2425

@@ -71,7 +72,11 @@
7172
<version>29.0-jre</version>
7273
<scope>test</scope>
7374
</dependency>
74-
75+
<dependency>
76+
<groupId>org.sonarsource.sonarqube</groupId>
77+
<artifactId>sonar-plugin-api-impl</artifactId>
78+
<version>${sonar.apiVersion}</version>
79+
</dependency>
7580

7681
<dependency>
7782
<groupId>org.antlr</groupId>

src/sonar-sql-plugin/src/main/java/org/antlr/sql/sca/nodes/ParseTreeNode.java

Lines changed: 43 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,26 @@ public class ParseTreeNode implements IParsedNode {
1414

1515
private ParseTree tree;
1616

17+
private int globalIndex;
18+
19+
private int distance;
20+
21+
private int index;
22+
23+
private int index2;
24+
25+
public ParseTreeNode(ParseTree tree) {
26+
this.tree = tree;
27+
}
28+
29+
public ParseTreeNode(ParseTree tree, int distance, int index, int index2) {
30+
this.tree = tree;
31+
this.distance = distance;
32+
this.index = index;
33+
this.index2 = index2;
34+
}
35+
36+
@Override
1737
public int getDistance() {
1838
return distance;
1939
}
@@ -43,46 +63,16 @@ public boolean equals(Object obj) {
4363
return true;
4464
}
4565

66+
@Override
4667
public int getIndex() {
4768
return index;
4869
}
4970

71+
@Override
5072
public int getIndex2() {
5173
return index2;
5274
}
5375

54-
private int globalIndex;
55-
private int distance;
56-
private int index;
57-
private int index2;
58-
59-
public ParseTreeNode(ParseTree tree) {
60-
this.tree = tree;
61-
}
62-
63-
public ParseTreeNode(ParseTree tree, int distance, int index, int index2) {
64-
this.tree = tree;
65-
this.distance = distance;
66-
this.index = index;
67-
this.index2 = index2;
68-
}
69-
70-
static void visit(final List<IParsedNode> nodes, final ParseTree tree, int level) {
71-
if (tree == null) {
72-
return;
73-
}
74-
75-
final int newLevel = level + 1;
76-
final int c = tree.getChildCount();
77-
int j = c * -1;
78-
for (int i = 0; i < c; i++) {
79-
final ParseTree child = tree.getChild(i);
80-
final ParseTreeNode node = new ParseTreeNode(child, newLevel, i + 1, j++);
81-
nodes.add(node);
82-
visit(nodes, child, newLevel);
83-
}
84-
}
85-
8676
@Override
8777
public IParsedNode[] getUses() {
8878
if (this.tree == null) {
@@ -124,6 +114,7 @@ public String getText() {
124114
return this.tree.getText();
125115
}
126116

117+
@Override
127118
public IParsedNode[] getChildren() {
128119
final List<IParsedNode> nodes = new ArrayList<>();
129120
if (this.tree == null) {
@@ -133,6 +124,7 @@ public IParsedNode[] getChildren() {
133124
return nodes.toArray(new IParsedNode[0]);
134125
}
135126

127+
@Override
136128
public IParsedNode[] getSiblings() {
137129
final List<IParsedNode> nodes = new ArrayList<>();
138130
if (this.tree == null || this.tree.getParent() == null) {
@@ -144,6 +136,7 @@ public IParsedNode[] getSiblings() {
144136

145137
}
146138

139+
@Override
147140
public IParsedNode[] getParents() {
148141
List<IParsedNode> nodes = new ArrayList<>();
149142
if (this.tree == null) {
@@ -160,7 +153,7 @@ public IParsedNode[] getParents() {
160153
return nodes.toArray(new IParsedNode[0]);
161154
}
162155

163-
// @Override
156+
@Override
164157
public IParsedNode getControlFlowParent() {
165158
if (this.tree == null) {
166159
return null;
@@ -218,7 +211,7 @@ private ParseTree getParent() {
218211
return parseTreeItem;
219212
}
220213

221-
private int assign(ParseTree tree, int level) {
214+
private int assign(final ParseTree tree, int level) {
222215
if (tree == null) {
223216
return level;
224217
}
@@ -231,4 +224,20 @@ private int assign(ParseTree tree, int level) {
231224
}
232225
return level;
233226
}
227+
228+
private static void visit(final List<IParsedNode> nodes, final ParseTree tree, int level) {
229+
if (tree == null) {
230+
return;
231+
}
232+
233+
final int newLevel = level + 1;
234+
final int c = tree.getChildCount();
235+
int j = c * -1;
236+
for (int i = 0; i < c; i++) {
237+
final ParseTree child = tree.getChild(i);
238+
final ParseTreeNode node = new ParseTreeNode(child, newLevel, i + 1, j++);
239+
nodes.add(node);
240+
visit(nodes, child, newLevel);
241+
}
242+
}
234243
}
Lines changed: 51 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,34 +1,62 @@
11
package org.sonar.plugins.sql;
22

3-
import java.io.IOException;
43
import java.io.InputStream;
54
import java.io.InputStreamReader;
65

6+
import javax.xml.parsers.DocumentBuilder;
7+
import javax.xml.parsers.DocumentBuilderFactory;
8+
79
import org.sonar.api.server.rule.RulesDefinition;
8-
import org.sonar.api.server.rule.RulesDefinitionXmlLoader;
10+
import org.sonar.api.utils.log.Logger;
11+
import org.sonar.api.utils.log.Loggers;
12+
import org.sonar.plugins.sql.sensors.XmlHelper;
13+
import org.w3c.dom.Document;
14+
import org.w3c.dom.Node;
15+
import org.w3c.dom.NodeList;
916

1017
public class CGRulesDefinition implements RulesDefinition {
1118

12-
private RulesDefinitionXmlLoader xmlProfileParser;
13-
14-
public CGRulesDefinition(RulesDefinitionXmlLoader xmlProfileParser) {
15-
this.xmlProfileParser = xmlProfileParser;
16-
}
17-
18-
@Override
19-
public void define(Context context) {
20-
try (InputStream stream = this.getClass().getResourceAsStream("/rules/cgsql-rules.xml")) {
21-
try (InputStreamReader reader = new InputStreamReader(stream)) {
22-
final NewRepository repo = context.createExternalRepository(Constants.TSQL_CG_ENGINEID,
23-
Constants.languageKey);
24-
xmlProfileParser.load(repo, reader);
25-
repo.rules().forEach(x -> x.setActivatedByDefault(true));
26-
repo.done();
27-
}
28-
} catch (IOException e) {
29-
e.printStackTrace();
30-
}
31-
32-
}
19+
private static final Logger LOGGER = Loggers.get(CGRulesDefinition.class);
20+
21+
@Override
22+
public void define(Context context) {
23+
final NewRepository repository = context.createExternalRepository(Constants.TSQL_CG_ENGINEID,
24+
Constants.languageKey);
25+
try (InputStream stream = this.getClass().getResourceAsStream("cgsql-rules.xml")) {
26+
try (InputStreamReader reader = new InputStreamReader(stream)) {
27+
28+
final DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
29+
final DocumentBuilder builder = factory.newDocumentBuilder();
30+
final Document xmlDoc = builder.parse(stream);
31+
32+
final NodeList nodes = xmlDoc.getElementsByTagName("rule");
33+
for (int i = 0; i < nodes.getLength(); i++) {
34+
try {
35+
final Node node = nodes.item(i);
36+
final String key = XmlHelper.getNodeValue(node, "key");
37+
final String name = XmlHelper.getNodeValue(node, "name");
38+
final String description = XmlHelper.getNodeValue(node, "description");
39+
40+
final String constantPerIssue = XmlHelper.getNodeValue(node,
41+
"debtRemediationFunctionCoefficient");
42+
final String severity = XmlHelper.getNodeValue(node, "severity");
43+
final String tags[] = XmlHelper.getNodeValue(node, "tag").split(",");
44+
45+
final NewRule rule = repository.createRule(key).setName(name)
46+
.setMarkdownDescription(description).setSeverity(severity).setTags(tags);
47+
rule.setDebtRemediationFunction(
48+
rule.debtRemediationFunctions().constantPerIssue(constantPerIssue));
49+
} catch (final Exception e) {
50+
LOGGER.warn(String.format("Unexpected error while registering rule: %s", i), e);
51+
52+
}
53+
}
54+
}
55+
} catch (Exception e) {
56+
LOGGER.warn("Unexpected error while registering rules", e);
57+
}
58+
repository.done();
59+
60+
}
3361

3462
}

src/sonar-sql-plugin/src/main/java/org/sonar/plugins/sql/Constants.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,6 @@ public final class Constants {
4747

4848
public static final String PLUGIN_SQL_SCA_MAX_FILE_SIZE = "sonar.sql.sca.maxfilesize";
4949

50-
public static final long PLUGIN_SQL_SCA_MAX_FILE_SIZE_DEFAULT = 1024 * 1024 * 2;
50+
public static final long PLUGIN_SQL_SCA_MAX_FILE_SIZE_DEFAULT = 1024 * 1024 * 2l;
5151

5252
}

0 commit comments

Comments
 (0)