@@ -0,0 +1,5 @@ | |||
sonar.projectKey=sample-multiline | |||
sonar.projectName=Sample Multiline | |||
sonar.projectVersion=1.0-SNAPSHOT | |||
sonar.sources=src/main/xoo | |||
sonar.language=xoo |
@@ -0,0 +1,16 @@ | |||
package sample; | |||
public class Sample { | |||
public Sample(int i) { | |||
int j {xoo-start-issue:0}= i++{xoo-end-issue:0}; | |||
} | |||
{xoo-start-issue:1}private String myMethod() { | |||
if (foo == bar) { | |||
return "hello"; | |||
} else { | |||
throw new IllegalStateException(); | |||
} | |||
}{xoo-end-issue:1} | |||
} |
@@ -6,15 +6,15 @@ | |||
package it.analysis; | |||
import com.sonar.orchestrator.Orchestrator; | |||
import com.sonar.orchestrator.build.BuildResult; | |||
import com.sonar.orchestrator.build.SonarRunner; | |||
import com.sonar.orchestrator.locator.FileLocation; | |||
import com.sonar.orchestrator.locator.ResourceLocation; | |||
import it.Category3Suite; | |||
import java.io.File; | |||
import java.io.FileNotFoundException; | |||
import java.io.InputStream; | |||
import org.apache.commons.io.FileUtils; | |||
import org.apache.commons.io.IOUtils; | |||
import org.json.simple.JSONArray; | |||
import org.json.simple.JSONObject; | |||
import org.junit.Before; | |||
import org.junit.ClassRule; | |||
import org.junit.Rule; | |||
@@ -23,6 +23,13 @@ import org.junit.rules.TemporaryFolder; | |||
import org.skyscreamer.jsonassert.JSONAssert; | |||
import util.ItUtils; | |||
import java.io.File; | |||
import java.io.FileNotFoundException; | |||
import java.io.IOException; | |||
import java.io.InputStream; | |||
import java.util.ArrayList; | |||
import java.util.List; | |||
import static org.assertj.core.api.Assertions.assertThat; | |||
public class IssueJsonReportTest { | |||
@@ -38,6 +45,69 @@ public class IssueJsonReportTest { | |||
orchestrator.resetData(); | |||
} | |||
@Test | |||
public void issue_line() throws IOException { | |||
orchestrator.getServer().restoreProfile(getResource("one-issue-per-line.xml")); | |||
orchestrator.getServer().provisionProject("sample", "xoo-sample"); | |||
orchestrator.getServer().associateProjectToQualityProfile("sample", "xoo", "one-issue-per-line"); | |||
File projectDir = ItUtils.projectDir("shared/xoo-sample"); | |||
SonarRunner runner = SonarRunner.create(projectDir, | |||
"sonar.analysis.mode", "issues", | |||
"sonar.verbose", "true", | |||
"sonar.report.export.path", "sonar-report.json"); | |||
BuildResult result = orchestrator.executeBuild(runner); | |||
assertThat(ItUtils.countIssuesInJsonReport(result, true)).isEqualTo(17); | |||
JSONObject obj = ItUtils.getJSONReport(result); | |||
JSONArray issues = (JSONArray) obj.get("issues"); | |||
for (Object issue : issues) { | |||
JSONObject jsonIssue = (JSONObject) issue; | |||
assertThat(jsonIssue.get("startLine")).isNotNull(); | |||
assertThat(jsonIssue.get("endLine")).isNotNull(); | |||
assertThat(jsonIssue.get("endLine")).isEqualTo(jsonIssue.get("startLine")); | |||
assertThat(jsonIssue.get("endOffset")).isNotNull(); | |||
assertThat(jsonIssue.get("startOffset")).isNotNull(); | |||
} | |||
List<Long> lineNumbers = new ArrayList<Long>(16); | |||
for (long i = 1L; i < 18; i++) { | |||
lineNumbers.add(i); | |||
} | |||
assertThat(issues).extracting("startLine").containsAll(lineNumbers); | |||
assertThat(issues).extracting("endLine").containsAll(lineNumbers); | |||
} | |||
@Test | |||
public void precise_issue_location() throws IOException { | |||
orchestrator.getServer().restoreProfile(getResource("multiline.xml")); | |||
orchestrator.getServer().provisionProject("sample-multiline", "xoo-sample"); | |||
orchestrator.getServer().associateProjectToQualityProfile("sample-multiline", "xoo", "multiline"); | |||
File projectDir = ItUtils.projectDir("shared/xoo-precise-issues"); | |||
SonarRunner runner = SonarRunner.create(projectDir, | |||
"sonar.analysis.mode", "issues", | |||
"sonar.verbose", "true", | |||
"sonar.report.export.path", "sonar-report.json"); | |||
BuildResult result = orchestrator.executeBuild(runner); | |||
assertThat(ItUtils.countIssuesInJsonReport(result, true)).isEqualTo(2); | |||
JSONObject obj = ItUtils.getJSONReport(result); | |||
JSONArray issues = (JSONArray) obj.get("issues"); | |||
for (Object i : issues) { | |||
JSONObject issue = (JSONObject) i; | |||
assertThat(issue.get("startLine")).isIn(6L, 9L); | |||
assertThat(issue.get("line")).isIn(6L, 9L); | |||
assertThat(issue.get("endLine")).isIn(6L, 15L); | |||
assertThat(issue.get("startOffset")).isIn(27L, 20L); | |||
assertThat(issue.get("endOffset")).isIn(32L, 2L); | |||
} | |||
} | |||
@Test | |||
public void test_json_report_no_server_analysis() throws Exception { | |||
orchestrator.getServer().restoreProfile(getResource("one-issue-per-line.xml")); |
@@ -116,11 +116,11 @@ public class IssuesModeTest { | |||
assertThat(i.status()).isEqualTo("OPEN"); | |||
} | |||
assertThat(serverIssues).hasSize(17); | |||
// change quality profile | |||
restoreProfile("with-many-rules.xml"); | |||
orchestrator.getServer().associateProjectToQualityProfile("sample", "xoo", "with-many-rules"); | |||
// do it again, scanning nothing (all files should be unchanged) | |||
runner = configureRunnerIssues("shared/xoo-sample", | |||
"sonar.verbose", "true"); | |||
@@ -129,7 +129,7 @@ public class IssuesModeTest { | |||
assertThat(result.getLogs()).contains("'One Issue Per Line' skipped because there is no related file in current project"); | |||
ItUtils.assertIssuesInJsonReport(result, 0, 0, 17); | |||
} | |||
// SONAR-6931 | |||
@Test | |||
public void only_scan_changed_files_transitions() throws IOException { | |||
@@ -144,7 +144,7 @@ public class IssuesModeTest { | |||
assertThat(i.status()).isEqualTo("OPEN"); | |||
} | |||
assertThat(serverIssues).hasSize(17); | |||
// resolve 2 issues | |||
IssueClient issueClient = orchestrator.getServer().wsClient("admin", "admin").issueClient(); | |||
issueClient.doTransition(serverIssues.get(0).key(), "wontfix"); | |||
@@ -158,7 +158,7 @@ public class IssuesModeTest { | |||
assertThat(result.getLogs()).contains("'One Issue Per Line' skipped because there is no related file in current project"); | |||
ItUtils.assertIssuesInJsonReport(result, 0, 0, 15); | |||
} | |||
// SONAR-6931 | |||
@Test | |||
public void only_scan_changed_files_on_change() throws IOException { | |||
@@ -168,11 +168,11 @@ public class IssuesModeTest { | |||
SonarRunner runner = configureRunner("shared/xoo-sample", "sonar.verbose", "true"); | |||
BuildResult result = orchestrator.executeBuild(runner); | |||
// change QP | |||
restoreProfile("with-many-rules.xml"); | |||
orchestrator.getServer().associateProjectToQualityProfile("sample", "xoo", "with-many-rules"); | |||
// now change file hash in a temporary location | |||
File tmpProjectDir = temp.newFolder(); | |||
FileUtils.copyDirectory(ItUtils.projectDir("shared/xoo-sample"), tmpProjectDir); | |||
@@ -192,7 +192,7 @@ public class IssuesModeTest { | |||
assertThat(result.getLogs()).doesNotContain("'One Issue Per Line' skipped because there is no related file in current project"); | |||
ItUtils.assertIssuesInJsonReport(result, 3, 0, 17); | |||
} | |||
@Test | |||
public void non_associated_mode() throws IOException { | |||
restoreProfile("one-issue-per-line.xml"); | |||
@@ -299,8 +299,8 @@ public class IssuesModeTest { | |||
orchestrator.executeBuild(runner); | |||
// Second run issues mode | |||
runner = configureRunnerIssues("shared/xoo-sample", | |||
"sonar.report.export.path", "sonar-report.json", | |||
runner = configureRunnerIssues("shared/xoo-sample", | |||
"sonar.report.export.path", "sonar-report.json", | |||
"sonar.scanAllFiles", "true"); | |||
result = orchestrator.executeBuild(runner); | |||
@@ -331,7 +331,7 @@ public class IssuesModeTest { | |||
restoreProfile("/one-issue-per-line.xml"); | |||
// Second issues mode | |||
runner = configureRunnerIssues("shared/xoo-sample", | |||
runner = configureRunnerIssues("shared/xoo-sample", | |||
"sonar.report.export.path", "sonar-report.json", | |||
"sonar.scanAllFiles", "true"); | |||
result = orchestrator.executeBuild(runner); |
@@ -0,0 +1,12 @@ | |||
<?xml version="1.0" encoding="UTF-8"?><!-- Generated by Sonar --> | |||
<profile> | |||
<name>multiline</name> | |||
<language>xoo</language> | |||
<rules> | |||
<rule> | |||
<repositoryKey>xoo</repositoryKey> | |||
<key>MultilineIssue</key> | |||
<priority>MAJOR</priority> | |||
</rule> | |||
</rules> | |||
</profile> |
@@ -1,174 +1,212 @@ | |||
{ | |||
"version": "<SONAR_VERSION>", | |||
"components": [ | |||
{ | |||
"key": "sample" | |||
}, | |||
{ | |||
"key": "sample:src/main/xoo/sample/Sample.xoo", | |||
"moduleKey": "sample", | |||
"path": "src/main/xoo/sample/Sample.xoo", | |||
"status": "ADDED" | |||
}, | |||
{ | |||
"key": "sample:src/main/xoo/sample", | |||
"moduleKey": "sample", | |||
"path": "src/main/xoo/sample" | |||
} | |||
], | |||
"issues": [ | |||
{ | |||
"key": "<ISSUE_KEY>", | |||
"component": "sample:src/main/xoo/sample/Sample.xoo", | |||
"line": 6, | |||
"creationDate": "2013-05-02T00:00:00+0200", | |||
"endLine": 2, | |||
"endOffset": 0, | |||
"isNew": true, | |||
"key": "<ISSUE_KEY>", | |||
"message": "This issue is generated on each line", | |||
"severity": "MAJOR", | |||
"rule": "xoo:OneIssuePerLine", | |||
"status": "OPEN", | |||
"isNew": true, | |||
"creationDate": "2013-05-02T00:00:00+0200" | |||
"severity": "MAJOR", | |||
"startLine": 2, | |||
"startOffset": 0, | |||
"status": "OPEN" | |||
}, | |||
{ | |||
"key": "<ISSUE_KEY>", | |||
"component": "sample:src/main/xoo/sample/Sample.xoo", | |||
"line": 5, | |||
"creationDate": "2013-05-02T00:00:00+0200", | |||
"endLine": 6, | |||
"endOffset": 14, | |||
"isNew": true, | |||
"key": "<ISSUE_KEY>", | |||
"message": "This issue is generated on each line", | |||
"severity": "MAJOR", | |||
"rule": "xoo:OneIssuePerLine", | |||
"status": "OPEN", | |||
"isNew": true, | |||
"creationDate": "2013-05-02T00:00:00+0200" | |||
"severity": "MAJOR", | |||
"startLine": 6, | |||
"startOffset": 0, | |||
"status": "OPEN" | |||
}, | |||
{ | |||
"key": "<ISSUE_KEY>", | |||
"component": "sample:src/main/xoo/sample/Sample.xoo", | |||
"line": 13, | |||
"creationDate": "2013-05-02T00:00:00+0200", | |||
"endLine": 1, | |||
"endOffset": 15, | |||
"isNew": true, | |||
"key": "<ISSUE_KEY>", | |||
"message": "This issue is generated on each line", | |||
"severity": "MAJOR", | |||
"rule": "xoo:OneIssuePerLine", | |||
"status": "OPEN", | |||
"isNew": true, | |||
"creationDate": "2013-05-02T00:00:00+0200" | |||
"severity": "MAJOR", | |||
"startLine": 1, | |||
"startOffset": 0, | |||
"status": "OPEN" | |||
}, | |||
{ | |||
"key": "<ISSUE_KEY>", | |||
"component": "sample:src/main/xoo/sample/Sample.xoo", | |||
"line": 1, | |||
"creationDate": "2013-05-02T00:00:00+0200", | |||
"endLine": 5, | |||
"endOffset": 23, | |||
"isNew": true, | |||
"key": "<ISSUE_KEY>", | |||
"message": "This issue is generated on each line", | |||
"severity": "MAJOR", | |||
"rule": "xoo:OneIssuePerLine", | |||
"status": "OPEN", | |||
"isNew": true, | |||
"creationDate": "2013-05-02T00:00:00+0200" | |||
"severity": "MAJOR", | |||
"startLine": 5, | |||
"startOffset": 0, | |||
"status": "OPEN" | |||
}, | |||
{ | |||
"key": "<ISSUE_KEY>", | |||
"component": "sample:src/main/xoo/sample/Sample.xoo", | |||
"line": 3, | |||
"creationDate": "2013-05-02T00:00:00+0200", | |||
"endLine": 8, | |||
"endOffset": 1, | |||
"isNew": true, | |||
"key": "<ISSUE_KEY>", | |||
"message": "This issue is generated on each line", | |||
"severity": "MAJOR", | |||
"rule": "xoo:OneIssuePerLine", | |||
"status": "OPEN", | |||
"isNew": true, | |||
"creationDate": "2013-05-02T00:00:00+0200" | |||
"severity": "MAJOR", | |||
"startLine": 8, | |||
"startOffset": 0, | |||
"status": "OPEN" | |||
}, | |||
{ | |||
"key": "<ISSUE_KEY>", | |||
"component": "sample:src/main/xoo/sample/Sample.xoo", | |||
"line": 4, | |||
"creationDate": "2013-05-02T00:00:00+0200", | |||
"endLine": 9, | |||
"endOffset": 28, | |||
"isNew": true, | |||
"key": "<ISSUE_KEY>", | |||
"message": "This issue is generated on each line", | |||
"severity": "MAJOR", | |||
"rule": "xoo:OneIssuePerLine", | |||
"status": "OPEN", | |||
"isNew": true, | |||
"creationDate": "2013-05-02T00:00:00+0200" | |||
"severity": "MAJOR", | |||
"startLine": 9, | |||
"startOffset": 0, | |||
"status": "OPEN" | |||
}, | |||
{ | |||
"key": "<ISSUE_KEY>", | |||
"component": "sample:src/main/xoo/sample/Sample.xoo", | |||
"line": 12, | |||
"creationDate": "2013-05-02T00:00:00+0200", | |||
"endLine": 7, | |||
"endOffset": 2, | |||
"isNew": true, | |||
"key": "<ISSUE_KEY>", | |||
"message": "This issue is generated on each line", | |||
"severity": "MAJOR", | |||
"rule": "xoo:OneIssuePerLine", | |||
"status": "OPEN", | |||
"isNew": true, | |||
"creationDate": "2013-05-02T00:00:00+0200" | |||
"severity": "MAJOR", | |||
"startLine": 7, | |||
"startOffset": 0, | |||
"status": "OPEN" | |||
}, | |||
{ | |||
"key": "<ISSUE_KEY>", | |||
"component": "sample:src/main/xoo/sample/Sample.xoo", | |||
"line": 10, | |||
"creationDate": "2013-05-02T00:00:00+0200", | |||
"endLine": 4, | |||
"endOffset": 1, | |||
"isNew": true, | |||
"key": "<ISSUE_KEY>", | |||
"message": "This issue is generated on each line", | |||
"severity": "MAJOR", | |||
"rule": "xoo:OneIssuePerLine", | |||
"status": "OPEN", | |||
"isNew": true, | |||
"creationDate": "2013-05-02T00:00:00+0200" | |||
"severity": "MAJOR", | |||
"startLine": 4, | |||
"startOffset": 0, | |||
"status": "OPEN" | |||
}, | |||
{ | |||
"key": "<ISSUE_KEY>", | |||
"component": "sample:src/main/xoo/sample/Sample.xoo", | |||
"line": 2, | |||
"creationDate": "2013-05-02T00:00:00+0200", | |||
"endLine": 11, | |||
"endOffset": 2, | |||
"isNew": true, | |||
"key": "<ISSUE_KEY>", | |||
"message": "This issue is generated on each line", | |||
"severity": "MAJOR", | |||
"rule": "xoo:OneIssuePerLine", | |||
"status": "OPEN", | |||
"isNew": true, | |||
"creationDate": "2013-05-02T00:00:00+0200" | |||
"severity": "MAJOR", | |||
"startLine": 11, | |||
"startOffset": 0, | |||
"status": "OPEN" | |||
}, | |||
{ | |||
"key": "<ISSUE_KEY>", | |||
"component": "sample:src/main/xoo/sample/Sample.xoo", | |||
"line": 9, | |||
"creationDate": "2013-05-02T00:00:00+0200", | |||
"endLine": 3, | |||
"endOffset": 21, | |||
"isNew": true, | |||
"key": "<ISSUE_KEY>", | |||
"message": "This issue is generated on each line", | |||
"severity": "MAJOR", | |||
"rule": "xoo:OneIssuePerLine", | |||
"status": "OPEN", | |||
"isNew": true, | |||
"creationDate": "2013-05-02T00:00:00+0200" | |||
"severity": "MAJOR", | |||
"startLine": 3, | |||
"startOffset": 0, | |||
"status": "OPEN" | |||
}, | |||
{ | |||
"key": "<ISSUE_KEY>", | |||
"component": "sample:src/main/xoo/sample/Sample.xoo", | |||
"line": 11, | |||
"creationDate": "2013-05-02T00:00:00+0200", | |||
"endLine": 13, | |||
"endOffset": 0, | |||
"isNew": true, | |||
"key": "<ISSUE_KEY>", | |||
"message": "This issue is generated on each line", | |||
"severity": "MAJOR", | |||
"rule": "xoo:OneIssuePerLine", | |||
"status": "OPEN", | |||
"isNew": true, | |||
"creationDate": "2013-05-02T00:00:00+0200" | |||
"severity": "MAJOR", | |||
"startLine": 13, | |||
"startOffset": 0, | |||
"status": "OPEN" | |||
}, | |||
{ | |||
"key": "<ISSUE_KEY>", | |||
"component": "sample:src/main/xoo/sample/Sample.xoo", | |||
"line": 7, | |||
"creationDate": "2013-05-02T00:00:00+0200", | |||
"endLine": 12, | |||
"endOffset": 1, | |||
"isNew": true, | |||
"key": "<ISSUE_KEY>", | |||
"message": "This issue is generated on each line", | |||
"severity": "MAJOR", | |||
"rule": "xoo:OneIssuePerLine", | |||
"status": "OPEN", | |||
"isNew": true, | |||
"creationDate": "2013-05-02T00:00:00+0200" | |||
"severity": "MAJOR", | |||
"startLine": 12, | |||
"startOffset": 0, | |||
"status": "OPEN" | |||
}, | |||
{ | |||
"key": "<ISSUE_KEY>", | |||
"component": "sample:src/main/xoo/sample/Sample.xoo", | |||
"line": 8, | |||
"creationDate": "2013-05-02T00:00:00+0200", | |||
"endLine": 10, | |||
"endOffset": 17, | |||
"isNew": true, | |||
"key": "<ISSUE_KEY>", | |||
"message": "This issue is generated on each line", | |||
"severity": "MAJOR", | |||
"rule": "xoo:OneIssuePerLine", | |||
"status": "OPEN", | |||
"isNew": true, | |||
"creationDate": "2013-05-02T00:00:00+0200" | |||
} | |||
], | |||
"components": [ | |||
{ | |||
"key": "sample" | |||
}, | |||
{ | |||
"key": "sample:src/main/xoo/sample", | |||
"path": "src/main/xoo/sample", | |||
"moduleKey": "sample" | |||
}, | |||
{ | |||
"key": "sample:src/main/xoo/sample/Sample.xoo", | |||
"path": "src/main/xoo/sample/Sample.xoo", | |||
"moduleKey": "sample", | |||
"status": "ADDED" | |||
"severity": "MAJOR", | |||
"startLine": 10, | |||
"startOffset": 0, | |||
"status": "OPEN" | |||
} | |||
], | |||
"rules": [ | |||
{ | |||
"key": "xoo:OneIssuePerLine", | |||
"rule": "OneIssuePerLine", | |||
"name": "One Issue Per Line", | |||
"repository": "xoo", | |||
"name": "One Issue Per Line" | |||
"rule": "OneIssuePerLine" | |||
} | |||
], | |||
"users": [ ] | |||
"users": [], | |||
"version": "<SONAR_VERSION>" | |||
} |
@@ -1,196 +1,255 @@ | |||
{ | |||
"version": "<SONAR_VERSION>", | |||
"components": [ | |||
{ | |||
"key": "sample:mybranch" | |||
}, | |||
{ | |||
"key": "sample:mybranch:src/main/xoo/sample/Sample.xoo", | |||
"moduleKey": "sample:mybranch", | |||
"path": "src/main/xoo/sample/Sample.xoo", | |||
"status": "CHANGED" | |||
}, | |||
{ | |||
"key": "sample:mybranch:src/main/xoo/sample", | |||
"moduleKey": "sample:mybranch", | |||
"path": "src/main/xoo/sample" | |||
} | |||
], | |||
"issues": [ | |||
{ | |||
"key": "<ISSUE_KEY>", | |||
"component": "sample:mybranch:src/main/xoo/sample/Sample.xoo", | |||
"line": 2, | |||
"message": "This issue is generated on each line", | |||
"severity": "MAJOR", | |||
"rule": "xoo:OneIssuePerLine", | |||
"status": "OPEN", | |||
"creationDate": "2013-05-01T00:00:00+0200", | |||
"endLine": 1, | |||
"endOffset": 15, | |||
"isNew": false, | |||
"creationDate": "2013-05-01T00:00:00+0200" | |||
}, | |||
{ | |||
"key": "<ISSUE_KEY>", | |||
"component": "sample:mybranch:src/main/xoo/sample/Sample.xoo", | |||
"line": 10, | |||
"line": 1, | |||
"message": "This issue is generated on each line", | |||
"severity": "MAJOR", | |||
"rule": "xoo:OneIssuePerLine", | |||
"status": "OPEN", | |||
"isNew": false, | |||
"creationDate": "2013-05-01T00:00:00+0200" | |||
"severity": "MAJOR", | |||
"startLine": 1, | |||
"startOffset": 0, | |||
"status": "OPEN" | |||
}, | |||
{ | |||
"key": "<ISSUE_KEY>", | |||
"component": "sample:mybranch:src/main/xoo/sample/Sample.xoo", | |||
"line": 13, | |||
"creationDate": "2013-05-01T00:00:00+0200", | |||
"endLine": 2, | |||
"endOffset": 0, | |||
"isNew": false, | |||
"key": "<ISSUE_KEY>", | |||
"line": 2, | |||
"message": "This issue is generated on each line", | |||
"severity": "MAJOR", | |||
"rule": "xoo:OneIssuePerLine", | |||
"status": "OPEN", | |||
"isNew": false, | |||
"creationDate": "2013-05-01T00:00:00+0200" | |||
"severity": "MAJOR", | |||
"startLine": 2, | |||
"startOffset": 0, | |||
"status": "OPEN" | |||
}, | |||
{ | |||
"key": "<ISSUE_KEY>", | |||
"component": "sample:mybranch:src/main/xoo/sample/Sample.xoo", | |||
"line": 15, | |||
"creationDate": "2013-05-01T00:00:00+0200", | |||
"endLine": 3, | |||
"endOffset": 21, | |||
"isNew": false, | |||
"key": "<ISSUE_KEY>", | |||
"line": 3, | |||
"message": "This issue is generated on each line", | |||
"severity": "MAJOR", | |||
"rule": "xoo:OneIssuePerLine", | |||
"status": "OPEN", | |||
"isNew": false, | |||
"creationDate": "2013-05-01T00:00:00+0200" | |||
"severity": "MAJOR", | |||
"startLine": 3, | |||
"startOffset": 0, | |||
"status": "OPEN" | |||
}, | |||
{ | |||
"key": "<ISSUE_KEY>", | |||
"component": "sample:mybranch:src/main/xoo/sample/Sample.xoo", | |||
"creationDate": "2013-05-01T00:00:00+0200", | |||
"endLine": 4, | |||
"endOffset": 1, | |||
"isNew": false, | |||
"key": "<ISSUE_KEY>", | |||
"line": 4, | |||
"message": "This issue is generated on each line", | |||
"severity": "MAJOR", | |||
"rule": "xoo:OneIssuePerLine", | |||
"status": "OPEN", | |||
"isNew": false, | |||
"creationDate": "2013-05-01T00:00:00+0200" | |||
"severity": "MAJOR", | |||
"startLine": 4, | |||
"startOffset": 0, | |||
"status": "OPEN" | |||
}, | |||
{ | |||
"key": "<ISSUE_KEY>", | |||
"component": "sample:mybranch:src/main/xoo/sample/Sample.xoo", | |||
"line": 3, | |||
"creationDate": "2013-05-01T00:00:00+0200", | |||
"endLine": 5, | |||
"endOffset": 23, | |||
"isNew": false, | |||
"key": "<ISSUE_KEY>", | |||
"line": 5, | |||
"message": "This issue is generated on each line", | |||
"severity": "MAJOR", | |||
"rule": "xoo:OneIssuePerLine", | |||
"status": "OPEN", | |||
"isNew": false, | |||
"creationDate": "2013-05-01T00:00:00+0200" | |||
"severity": "MAJOR", | |||
"startLine": 5, | |||
"startOffset": 0, | |||
"status": "OPEN" | |||
}, | |||
{ | |||
"key": "<ISSUE_KEY>", | |||
"component": "sample:mybranch:src/main/xoo/sample/Sample.xoo", | |||
"line": 12, | |||
"creationDate": "2013-05-01T00:00:00+0200", | |||
"endLine": 6, | |||
"endOffset": 14, | |||
"isNew": false, | |||
"key": "<ISSUE_KEY>", | |||
"line": 6, | |||
"message": "This issue is generated on each line", | |||
"severity": "MAJOR", | |||
"rule": "xoo:OneIssuePerLine", | |||
"status": "OPEN", | |||
"isNew": false, | |||
"creationDate": "2013-05-01T00:00:00+0200" | |||
"severity": "MAJOR", | |||
"startLine": 6, | |||
"startOffset": 0, | |||
"status": "OPEN" | |||
}, | |||
{ | |||
"key": "<ISSUE_KEY>", | |||
"component": "sample:mybranch:src/main/xoo/sample/Sample.xoo", | |||
"line": 11, | |||
"creationDate": "2013-05-01T00:00:00+0200", | |||
"endLine": 8, | |||
"endOffset": 2, | |||
"isNew": false, | |||
"key": "<ISSUE_KEY>", | |||
"line": 8, | |||
"message": "This issue is generated on each line", | |||
"severity": "MAJOR", | |||
"rule": "xoo:OneIssuePerLine", | |||
"status": "OPEN", | |||
"isNew": true, | |||
"creationDate": "2013-05-02T00:00:00+0200" | |||
"severity": "MAJOR", | |||
"startLine": 8, | |||
"startOffset": 0, | |||
"status": "OPEN" | |||
}, | |||
{ | |||
"key": "<ISSUE_KEY>", | |||
"component": "sample:mybranch:src/main/xoo/sample/Sample.xoo", | |||
"line": 5, | |||
"creationDate": "2013-05-01T00:00:00+0200", | |||
"endLine": 9, | |||
"endOffset": 1, | |||
"isNew": false, | |||
"key": "<ISSUE_KEY>", | |||
"line": 9, | |||
"message": "This issue is generated on each line", | |||
"severity": "MAJOR", | |||
"rule": "xoo:OneIssuePerLine", | |||
"status": "OPEN", | |||
"isNew": false, | |||
"creationDate": "2013-05-01T00:00:00+0200" | |||
"severity": "MAJOR", | |||
"startLine": 9, | |||
"startOffset": 0, | |||
"status": "OPEN" | |||
}, | |||
{ | |||
"key": "<ISSUE_KEY>", | |||
"component": "sample:mybranch:src/main/xoo/sample/Sample.xoo", | |||
"line": 7, | |||
"creationDate": "2013-05-01T00:00:00+0200", | |||
"endLine": 10, | |||
"endOffset": 28, | |||
"isNew": false, | |||
"key": "<ISSUE_KEY>", | |||
"line": 10, | |||
"message": "This issue is generated on each line", | |||
"severity": "MAJOR", | |||
"rule": "xoo:OneIssuePerLine", | |||
"status": "OPEN", | |||
"isNew": true, | |||
"creationDate": "2013-05-02T00:00:00+0200" | |||
"severity": "MAJOR", | |||
"startLine": 10, | |||
"startOffset": 0, | |||
"status": "OPEN" | |||
}, | |||
{ | |||
"key": "<ISSUE_KEY>", | |||
"component": "sample:mybranch:src/main/xoo/sample/Sample.xoo", | |||
"line": 9, | |||
"creationDate": "2013-05-01T00:00:00+0200", | |||
"endLine": 12, | |||
"endOffset": 17, | |||
"isNew": false, | |||
"key": "<ISSUE_KEY>", | |||
"line": 12, | |||
"message": "This issue is generated on each line", | |||
"severity": "MAJOR", | |||
"rule": "xoo:OneIssuePerLine", | |||
"status": "OPEN", | |||
"isNew": false, | |||
"creationDate": "2013-05-01T00:00:00+0200" | |||
"severity": "MAJOR", | |||
"startLine": 12, | |||
"startOffset": 0, | |||
"status": "OPEN" | |||
}, | |||
{ | |||
"key": "<ISSUE_KEY>", | |||
"component": "sample:mybranch:src/main/xoo/sample/Sample.xoo", | |||
"line": 6, | |||
"creationDate": "2013-05-01T00:00:00+0200", | |||
"endLine": 13, | |||
"endOffset": 2, | |||
"isNew": false, | |||
"key": "<ISSUE_KEY>", | |||
"line": 13, | |||
"message": "This issue is generated on each line", | |||
"severity": "MAJOR", | |||
"rule": "xoo:OneIssuePerLine", | |||
"status": "OPEN", | |||
"isNew": false, | |||
"creationDate": "2013-05-01T00:00:00+0200" | |||
"severity": "MAJOR", | |||
"startLine": 13, | |||
"startOffset": 0, | |||
"status": "OPEN" | |||
}, | |||
{ | |||
"key": "<ISSUE_KEY>", | |||
"component": "sample:mybranch:src/main/xoo/sample/Sample.xoo", | |||
"line": 8, | |||
"creationDate": "2013-05-01T00:00:00+0200", | |||
"endLine": 14, | |||
"endOffset": 1, | |||
"isNew": false, | |||
"key": "<ISSUE_KEY>", | |||
"line": 14, | |||
"message": "This issue is generated on each line", | |||
"severity": "MAJOR", | |||
"rule": "xoo:OneIssuePerLine", | |||
"status": "OPEN", | |||
"isNew": false, | |||
"creationDate": "2013-05-01T00:00:00+0200" | |||
"severity": "MAJOR", | |||
"startLine": 14, | |||
"startOffset": 0, | |||
"status": "OPEN" | |||
}, | |||
{ | |||
"key": "<ISSUE_KEY>", | |||
"component": "sample:mybranch:src/main/xoo/sample/Sample.xoo", | |||
"line": 1, | |||
"creationDate": "2013-05-01T00:00:00+0200", | |||
"endLine": 15, | |||
"endOffset": 0, | |||
"isNew": false, | |||
"key": "<ISSUE_KEY>", | |||
"line": 15, | |||
"message": "This issue is generated on each line", | |||
"severity": "MAJOR", | |||
"rule": "xoo:OneIssuePerLine", | |||
"status": "OPEN", | |||
"isNew": false, | |||
"creationDate": "2013-05-01T00:00:00+0200" | |||
"severity": "MAJOR", | |||
"startLine": 15, | |||
"startOffset": 0, | |||
"status": "OPEN" | |||
}, | |||
{ | |||
"key": "<ISSUE_KEY>", | |||
"component": "sample:mybranch:src/main/xoo/sample/Sample.xoo", | |||
"line": 14, | |||
"creationDate": "2013-05-02T00:00:00+0200", | |||
"endLine": 11, | |||
"endOffset": 28, | |||
"isNew": true, | |||
"key": "<ISSUE_KEY>", | |||
"line": 11, | |||
"message": "This issue is generated on each line", | |||
"severity": "MAJOR", | |||
"rule": "xoo:OneIssuePerLine", | |||
"status": "OPEN", | |||
"isNew": false, | |||
"creationDate": "2013-05-01T00:00:00+0200" | |||
} | |||
], | |||
"components": [ | |||
{ | |||
"key": "sample:mybranch" | |||
}, | |||
{ | |||
"key": "sample:mybranch:src/main/xoo/sample", | |||
"path": "src/main/xoo/sample", | |||
"moduleKey": "sample:mybranch" | |||
"severity": "MAJOR", | |||
"startLine": 11, | |||
"startOffset": 0, | |||
"status": "OPEN" | |||
}, | |||
{ | |||
"key": "sample:mybranch:src/main/xoo/sample/Sample.xoo", | |||
"path": "src/main/xoo/sample/Sample.xoo", | |||
"moduleKey": "sample:mybranch", | |||
"status": "CHANGED" | |||
"component": "sample:mybranch:src/main/xoo/sample/Sample.xoo", | |||
"creationDate": "2013-05-02T00:00:00+0200", | |||
"endLine": 7, | |||
"endOffset": 28, | |||
"isNew": true, | |||
"key": "<ISSUE_KEY>", | |||
"line": 7, | |||
"message": "This issue is generated on each line", | |||
"rule": "xoo:OneIssuePerLine", | |||
"severity": "MAJOR", | |||
"startLine": 7, | |||
"startOffset": 0, | |||
"status": "OPEN" | |||
} | |||
], | |||
"rules": [ | |||
{ | |||
"key": "xoo:OneIssuePerLine", | |||
"rule": "OneIssuePerLine", | |||
"name": "One Issue Per Line", | |||
"repository": "xoo", | |||
"name": "One Issue Per Line" | |||
"rule": "OneIssuePerLine" | |||
} | |||
], | |||
"users": [ ] | |||
"users": [], | |||
"version": "<SONAR_VERSION>" | |||
} |
@@ -1,195 +1,255 @@ | |||
{ | |||
"version": "<SONAR_VERSION>", | |||
"issues": [ | |||
{ | |||
"key": "<ISSUE_KEY>", | |||
"component": "sample:src/main/xoo/sample/Sample.xoo", | |||
"line": 6, | |||
"message": "This issue is generated on each line", | |||
"severity": "MAJOR", | |||
"rule": "xoo:OneIssuePerLine", | |||
"status": "OPEN", | |||
"isNew": false, | |||
"creationDate": "2013-05-01T00:00:00+0200" | |||
}, | |||
{ | |||
"key": "<ISSUE_KEY>", | |||
"component": "sample:src/main/xoo/sample/Sample.xoo", | |||
"line": 5, | |||
"message": "This issue is generated on each line", | |||
"severity": "MAJOR", | |||
"rule": "xoo:OneIssuePerLine", | |||
"status": "OPEN", | |||
"isNew": false, | |||
"creationDate": "2013-05-01T00:00:00+0200" | |||
}, | |||
{ | |||
"key": "<ISSUE_KEY>", | |||
"component": "sample:src/main/xoo/sample/Sample.xoo", | |||
"line": 13, | |||
"message": "This issue is generated on each line", | |||
"severity": "MAJOR", | |||
"rule": "xoo:OneIssuePerLine", | |||
"status": "OPEN", | |||
"isNew": false, | |||
"creationDate": "2013-05-01T00:00:00+0200" | |||
}, | |||
{ | |||
"key": "<ISSUE_KEY>", | |||
"component": "sample:src/main/xoo/sample/Sample.xoo", | |||
"line": 1, | |||
"message": "This issue is generated on each line", | |||
"severity": "MAJOR", | |||
"rule": "xoo:OneIssuePerLine", | |||
"status": "OPEN", | |||
"isNew": false, | |||
"creationDate": "2013-05-01T00:00:00+0200" | |||
}, | |||
{ | |||
"key": "<ISSUE_KEY>", | |||
"component": "sample:src/main/xoo/sample/Sample.xoo", | |||
"line": 3, | |||
"message": "This issue is generated on each line", | |||
"severity": "MAJOR", | |||
"rule": "xoo:OneIssuePerLine", | |||
"status": "OPEN", | |||
"isNew": false, | |||
"creationDate": "2013-05-01T00:00:00+0200" | |||
}, | |||
{ | |||
"key": "<ISSUE_KEY>", | |||
"component": "sample:src/main/xoo/sample/Sample.xoo", | |||
"line": 4, | |||
"message": "This issue is generated on each line", | |||
"severity": "MAJOR", | |||
"rule": "xoo:OneIssuePerLine", | |||
"status": "OPEN", | |||
"isNew": false, | |||
"creationDate": "2013-05-01T00:00:00+0200" | |||
}, | |||
{ | |||
"key": "<ISSUE_KEY>", | |||
"component": "sample:src/main/xoo/sample/Sample.xoo", | |||
"line": 12, | |||
"message": "This issue is generated on each line", | |||
"severity": "MAJOR", | |||
"rule": "xoo:OneIssuePerLine", | |||
"status": "OPEN", | |||
"isNew": false, | |||
"creationDate": "2013-05-01T00:00:00+0200" | |||
}, | |||
{ | |||
"key": "<ISSUE_KEY>", | |||
"component": "sample:src/main/xoo/sample/Sample.xoo", | |||
"line": 10, | |||
"message": "This issue is generated on each line", | |||
"severity": "MAJOR", | |||
"rule": "xoo:OneIssuePerLine", | |||
"status": "OPEN", | |||
"isNew": false, | |||
"creationDate": "2013-05-01T00:00:00+0200" | |||
}, | |||
{ | |||
"key": "<ISSUE_KEY>", | |||
"component": "sample:src/main/xoo/sample/Sample.xoo", | |||
"line": 2, | |||
"message": "This issue is generated on each line", | |||
"severity": "MAJOR", | |||
"rule": "xoo:OneIssuePerLine", | |||
"status": "OPEN", | |||
"isNew": false, | |||
"creationDate": "2013-05-01T00:00:00+0200" | |||
}, | |||
{ | |||
"key": "<ISSUE_KEY>", | |||
"component": "sample:src/main/xoo/sample/Sample.xoo", | |||
"line": 9, | |||
"message": "This issue is generated on each line", | |||
"severity": "MAJOR", | |||
"rule": "xoo:OneIssuePerLine", | |||
"status": "OPEN", | |||
"isNew": false, | |||
"creationDate": "2013-05-01T00:00:00+0200" | |||
}, | |||
{ | |||
"key": "<ISSUE_KEY>", | |||
"component": "sample:src/main/xoo/sample/Sample.xoo", | |||
"line": 11, | |||
"message": "This issue is generated on each line", | |||
"severity": "MAJOR", | |||
"rule": "xoo:OneIssuePerLine", | |||
"status": "OPEN", | |||
"isNew": true, | |||
"creationDate": "2013-05-02T00:00:00+0200" | |||
}, | |||
{ | |||
"key": "<ISSUE_KEY>", | |||
"component": "sample:src/main/xoo/sample/Sample.xoo", | |||
"line": 7, | |||
"message": "This issue is generated on each line", | |||
"severity": "MAJOR", | |||
"rule": "xoo:OneIssuePerLine", | |||
"status": "OPEN", | |||
"isNew": true, | |||
"creationDate": "2013-05-02T00:00:00+0200" | |||
}, | |||
{ | |||
"key": "<ISSUE_KEY>", | |||
"component": "sample:src/main/xoo/sample/Sample.xoo", | |||
"line": 8, | |||
"message": "This issue is generated on each line", | |||
"severity": "MAJOR", | |||
"rule": "xoo:OneIssuePerLine", | |||
"status": "OPEN", | |||
"isNew": false, | |||
"creationDate": "2013-05-01T00:00:00+0200" | |||
}, | |||
{ | |||
"key": "<ISSUE_KEY>", | |||
"component": "sample:src/main/xoo/sample/Sample.xoo", | |||
"line": 14, | |||
"message": "This issue is generated on each line", | |||
"severity": "MAJOR", | |||
"rule": "xoo:OneIssuePerLine", | |||
"status": "OPEN", | |||
"isNew": false, | |||
"creationDate": "2013-05-01T00:00:00+0200" | |||
}, | |||
{ | |||
"key": "<ISSUE_KEY>", | |||
"component": "sample:src/main/xoo/sample/Sample.xoo", | |||
"line": 15, | |||
"message": "This issue is generated on each line", | |||
"severity": "MAJOR", | |||
"rule": "xoo:OneIssuePerLine", | |||
"status": "OPEN", | |||
"isNew": false, | |||
"creationDate": "2013-05-01T00:00:00+0200" | |||
} | |||
], | |||
"components": [ | |||
{ | |||
"key": "sample" | |||
}, | |||
{ | |||
"key": "sample:src/main/xoo/sample", | |||
"path": "src/main/xoo/sample", | |||
"moduleKey": "sample" | |||
}, | |||
{ | |||
"key": "sample:src/main/xoo/sample/Sample.xoo", | |||
"path": "src/main/xoo/sample/Sample.xoo", | |||
"moduleKey": "sample", | |||
"status": "CHANGED" | |||
} | |||
], | |||
"rules": [ | |||
{ | |||
"key": "xoo:OneIssuePerLine", | |||
"rule": "OneIssuePerLine", | |||
"repository": "xoo", | |||
"name": "One Issue Per Line" | |||
} | |||
], | |||
"users": [] | |||
"components": [ | |||
{ | |||
"key": "sample" | |||
}, | |||
{ | |||
"key": "sample:src/main/xoo/sample/Sample.xoo", | |||
"moduleKey": "sample", | |||
"path": "src/main/xoo/sample/Sample.xoo", | |||
"status": "CHANGED" | |||
}, | |||
{ | |||
"key": "sample:src/main/xoo/sample", | |||
"moduleKey": "sample", | |||
"path": "src/main/xoo/sample" | |||
} | |||
], | |||
"issues": [ | |||
{ | |||
"component": "sample:src/main/xoo/sample/Sample.xoo", | |||
"creationDate": "2013-05-02T00:00:00+0200", | |||
"endLine": 11, | |||
"endOffset": 28, | |||
"isNew": true, | |||
"key": "<ISSUE_KEY>", | |||
"line": 11, | |||
"message": "This issue is generated on each line", | |||
"rule": "xoo:OneIssuePerLine", | |||
"severity": "MAJOR", | |||
"startLine": 11, | |||
"startOffset": 0, | |||
"status": "OPEN" | |||
}, | |||
{ | |||
"component": "sample:src/main/xoo/sample/Sample.xoo", | |||
"creationDate": "2013-05-02T00:00:00+0200", | |||
"endLine": 7, | |||
"endOffset": 28, | |||
"isNew": true, | |||
"key": "<ISSUE_KEY>", | |||
"line": 7, | |||
"message": "This issue is generated on each line", | |||
"rule": "xoo:OneIssuePerLine", | |||
"severity": "MAJOR", | |||
"startLine": 7, | |||
"startOffset": 0, | |||
"status": "OPEN" | |||
}, | |||
{ | |||
"component": "sample:src/main/xoo/sample/Sample.xoo", | |||
"creationDate": "2013-05-01T00:00:00+0200", | |||
"endLine": 1, | |||
"endOffset": 15, | |||
"isNew": false, | |||
"key": "<ISSUE_KEY>", | |||
"line": 1, | |||
"message": "This issue is generated on each line", | |||
"rule": "xoo:OneIssuePerLine", | |||
"severity": "MAJOR", | |||
"startLine": 1, | |||
"startOffset": 0, | |||
"status": "OPEN" | |||
}, | |||
{ | |||
"component": "sample:src/main/xoo/sample/Sample.xoo", | |||
"creationDate": "2013-05-01T00:00:00+0200", | |||
"endLine": 2, | |||
"endOffset": 0, | |||
"isNew": false, | |||
"key": "<ISSUE_KEY>", | |||
"line": 2, | |||
"message": "This issue is generated on each line", | |||
"rule": "xoo:OneIssuePerLine", | |||
"severity": "MAJOR", | |||
"startLine": 2, | |||
"startOffset": 0, | |||
"status": "OPEN" | |||
}, | |||
{ | |||
"component": "sample:src/main/xoo/sample/Sample.xoo", | |||
"creationDate": "2013-05-01T00:00:00+0200", | |||
"endLine": 3, | |||
"endOffset": 21, | |||
"isNew": false, | |||
"key": "<ISSUE_KEY>", | |||
"line": 3, | |||
"message": "This issue is generated on each line", | |||
"rule": "xoo:OneIssuePerLine", | |||
"severity": "MAJOR", | |||
"startLine": 3, | |||
"startOffset": 0, | |||
"status": "OPEN" | |||
}, | |||
{ | |||
"component": "sample:src/main/xoo/sample/Sample.xoo", | |||
"creationDate": "2013-05-01T00:00:00+0200", | |||
"endLine": 4, | |||
"endOffset": 1, | |||
"isNew": false, | |||
"key": "<ISSUE_KEY>", | |||
"line": 4, | |||
"message": "This issue is generated on each line", | |||
"rule": "xoo:OneIssuePerLine", | |||
"severity": "MAJOR", | |||
"startLine": 4, | |||
"startOffset": 0, | |||
"status": "OPEN" | |||
}, | |||
{ | |||
"component": "sample:src/main/xoo/sample/Sample.xoo", | |||
"creationDate": "2013-05-01T00:00:00+0200", | |||
"endLine": 5, | |||
"endOffset": 23, | |||
"isNew": false, | |||
"key": "<ISSUE_KEY>", | |||
"line": 5, | |||
"message": "This issue is generated on each line", | |||
"rule": "xoo:OneIssuePerLine", | |||
"severity": "MAJOR", | |||
"startLine": 5, | |||
"startOffset": 0, | |||
"status": "OPEN" | |||
}, | |||
{ | |||
"component": "sample:src/main/xoo/sample/Sample.xoo", | |||
"creationDate": "2013-05-01T00:00:00+0200", | |||
"endLine": 6, | |||
"endOffset": 14, | |||
"isNew": false, | |||
"key": "<ISSUE_KEY>", | |||
"line": 6, | |||
"message": "This issue is generated on each line", | |||
"rule": "xoo:OneIssuePerLine", | |||
"severity": "MAJOR", | |||
"startLine": 6, | |||
"startOffset": 0, | |||
"status": "OPEN" | |||
}, | |||
{ | |||
"component": "sample:src/main/xoo/sample/Sample.xoo", | |||
"creationDate": "2013-05-01T00:00:00+0200", | |||
"endLine": 8, | |||
"endOffset": 2, | |||
"isNew": false, | |||
"key": "<ISSUE_KEY>", | |||
"line": 8, | |||
"message": "This issue is generated on each line", | |||
"rule": "xoo:OneIssuePerLine", | |||
"severity": "MAJOR", | |||
"startLine": 8, | |||
"startOffset": 0, | |||
"status": "OPEN" | |||
}, | |||
{ | |||
"component": "sample:src/main/xoo/sample/Sample.xoo", | |||
"creationDate": "2013-05-01T00:00:00+0200", | |||
"endLine": 9, | |||
"endOffset": 1, | |||
"isNew": false, | |||
"key": "<ISSUE_KEY>", | |||
"line": 9, | |||
"message": "This issue is generated on each line", | |||
"rule": "xoo:OneIssuePerLine", | |||
"severity": "MAJOR", | |||
"startLine": 9, | |||
"startOffset": 0, | |||
"status": "OPEN" | |||
}, | |||
{ | |||
"component": "sample:src/main/xoo/sample/Sample.xoo", | |||
"creationDate": "2013-05-01T00:00:00+0200", | |||
"endLine": 10, | |||
"endOffset": 28, | |||
"isNew": false, | |||
"key": "<ISSUE_KEY>", | |||
"line": 10, | |||
"message": "This issue is generated on each line", | |||
"rule": "xoo:OneIssuePerLine", | |||
"severity": "MAJOR", | |||
"startLine": 10, | |||
"startOffset": 0, | |||
"status": "OPEN" | |||
}, | |||
{ | |||
"component": "sample:src/main/xoo/sample/Sample.xoo", | |||
"creationDate": "2013-05-01T00:00:00+0200", | |||
"endLine": 12, | |||
"endOffset": 17, | |||
"isNew": false, | |||
"key": "<ISSUE_KEY>", | |||
"line": 12, | |||
"message": "This issue is generated on each line", | |||
"rule": "xoo:OneIssuePerLine", | |||
"severity": "MAJOR", | |||
"startLine": 12, | |||
"startOffset": 0, | |||
"status": "OPEN" | |||
}, | |||
{ | |||
"component": "sample:src/main/xoo/sample/Sample.xoo", | |||
"creationDate": "2013-05-01T00:00:00+0200", | |||
"endLine": 13, | |||
"endOffset": 2, | |||
"isNew": false, | |||
"key": "<ISSUE_KEY>", | |||
"line": 13, | |||
"message": "This issue is generated on each line", | |||
"rule": "xoo:OneIssuePerLine", | |||
"severity": "MAJOR", | |||
"startLine": 13, | |||
"startOffset": 0, | |||
"status": "OPEN" | |||
}, | |||
{ | |||
"component": "sample:src/main/xoo/sample/Sample.xoo", | |||
"creationDate": "2013-05-01T00:00:00+0200", | |||
"endLine": 14, | |||
"endOffset": 1, | |||
"isNew": false, | |||
"key": "<ISSUE_KEY>", | |||
"line": 14, | |||
"message": "This issue is generated on each line", | |||
"rule": "xoo:OneIssuePerLine", | |||
"severity": "MAJOR", | |||
"startLine": 14, | |||
"startOffset": 0, | |||
"status": "OPEN" | |||
}, | |||
{ | |||
"component": "sample:src/main/xoo/sample/Sample.xoo", | |||
"creationDate": "2013-05-01T00:00:00+0200", | |||
"endLine": 15, | |||
"endOffset": 0, | |||
"isNew": false, | |||
"key": "<ISSUE_KEY>", | |||
"line": 15, | |||
"message": "This issue is generated on each line", | |||
"rule": "xoo:OneIssuePerLine", | |||
"severity": "MAJOR", | |||
"startLine": 15, | |||
"startOffset": 0, | |||
"status": "OPEN" | |||
} | |||
], | |||
"rules": [ | |||
{ | |||
"key": "xoo:OneIssuePerLine", | |||
"name": "One Issue Per Line", | |||
"repository": "xoo", | |||
"rule": "OneIssuePerLine" | |||
} | |||
], | |||
"users": [], | |||
"version": "<SONAR_VERSION>" | |||
} |
@@ -1,208 +1,238 @@ | |||
{ | |||
"version": "<SONAR_VERSION>", | |||
"components": [ | |||
{ | |||
"key": "com.sonarsource.it.samples:multi-modules-sample:module_a:module_a1" | |||
}, | |||
{ | |||
"key": "com.sonarsource.it.samples:multi-modules-sample:module_a:module_a1:src/main/xoo/com/sonar/it/samples/modules/a1/HelloA1.xoo", | |||
"moduleKey": "com.sonarsource.it.samples:multi-modules-sample:module_a:module_a1", | |||
"path": "src/main/xoo/com/sonar/it/samples/modules/a1/HelloA1.xoo", | |||
"status": "SAME" | |||
}, | |||
{ | |||
"key": "com.sonarsource.it.samples:multi-modules-sample:module_a:module_a1:src/main/xoo/com/sonar/it/samples/modules/a1", | |||
"moduleKey": "com.sonarsource.it.samples:multi-modules-sample:module_a:module_a1", | |||
"path": "src/main/xoo/com/sonar/it/samples/modules/a1" | |||
} | |||
], | |||
"issues": [ | |||
{ | |||
"key": "<ISSUE_KEY>", | |||
"component": "com.sonarsource.it.samples:multi-modules-sample:module_a:module_a1:src/main/xoo/com/sonar/it/samples/modules/a1/HelloA1.xoo", | |||
"line": 4, | |||
"message": "This issue is generated on each line", | |||
"severity": "MAJOR", | |||
"rule": "xoo:OneIssuePerLine", | |||
"status": "OPEN", | |||
"creationDate": "2013-05-01T00:00:00+0200", | |||
"endLine": 1, | |||
"isNew": false, | |||
"creationDate": "2013-05-01T00:00:00+0200" | |||
}, | |||
{ | |||
"key": "<ISSUE_KEY>", | |||
"component": "com.sonarsource.it.samples:multi-modules-sample:module_a:module_a1:src/main/xoo/com/sonar/it/samples/modules/a1/HelloA1.xoo", | |||
"line": 7, | |||
"line": 1, | |||
"message": "This issue is generated on each line", | |||
"severity": "MAJOR", | |||
"rule": "xoo:OneIssuePerLine", | |||
"status": "OPEN", | |||
"isNew": false, | |||
"creationDate": "2013-05-01T00:00:00+0200" | |||
"severity": "MAJOR", | |||
"startLine": 1, | |||
"status": "OPEN" | |||
}, | |||
{ | |||
"key": "<ISSUE_KEY>", | |||
"component": "com.sonarsource.it.samples:multi-modules-sample:module_a:module_a1:src/main/xoo/com/sonar/it/samples/modules/a1/HelloA1.xoo", | |||
"line": 6, | |||
"message": "This issue is generated on each line", | |||
"severity": "MAJOR", | |||
"rule": "xoo:OneIssuePerLine", | |||
"status": "OPEN", | |||
"creationDate": "2013-05-01T00:00:00+0200", | |||
"endLine": 2, | |||
"isNew": false, | |||
"creationDate": "2013-05-01T00:00:00+0200" | |||
}, | |||
{ | |||
"key": "<ISSUE_KEY>", | |||
"component": "com.sonarsource.it.samples:multi-modules-sample:module_a:module_a1:src/main/xoo/com/sonar/it/samples/modules/a1/HelloA1.xoo", | |||
"line": 1, | |||
"line": 2, | |||
"message": "This issue is generated on each line", | |||
"severity": "MAJOR", | |||
"rule": "xoo:OneIssuePerLine", | |||
"status": "OPEN", | |||
"isNew": false, | |||
"creationDate": "2013-05-01T00:00:00+0200" | |||
"severity": "MAJOR", | |||
"startLine": 2, | |||
"status": "OPEN" | |||
}, | |||
{ | |||
"key": "<ISSUE_KEY>", | |||
"component": "com.sonarsource.it.samples:multi-modules-sample:module_a:module_a1:src/main/xoo/com/sonar/it/samples/modules/a1/HelloA1.xoo", | |||
"line": 8, | |||
"creationDate": "2013-05-01T00:00:00+0200", | |||
"endLine": 3, | |||
"isNew": false, | |||
"key": "<ISSUE_KEY>", | |||
"line": 3, | |||
"message": "This issue is generated on each line", | |||
"severity": "MAJOR", | |||
"rule": "xoo:OneIssuePerLine", | |||
"status": "OPEN", | |||
"isNew": false, | |||
"creationDate": "2013-05-01T00:00:00+0200" | |||
"severity": "MAJOR", | |||
"startLine": 3, | |||
"status": "OPEN" | |||
}, | |||
{ | |||
"key": "<ISSUE_KEY>", | |||
"component": "com.sonarsource.it.samples:multi-modules-sample:module_a:module_a1:src/main/xoo/com/sonar/it/samples/modules/a1/HelloA1.xoo", | |||
"line": 15, | |||
"creationDate": "2013-05-01T00:00:00+0200", | |||
"endLine": 4, | |||
"isNew": false, | |||
"key": "<ISSUE_KEY>", | |||
"line": 4, | |||
"message": "This issue is generated on each line", | |||
"severity": "MAJOR", | |||
"rule": "xoo:OneIssuePerLine", | |||
"status": "OPEN", | |||
"isNew": false, | |||
"creationDate": "2013-05-01T00:00:00+0200" | |||
"severity": "MAJOR", | |||
"startLine": 4, | |||
"status": "OPEN" | |||
}, | |||
{ | |||
"key": "<ISSUE_KEY>", | |||
"component": "com.sonarsource.it.samples:multi-modules-sample:module_a:module_a1:src/main/xoo/com/sonar/it/samples/modules/a1/HelloA1.xoo", | |||
"line": 14, | |||
"creationDate": "2013-05-01T00:00:00+0200", | |||
"endLine": 5, | |||
"isNew": false, | |||
"key": "<ISSUE_KEY>", | |||
"line": 5, | |||
"message": "This issue is generated on each line", | |||
"severity": "MAJOR", | |||
"rule": "xoo:OneIssuePerLine", | |||
"status": "OPEN", | |||
"isNew": false, | |||
"creationDate": "2013-05-01T00:00:00+0200" | |||
"severity": "MAJOR", | |||
"startLine": 5, | |||
"status": "OPEN" | |||
}, | |||
{ | |||
"key": "<ISSUE_KEY>", | |||
"component": "com.sonarsource.it.samples:multi-modules-sample:module_a:module_a1:src/main/xoo/com/sonar/it/samples/modules/a1/HelloA1.xoo", | |||
"line": 10, | |||
"creationDate": "2013-05-01T00:00:00+0200", | |||
"endLine": 6, | |||
"isNew": false, | |||
"key": "<ISSUE_KEY>", | |||
"line": 6, | |||
"message": "This issue is generated on each line", | |||
"severity": "MAJOR", | |||
"rule": "xoo:OneIssuePerLine", | |||
"status": "OPEN", | |||
"isNew": false, | |||
"creationDate": "2013-05-01T00:00:00+0200" | |||
"severity": "MAJOR", | |||
"startLine": 6, | |||
"status": "OPEN" | |||
}, | |||
{ | |||
"key": "<ISSUE_KEY>", | |||
"component": "com.sonarsource.it.samples:multi-modules-sample:module_a:module_a1:src/main/xoo/com/sonar/it/samples/modules/a1/HelloA1.xoo", | |||
"line": 3, | |||
"creationDate": "2013-05-01T00:00:00+0200", | |||
"endLine": 7, | |||
"isNew": false, | |||
"key": "<ISSUE_KEY>", | |||
"line": 7, | |||
"message": "This issue is generated on each line", | |||
"severity": "MAJOR", | |||
"rule": "xoo:OneIssuePerLine", | |||
"status": "OPEN", | |||
"isNew": false, | |||
"creationDate": "2013-05-01T00:00:00+0200" | |||
"severity": "MAJOR", | |||
"startLine": 7, | |||
"status": "OPEN" | |||
}, | |||
{ | |||
"key": "<ISSUE_KEY>", | |||
"component": "com.sonarsource.it.samples:multi-modules-sample:module_a:module_a1:src/main/xoo/com/sonar/it/samples/modules/a1/HelloA1.xoo", | |||
"line": 2, | |||
"creationDate": "2013-05-01T00:00:00+0200", | |||
"endLine": 8, | |||
"isNew": false, | |||
"key": "<ISSUE_KEY>", | |||
"line": 8, | |||
"message": "This issue is generated on each line", | |||
"severity": "MAJOR", | |||
"rule": "xoo:OneIssuePerLine", | |||
"status": "OPEN", | |||
"isNew": false, | |||
"creationDate": "2013-05-01T00:00:00+0200" | |||
"severity": "MAJOR", | |||
"startLine": 8, | |||
"status": "OPEN" | |||
}, | |||
{ | |||
"key": "<ISSUE_KEY>", | |||
"component": "com.sonarsource.it.samples:multi-modules-sample:module_a:module_a1:src/main/xoo/com/sonar/it/samples/modules/a1/HelloA1.xoo", | |||
"line": 16, | |||
"creationDate": "2013-05-01T00:00:00+0200", | |||
"endLine": 9, | |||
"isNew": false, | |||
"key": "<ISSUE_KEY>", | |||
"line": 9, | |||
"message": "This issue is generated on each line", | |||
"severity": "MAJOR", | |||
"rule": "xoo:OneIssuePerLine", | |||
"status": "OPEN", | |||
"isNew": false, | |||
"creationDate": "2013-05-01T00:00:00+0200" | |||
"severity": "MAJOR", | |||
"startLine": 9, | |||
"status": "OPEN" | |||
}, | |||
{ | |||
"key": "<ISSUE_KEY>", | |||
"component": "com.sonarsource.it.samples:multi-modules-sample:module_a:module_a1:src/main/xoo/com/sonar/it/samples/modules/a1/HelloA1.xoo", | |||
"line": 9, | |||
"creationDate": "2013-05-01T00:00:00+0200", | |||
"endLine": 10, | |||
"isNew": false, | |||
"key": "<ISSUE_KEY>", | |||
"line": 10, | |||
"message": "This issue is generated on each line", | |||
"severity": "MAJOR", | |||
"rule": "xoo:OneIssuePerLine", | |||
"status": "OPEN", | |||
"isNew": false, | |||
"creationDate": "2013-05-01T00:00:00+0200" | |||
"severity": "MAJOR", | |||
"startLine": 10, | |||
"status": "OPEN" | |||
}, | |||
{ | |||
"key": "<ISSUE_KEY>", | |||
"component": "com.sonarsource.it.samples:multi-modules-sample:module_a:module_a1:src/main/xoo/com/sonar/it/samples/modules/a1/HelloA1.xoo", | |||
"line": 5, | |||
"creationDate": "2013-05-01T00:00:00+0200", | |||
"endLine": 11, | |||
"isNew": false, | |||
"key": "<ISSUE_KEY>", | |||
"line": 11, | |||
"message": "This issue is generated on each line", | |||
"severity": "MAJOR", | |||
"rule": "xoo:OneIssuePerLine", | |||
"status": "OPEN", | |||
"isNew": false, | |||
"creationDate": "2013-05-01T00:00:00+0200" | |||
"severity": "MAJOR", | |||
"startLine": 11, | |||
"status": "OPEN" | |||
}, | |||
{ | |||
"key": "<ISSUE_KEY>", | |||
"component": "com.sonarsource.it.samples:multi-modules-sample:module_a:module_a1:src/main/xoo/com/sonar/it/samples/modules/a1/HelloA1.xoo", | |||
"creationDate": "2013-05-01T00:00:00+0200", | |||
"endLine": 12, | |||
"isNew": false, | |||
"key": "<ISSUE_KEY>", | |||
"line": 12, | |||
"message": "This issue is generated on each line", | |||
"severity": "MAJOR", | |||
"rule": "xoo:OneIssuePerLine", | |||
"status": "OPEN", | |||
"isNew": false, | |||
"creationDate": "2013-05-01T00:00:00+0200" | |||
"severity": "MAJOR", | |||
"startLine": 12, | |||
"status": "OPEN" | |||
}, | |||
{ | |||
"key": "<ISSUE_KEY>", | |||
"component": "com.sonarsource.it.samples:multi-modules-sample:module_a:module_a1:src/main/xoo/com/sonar/it/samples/modules/a1/HelloA1.xoo", | |||
"creationDate": "2013-05-01T00:00:00+0200", | |||
"endLine": 13, | |||
"isNew": false, | |||
"key": "<ISSUE_KEY>", | |||
"line": 13, | |||
"message": "This issue is generated on each line", | |||
"severity": "MAJOR", | |||
"rule": "xoo:OneIssuePerLine", | |||
"status": "OPEN", | |||
"isNew": false, | |||
"creationDate": "2013-05-01T00:00:00+0200" | |||
"severity": "MAJOR", | |||
"startLine": 13, | |||
"status": "OPEN" | |||
}, | |||
{ | |||
"key": "<ISSUE_KEY>", | |||
"component": "com.sonarsource.it.samples:multi-modules-sample:module_a:module_a1:src/main/xoo/com/sonar/it/samples/modules/a1/HelloA1.xoo", | |||
"line": 11, | |||
"creationDate": "2013-05-01T00:00:00+0200", | |||
"endLine": 14, | |||
"isNew": false, | |||
"key": "<ISSUE_KEY>", | |||
"line": 14, | |||
"message": "This issue is generated on each line", | |||
"severity": "MAJOR", | |||
"rule": "xoo:OneIssuePerLine", | |||
"status": "OPEN", | |||
"isNew": false, | |||
"creationDate": "2013-05-01T00:00:00+0200" | |||
} | |||
], | |||
"components": [ | |||
{ | |||
"key": "com.sonarsource.it.samples:multi-modules-sample:module_a:module_a1" | |||
"severity": "MAJOR", | |||
"startLine": 14, | |||
"status": "OPEN" | |||
}, | |||
{ | |||
"key": "com.sonarsource.it.samples:multi-modules-sample:module_a:module_a1:src/main/xoo/com/sonar/it/samples/modules/a1", | |||
"path": "src/main/xoo/com/sonar/it/samples/modules/a1", | |||
"moduleKey": "com.sonarsource.it.samples:multi-modules-sample:module_a:module_a1" | |||
"component": "com.sonarsource.it.samples:multi-modules-sample:module_a:module_a1:src/main/xoo/com/sonar/it/samples/modules/a1/HelloA1.xoo", | |||
"creationDate": "2013-05-01T00:00:00+0200", | |||
"endLine": 15, | |||
"isNew": false, | |||
"key": "<ISSUE_KEY>", | |||
"line": 15, | |||
"message": "This issue is generated on each line", | |||
"rule": "xoo:OneIssuePerLine", | |||
"severity": "MAJOR", | |||
"startLine": 15, | |||
"status": "OPEN" | |||
}, | |||
{ | |||
"key": "com.sonarsource.it.samples:multi-modules-sample:module_a:module_a1:src/main/xoo/com/sonar/it/samples/modules/a1/HelloA1.xoo", | |||
"path": "src/main/xoo/com/sonar/it/samples/modules/a1/HelloA1.xoo", | |||
"moduleKey": "com.sonarsource.it.samples:multi-modules-sample:module_a:module_a1", | |||
"status": "SAME" | |||
"component": "com.sonarsource.it.samples:multi-modules-sample:module_a:module_a1:src/main/xoo/com/sonar/it/samples/modules/a1/HelloA1.xoo", | |||
"creationDate": "2013-05-01T00:00:00+0200", | |||
"endLine": 16, | |||
"isNew": false, | |||
"key": "<ISSUE_KEY>", | |||
"line": 16, | |||
"message": "This issue is generated on each line", | |||
"rule": "xoo:OneIssuePerLine", | |||
"severity": "MAJOR", | |||
"startLine": 16, | |||
"status": "OPEN" | |||
} | |||
], | |||
"rules": [ | |||
{ | |||
"key": "xoo:OneIssuePerLine", | |||
"rule": "OneIssuePerLine", | |||
"name": "One Issue Per Line", | |||
"repository": "xoo", | |||
"name": "One Issue Per Line" | |||
"rule": "OneIssuePerLine" | |||
} | |||
], | |||
"users": [ ] | |||
"users": [], | |||
"version": "<SONAR_VERSION>" | |||
} |
@@ -21,11 +21,19 @@ package org.sonar.batch.bootstrapper; | |||
public interface IssueListener { | |||
void handle(Issue issue); | |||
class Issue { | |||
/** @since 5.3 */ | |||
private Integer startLine; | |||
/** @since 5.3 */ | |||
private Integer startLineOffset; | |||
/** @since 5.3 */ | |||
private Integer endLine; | |||
/** @since 5.3 */ | |||
private Integer endLineOffset; | |||
private String key; | |||
private String componentKey; | |||
private Integer line; | |||
private String message; | |||
private String ruleKey; | |||
private String ruleName; | |||
@@ -60,12 +68,36 @@ public interface IssueListener { | |||
this.componentKey = componentKey; | |||
} | |||
public Integer getLine() { | |||
return line; | |||
public Integer getStartLine() { | |||
return startLine; | |||
} | |||
public void setStartLine(Integer startLine) { | |||
this.startLine = startLine; | |||
} | |||
public Integer getStartLineOffset() { | |||
return startLineOffset; | |||
} | |||
public void setStartLineOffset(Integer startLineOffset) { | |||
this.startLineOffset = startLineOffset; | |||
} | |||
public Integer getEndLine() { | |||
return endLine; | |||
} | |||
public void setEndLine(Integer endLine) { | |||
this.endLine = endLine; | |||
} | |||
public Integer getEndLineOffset() { | |||
return endLineOffset; | |||
} | |||
public void setLine(Integer line) { | |||
this.line = line; | |||
public void setEndLineOffset(Integer endLineOffset) { | |||
this.endLineOffset = endLineOffset; | |||
} | |||
public String getMessage() { |
@@ -19,8 +19,9 @@ | |||
*/ | |||
package org.sonar.batch.issue; | |||
import org.apache.commons.lang.StringUtils; | |||
import org.sonar.batch.issue.tracking.TrackedIssue; | |||
import org.apache.commons.lang.StringUtils; | |||
import org.sonar.api.rule.RuleKey; | |||
import org.sonar.api.batch.rule.Rule; | |||
import org.sonar.api.batch.rule.Rules; | |||
@@ -33,7 +34,6 @@ import java.util.Set; | |||
import org.sonar.batch.repository.user.UserRepositoryLoader; | |||
import org.sonar.batch.bootstrapper.IssueListener; | |||
import org.sonar.core.issue.DefaultIssue; | |||
public class DefaultIssueCallback implements IssueCallback { | |||
private final IssueCache issues; | |||
@@ -65,37 +65,40 @@ public class DefaultIssueCallback implements IssueCallback { | |||
return; | |||
} | |||
for (DefaultIssue issue : issues.all()) { | |||
for (TrackedIssue issue : issues.all()) { | |||
collectInfo(issue); | |||
} | |||
getUsers(); | |||
for (DefaultIssue issue : issues.all()) { | |||
for (TrackedIssue issue : issues.all()) { | |||
IssueListener.Issue newIssue = new IssueListener.Issue(); | |||
newIssue.setAssigneeLogin(issue.assignee()); | |||
newIssue.setAssigneeName(getAssigneeName(issue.assignee())); | |||
newIssue.setComponentKey(issue.componentKey()); | |||
newIssue.setKey(issue.key()); | |||
newIssue.setLine(issue.getLine()); | |||
newIssue.setMessage(issue.getMessage()); | |||
newIssue.setMessage(issue.message()); | |||
newIssue.setNew(issue.isNew()); | |||
newIssue.setResolution(issue.resolution()); | |||
newIssue.setRuleKey(issue.getRuleKey().toString()); | |||
newIssue.setRuleName(getRuleName(issue.getRuleKey())); | |||
newIssue.setRuleKey(issue.ruleKey().toString()); | |||
newIssue.setRuleName(getRuleName(issue.ruleKey())); | |||
newIssue.setSeverity(issue.severity()); | |||
newIssue.setStatus(issue.status()); | |||
newIssue.setStartLine(issue.startLine()); | |||
newIssue.setStartLineOffset(issue.startLineOffset()); | |||
newIssue.setEndLine(issue.endLine()); | |||
newIssue.setEndLineOffset(issue.endLineOffset()); | |||
listener.handle(newIssue); | |||
} | |||
} | |||
private void collectInfo(DefaultIssue issue) { | |||
private void collectInfo(TrackedIssue issue) { | |||
if (!StringUtils.isEmpty(issue.assignee())) { | |||
userLoginNames.add(issue.assignee()); | |||
} | |||
if (issue.getRuleKey() != null) { | |||
ruleKeys.add(issue.getRuleKey()); | |||
if (issue.ruleKey() != null) { | |||
ruleKeys.add(issue.ruleKey()); | |||
} | |||
} | |||
@@ -19,11 +19,12 @@ | |||
*/ | |||
package org.sonar.batch.issue; | |||
import com.google.common.base.Function; | |||
import com.google.common.base.Predicate; | |||
import com.google.common.collect.Iterables; | |||
import org.sonar.api.issue.Issue; | |||
import org.sonar.api.issue.ProjectIssues; | |||
import org.sonar.core.issue.DefaultIssue; | |||
import org.sonar.batch.issue.tracking.TrackedIssue; | |||
import javax.annotation.Nullable; | |||
@@ -41,15 +42,19 @@ public class DefaultProjectIssues implements ProjectIssues { | |||
@Override | |||
public Iterable<Issue> issues() { | |||
return (Iterable) Iterables.filter(cache.all(), new ResolvedPredicate(false)); | |||
return Iterables.transform( | |||
Iterables.filter(cache.all(), new ResolvedPredicate(false)), | |||
new IssueTransformer()); | |||
} | |||
@Override | |||
public Iterable<Issue> resolvedIssues() { | |||
return (Iterable) Iterables.filter(cache.all(), new ResolvedPredicate(true)); | |||
return Iterables.transform( | |||
Iterables.filter(cache.all(), new ResolvedPredicate(true)), | |||
new IssueTransformer()); | |||
} | |||
private static class ResolvedPredicate implements Predicate<DefaultIssue> { | |||
private static class ResolvedPredicate implements Predicate<TrackedIssue> { | |||
private final boolean resolved; | |||
private ResolvedPredicate(boolean resolved) { | |||
@@ -57,11 +62,18 @@ public class DefaultProjectIssues implements ProjectIssues { | |||
} | |||
@Override | |||
public boolean apply(@Nullable DefaultIssue issue) { | |||
public boolean apply(@Nullable TrackedIssue issue) { | |||
if (issue != null) { | |||
return resolved ? (issue.resolution() != null) : (issue.resolution() == null); | |||
} | |||
return false; | |||
} | |||
} | |||
private static class IssueTransformer implements Function<TrackedIssue, Issue> { | |||
@Override | |||
public Issue apply(TrackedIssue issue) { | |||
return new TrackedIssueAdapter(issue); | |||
} | |||
} | |||
} |
@@ -19,8 +19,9 @@ | |||
*/ | |||
package org.sonar.batch.issue; | |||
import org.sonar.batch.issue.tracking.TrackedIssue; | |||
import org.sonar.api.batch.BatchSide; | |||
import org.sonar.core.issue.DefaultIssue; | |||
import org.sonar.batch.index.Cache; | |||
import org.sonar.batch.index.Caches; | |||
@@ -33,17 +34,17 @@ import java.util.Collection; | |||
public class IssueCache { | |||
// component key -> issue key -> issue | |||
private final Cache<DefaultIssue> cache; | |||
private final Cache<TrackedIssue> cache; | |||
public IssueCache(Caches caches) { | |||
cache = caches.createCache("issues"); | |||
} | |||
public Iterable<DefaultIssue> byComponent(String componentKey) { | |||
public Iterable<TrackedIssue> byComponent(String componentKey) { | |||
return cache.values(componentKey); | |||
} | |||
public Iterable<DefaultIssue> all() { | |||
public Iterable<TrackedIssue> all() { | |||
return cache.values(); | |||
} | |||
@@ -51,7 +52,7 @@ public class IssueCache { | |||
return cache.keySet(); | |||
} | |||
public IssueCache put(DefaultIssue issue) { | |||
public IssueCache put(TrackedIssue issue) { | |||
cache.put(issue.componentKey(), issue.key(), issue); | |||
return this; | |||
} |
@@ -0,0 +1,102 @@ | |||
/* | |||
* SonarQube, open source software quality management tool. | |||
* Copyright (C) 2008-2014 SonarSource | |||
* mailto:contact AT sonarsource DOT com | |||
* | |||
* SonarQube 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. | |||
* | |||
* SonarQube 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.batch.issue; | |||
import com.google.common.base.Preconditions; | |||
import org.sonar.core.util.Uuids; | |||
import org.sonar.api.issue.Issue; | |||
import org.sonar.batch.protocol.output.BatchReport.TextRange; | |||
import org.sonar.core.component.ComponentKeys; | |||
import java.util.Date; | |||
import org.sonar.batch.issue.tracking.TrackedIssue; | |||
import org.sonar.api.rule.RuleKey; | |||
import org.sonar.batch.index.BatchComponent; | |||
import org.sonar.batch.protocol.output.BatchReport; | |||
public class IssueTransformer { | |||
private IssueTransformer() { | |||
// static only | |||
} | |||
public static TrackedIssue toTrackedIssue(org.sonar.batch.protocol.input.BatchInput.ServerIssue serverIssue) { | |||
TrackedIssue issue = new TrackedIssue(); | |||
issue.setKey(serverIssue.getKey()); | |||
issue.setStatus(serverIssue.getStatus()); | |||
issue.setResolution(serverIssue.hasResolution() ? serverIssue.getResolution() : null); | |||
issue.setMessage(serverIssue.hasMsg() ? serverIssue.getMsg() : null); | |||
issue.setStartLine(serverIssue.hasLine() ? serverIssue.getLine() : null); | |||
issue.setEndLine(serverIssue.hasLine() ? serverIssue.getLine() : null); | |||
issue.setSeverity(serverIssue.getSeverity().name()); | |||
issue.setAssignee(serverIssue.hasAssigneeLogin() ? serverIssue.getAssigneeLogin() : null); | |||
issue.setComponentKey(ComponentKeys.createEffectiveKey(serverIssue.getModuleKey(), serverIssue.hasPath() ? serverIssue.getPath() : null)); | |||
issue.setCreationDate(new Date(serverIssue.getCreationDate())); | |||
issue.setRuleKey(RuleKey.of(serverIssue.getRuleRepository(), serverIssue.getRuleKey())); | |||
issue.setNew(false); | |||
return issue; | |||
} | |||
public static void close(TrackedIssue issue) { | |||
issue.setStatus(Issue.STATUS_CLOSED); | |||
issue.setStartLine(null); | |||
issue.setEndLine(null); | |||
issue.setResolution(Issue.RESOLUTION_FIXED); | |||
} | |||
public static void resolveRemove(TrackedIssue issue) { | |||
issue.setStatus(Issue.STATUS_CLOSED); | |||
issue.setStartLine(null); | |||
issue.setEndLine(null); | |||
issue.setResolution(Issue.RESOLUTION_REMOVED); | |||
} | |||
public static TrackedIssue toTrackedIssue(BatchComponent component, BatchReport.Issue rawIssue) { | |||
RuleKey ruleKey = RuleKey.of(rawIssue.getRuleRepository(), rawIssue.getRuleKey()); | |||
Preconditions.checkNotNull(component.key(), "Component key must be set"); | |||
Preconditions.checkNotNull(ruleKey, "Rule key must be set"); | |||
TrackedIssue issue = new TrackedIssue(); | |||
issue.setKey(Uuids.create()); | |||
issue.setComponentKey(component.key()); | |||
issue.setRuleKey(ruleKey); | |||
issue.setEffortToFix(rawIssue.hasEffortToFix() ? rawIssue.getEffortToFix() : null); | |||
issue.setSeverity(rawIssue.getSeverity().name()); | |||
issue.setMessage(rawIssue.hasMsg() ? rawIssue.getMsg() : null); | |||
issue.setResolution(null); | |||
issue.setStatus(Issue.STATUS_OPEN); | |||
issue.setNew(true); | |||
if (rawIssue.hasTextRange()) { | |||
TextRange r = rawIssue.getTextRange(); | |||
issue.setStartLine(r.hasStartLine() ? rawIssue.getTextRange().getStartLine() : null); | |||
issue.setStartLineOffset(r.hasStartOffset() ? r.getStartOffset() : null); | |||
issue.setEndLine(r.hasEndLine() ? r.getEndLine() : issue.startLine()); | |||
issue.setEndLineOffset(r.hasEndOffset() ? r.getEndOffset() : null); | |||
} | |||
return issue; | |||
} | |||
} |
@@ -0,0 +1,186 @@ | |||
/* | |||
* SonarQube, open source software quality management tool. | |||
* Copyright (C) 2008-2014 SonarSource | |||
* mailto:contact AT sonarsource DOT com | |||
* | |||
* SonarQube 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. | |||
* | |||
* SonarQube 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.batch.issue; | |||
import org.sonar.api.issue.IssueComment; | |||
import org.sonar.api.rule.RuleKey; | |||
import org.sonar.api.utils.Duration; | |||
import java.util.ArrayList; | |||
import java.util.Collection; | |||
import java.util.Date; | |||
import java.util.HashMap; | |||
import java.util.List; | |||
import java.util.Map; | |||
import org.sonar.batch.issue.tracking.TrackedIssue; | |||
import org.sonar.api.issue.Issue; | |||
public class TrackedIssueAdapter implements Issue { | |||
private TrackedIssue issue; | |||
public TrackedIssueAdapter(TrackedIssue issue) { | |||
this.issue = issue; | |||
} | |||
@Override | |||
public String key() { | |||
return issue.key(); | |||
} | |||
@Override | |||
public String componentKey() { | |||
return issue.componentKey(); | |||
} | |||
@Override | |||
public RuleKey ruleKey() { | |||
return issue.ruleKey(); | |||
} | |||
@Override | |||
public String severity() { | |||
return issue.severity(); | |||
} | |||
@Override | |||
public String message() { | |||
return issue.message(); | |||
} | |||
@Override | |||
public Integer line() { | |||
return issue.startLine(); | |||
} | |||
@Override | |||
public Double effortToFix() { | |||
return issue.effortToFix(); | |||
} | |||
@Override | |||
public String status() { | |||
return issue.status(); | |||
} | |||
@Override | |||
public String resolution() { | |||
return issue.resolution(); | |||
} | |||
@Override | |||
public String reporter() { | |||
return issue.reporter(); | |||
} | |||
@Override | |||
public String assignee() { | |||
return issue.assignee(); | |||
} | |||
@Override | |||
public boolean isNew() { | |||
return issue.isNew(); | |||
} | |||
@Override | |||
public Map<String, String> attributes() { | |||
return new HashMap<>(); | |||
} | |||
@Override | |||
public Date creationDate() { | |||
return null; | |||
} | |||
@Override | |||
public String language() { | |||
return null; | |||
} | |||
@Override | |||
public Date updateDate() { | |||
return null; | |||
} | |||
@Override | |||
public Date closeDate() { | |||
return null; | |||
} | |||
@Override | |||
public String attribute(String key) { | |||
return null; | |||
} | |||
@Override | |||
public String authorLogin() { | |||
return null; | |||
} | |||
@Override | |||
public String actionPlanKey() { | |||
return null; | |||
} | |||
@Override | |||
public List<IssueComment> comments() { | |||
return new ArrayList<>(); | |||
} | |||
@Override | |||
public Duration debt() { | |||
return null; | |||
} | |||
@Override | |||
public String projectKey() { | |||
return null; | |||
} | |||
@Override | |||
public String projectUuid() { | |||
return null; | |||
} | |||
@Override | |||
public String componentUuid() { | |||
return null; | |||
} | |||
@Override | |||
public Collection<String> tags() { | |||
return new ArrayList<>(); | |||
} | |||
@Override | |||
public boolean equals(Object o) { | |||
if (o == null || !(o instanceof Issue)) { | |||
return false; | |||
} | |||
Issue that = (Issue) o; | |||
return !(issue.key() != null ? !issue.key().equals(that.key()) : (that.key() != null)); | |||
} | |||
@Override | |||
public int hashCode() { | |||
return issue.key() != null ? issue.key().hashCode() : 0; | |||
} | |||
} |
@@ -19,50 +19,47 @@ | |||
*/ | |||
package org.sonar.batch.issue.tracking; | |||
import org.sonar.batch.issue.IssueTransformer; | |||
import com.google.common.collect.Lists; | |||
import com.google.common.collect.Sets; | |||
import java.util.Date; | |||
import java.util.List; | |||
import java.util.Set; | |||
import javax.annotation.Nullable; | |||
import org.sonar.api.batch.BatchSide; | |||
import org.sonar.api.resources.Project; | |||
import org.sonar.api.rule.RuleKey; | |||
import org.sonar.batch.index.BatchComponent; | |||
import org.sonar.batch.index.BatchComponentCache; | |||
import org.sonar.batch.issue.IssueCache; | |||
import org.sonar.batch.protocol.output.BatchReport; | |||
import org.sonar.batch.protocol.output.BatchReportReader; | |||
import org.sonar.batch.report.ReportPublisher; | |||
import org.sonar.core.issue.DefaultIssue; | |||
import org.sonar.core.issue.IssueChangeContext; | |||
import org.sonar.core.issue.workflow.IssueWorkflow; | |||
import org.sonar.core.util.CloseableIterator; | |||
@BatchSide | |||
public class IssueTransition { | |||
private final IssueCache issueCache; | |||
private final IssueWorkflow workflow; | |||
private final IssueChangeContext changeContext; | |||
private final BatchComponentCache componentCache; | |||
private final ReportPublisher reportPublisher; | |||
private final Date analysisDate; | |||
@Nullable | |||
private final LocalIssueTracking localIssueTracking; | |||
public IssueTransition(BatchComponentCache componentCache, IssueCache issueCache, IssueWorkflow workflow, ReportPublisher reportPublisher, | |||
public IssueTransition(BatchComponentCache componentCache, IssueCache issueCache, ReportPublisher reportPublisher, | |||
@Nullable LocalIssueTracking localIssueTracking) { | |||
this.componentCache = componentCache; | |||
this.issueCache = issueCache; | |||
this.workflow = workflow; | |||
this.reportPublisher = reportPublisher; | |||
this.localIssueTracking = localIssueTracking; | |||
this.analysisDate = ((Project) componentCache.getRoot().resource()).getAnalysisDate(); | |||
this.changeContext = IssueChangeContext.createScan(analysisDate); | |||
} | |||
public IssueTransition(BatchComponentCache componentCache, IssueCache issueCache, IssueWorkflow workflow, ReportPublisher reportPublisher) { | |||
this(componentCache, issueCache, workflow, reportPublisher, null); | |||
public IssueTransition(BatchComponentCache componentCache, IssueCache issueCache, ReportPublisher reportPublisher) { | |||
this(componentCache, issueCache, reportPublisher, null); | |||
} | |||
public void execute() { | |||
@@ -88,7 +85,7 @@ public class IssueTransition { | |||
throw new IllegalStateException("Can't read issues for " + component.key(), e); | |||
} | |||
List<DefaultIssue> trackedIssues; | |||
List<TrackedIssue> trackedIssues; | |||
if (localIssueTracking != null) { | |||
trackedIssues = localIssueTracking.trackIssues(component, rawIssues); | |||
} else { | |||
@@ -98,32 +95,19 @@ public class IssueTransition { | |||
// Unmatched raw issues = new issues | |||
addUnmatchedRawIssues(component, rawIssues, trackedIssues); | |||
for (DefaultIssue issue : trackedIssues) { | |||
workflow.doAutomaticTransition(issue, changeContext); | |||
for (TrackedIssue issue : trackedIssues) { | |||
issueCache.put(issue); | |||
} | |||
} | |||
private void addUnmatchedRawIssues(BatchComponent component, Set<org.sonar.batch.protocol.output.BatchReport.Issue> rawIssues, List<DefaultIssue> trackedIssues) { | |||
private void addUnmatchedRawIssues(BatchComponent component, Set<org.sonar.batch.protocol.output.BatchReport.Issue> rawIssues, List<TrackedIssue> trackedIssues) { | |||
for (BatchReport.Issue rawIssue : rawIssues) { | |||
DefaultIssue tracked = toTracked(component, rawIssue); | |||
tracked.setNew(true); | |||
TrackedIssue tracked = IssueTransformer.toTrackedIssue(component, rawIssue); | |||
tracked.setCreationDate(analysisDate); | |||
trackedIssues.add(tracked); | |||
} | |||
} | |||
private DefaultIssue toTracked(BatchComponent component, BatchReport.Issue rawIssue) { | |||
return new org.sonar.core.issue.DefaultIssueBuilder() | |||
.componentKey(component.key()) | |||
.projectKey("unused") | |||
.ruleKey(RuleKey.of(rawIssue.getRuleRepository(), rawIssue.getRuleKey())) | |||
.effortToFix(rawIssue.hasEffortToFix() ? rawIssue.getEffortToFix() : null) | |||
.line(rawIssue.hasLine() ? rawIssue.getLine() : null) | |||
.message(rawIssue.hasMsg() ? rawIssue.getMsg() : null) | |||
.severity(rawIssue.getSeverity().name()) | |||
.build(); | |||
} | |||
} |
@@ -19,8 +19,9 @@ | |||
*/ | |||
package org.sonar.batch.issue.tracking; | |||
import org.sonar.api.batch.fs.InputFile.Status; | |||
import org.sonar.batch.issue.IssueTransformer; | |||
import org.sonar.api.batch.fs.InputFile.Status; | |||
import org.sonar.batch.analysis.DefaultAnalysisMode; | |||
import com.google.common.annotations.VisibleForTesting; | |||
import com.google.common.collect.Lists; | |||
@@ -38,42 +39,27 @@ import org.sonar.api.batch.fs.internal.DefaultInputFile; | |||
import org.sonar.api.batch.rule.ActiveRule; | |||
import org.sonar.api.batch.rule.ActiveRules; | |||
import org.sonar.api.issue.Issue; | |||
import org.sonar.api.resources.Project; | |||
import org.sonar.api.resources.ResourceUtils; | |||
import org.sonar.api.rule.RuleKey; | |||
import org.sonar.batch.index.BatchComponent; | |||
import org.sonar.batch.index.BatchComponentCache; | |||
import org.sonar.batch.protocol.output.BatchReport; | |||
import org.sonar.batch.report.ReportPublisher; | |||
import org.sonar.batch.repository.ProjectRepositories; | |||
import org.sonar.core.component.ComponentKeys; | |||
import org.sonar.core.issue.DefaultIssue; | |||
import org.sonar.core.issue.IssueChangeContext; | |||
import org.sonar.core.issue.IssueUpdater; | |||
@BatchSide | |||
public class LocalIssueTracking { | |||
private final IssueTracking tracking; | |||
private final ServerLineHashesLoader lastLineHashes; | |||
private final IssueUpdater updater; | |||
private final IssueChangeContext changeContext; | |||
private final ActiveRules activeRules; | |||
private final ServerIssueRepository serverIssueRepository; | |||
private final Date analysisDate; | |||
private final DefaultAnalysisMode mode; | |||
private boolean hasServerAnalysis; | |||
public LocalIssueTracking(BatchComponentCache resourceCache, IssueTracking tracking, ServerLineHashesLoader lastLineHashes, IssueUpdater updater, | |||
ActiveRules activeRules, ServerIssueRepository serverIssueRepository, ProjectRepositories projectRepositories, ReportPublisher reportPublisher, | |||
DefaultAnalysisMode mode) { | |||
public LocalIssueTracking(IssueTracking tracking, ServerLineHashesLoader lastLineHashes, | |||
ActiveRules activeRules, ServerIssueRepository serverIssueRepository, ProjectRepositories projectRepositories, DefaultAnalysisMode mode) { | |||
this.tracking = tracking; | |||
this.lastLineHashes = lastLineHashes; | |||
this.updater = updater; | |||
this.serverIssueRepository = serverIssueRepository; | |||
this.mode = mode; | |||
this.analysisDate = ((Project) resourceCache.getRoot().resource()).getAnalysisDate(); | |||
this.changeContext = IssueChangeContext.createScan(analysisDate); | |||
this.activeRules = activeRules; | |||
this.hasServerAnalysis = projectRepositories.lastAnalysisDate() != null; | |||
} | |||
@@ -84,8 +70,8 @@ public class LocalIssueTracking { | |||
} | |||
} | |||
public List<DefaultIssue> trackIssues(BatchComponent component, Set<BatchReport.Issue> rawIssues) { | |||
List<DefaultIssue> trackedIssues = Lists.newArrayList(); | |||
public List<TrackedIssue> trackIssues(BatchComponent component, Set<BatchReport.Issue> rawIssues) { | |||
List<TrackedIssue> trackedIssues = Lists.newArrayList(); | |||
if (hasServerAnalysis) { | |||
// all the issues that are not closed in db before starting this module scan, including manual issues | |||
Collection<ServerIssue> serverIssues = loadServerIssues(component); | |||
@@ -124,33 +110,23 @@ public class LocalIssueTracking { | |||
return false; | |||
} | |||
private void copyServerIssues(Collection<ServerIssue> serverIssues, List<DefaultIssue> trackedIssues) { | |||
private void copyServerIssues(Collection<ServerIssue> serverIssues, List<TrackedIssue> trackedIssues) { | |||
for (ServerIssue serverIssue : serverIssues) { | |||
org.sonar.batch.protocol.input.BatchInput.ServerIssue unmatchedPreviousIssue = ((ServerIssueFromWs) serverIssue).getDto(); | |||
DefaultIssue unmatched = toUnmatchedIssue(unmatchedPreviousIssue); | |||
TrackedIssue unmatched = IssueTransformer.toTrackedIssue(unmatchedPreviousIssue); | |||
ActiveRule activeRule = activeRules.find(unmatched.ruleKey()); | |||
unmatched.setNew(false); | |||
boolean isRemovedRule = activeRule == null; | |||
unmatched.setBeingClosed(isRemovedRule); | |||
unmatched.setOnDisabledRule(isRemovedRule); | |||
if (activeRule == null) { | |||
// rule removed | |||
IssueTransformer.resolveRemove(unmatched); | |||
} | |||
trackedIssues.add(unmatched); | |||
} | |||
} | |||
private DefaultIssue toTracked(BatchComponent component, BatchReport.Issue rawIssue) { | |||
return new org.sonar.core.issue.DefaultIssueBuilder() | |||
.componentKey(component.key()) | |||
.projectKey("unused") | |||
.ruleKey(RuleKey.of(rawIssue.getRuleRepository(), rawIssue.getRuleKey())) | |||
.effortToFix(rawIssue.hasEffortToFix() ? rawIssue.getEffortToFix() : null) | |||
.line(rawIssue.hasLine() ? rawIssue.getLine() : null) | |||
.message(rawIssue.hasMsg() ? rawIssue.getMsg() : null) | |||
.severity(rawIssue.getSeverity().name()) | |||
.build(); | |||
} | |||
@CheckForNull | |||
private SourceHashHolder loadSourceHashes(BatchComponent component) { | |||
SourceHashHolder sourceHashHolder = null; | |||
@@ -173,20 +149,18 @@ public class LocalIssueTracking { | |||
} | |||
@VisibleForTesting | |||
protected void mergeMatched(BatchComponent component, IssueTrackingResult result, List<DefaultIssue> trackedIssues, Collection<BatchReport.Issue> rawIssues) { | |||
protected void mergeMatched(BatchComponent component, IssueTrackingResult result, List<TrackedIssue> trackedIssues, Collection<BatchReport.Issue> rawIssues) { | |||
for (BatchReport.Issue rawIssue : result.matched()) { | |||
rawIssues.remove(rawIssue); | |||
org.sonar.batch.protocol.input.BatchInput.ServerIssue ref = ((ServerIssueFromWs) result.matching(rawIssue)).getDto(); | |||
DefaultIssue tracked = toTracked(component, rawIssue); | |||
TrackedIssue tracked = IssueTransformer.toTrackedIssue(component, rawIssue); | |||
// invariant fields | |||
tracked.setKey(ref.getKey()); | |||
// non-persisted fields | |||
tracked.setNew(false); | |||
tracked.setBeingClosed(false); | |||
tracked.setOnDisabledRule(false); | |||
// fields to update with old values | |||
tracked.setResolution(ref.hasResolution() ? ref.getResolution() : null); | |||
@@ -202,10 +176,10 @@ public class LocalIssueTracking { | |||
} | |||
} | |||
private void addUnmatchedFromServer(Collection<ServerIssue> unmatchedIssues, SourceHashHolder sourceHashHolder, Collection<DefaultIssue> issues) { | |||
private void addUnmatchedFromServer(Collection<ServerIssue> unmatchedIssues, SourceHashHolder sourceHashHolder, Collection<TrackedIssue> issues) { | |||
for (ServerIssue unmatchedIssue : unmatchedIssues) { | |||
org.sonar.batch.protocol.input.BatchInput.ServerIssue unmatchedPreviousIssue = ((ServerIssueFromWs) unmatchedIssue).getDto(); | |||
DefaultIssue unmatched = toUnmatchedIssue(unmatchedPreviousIssue); | |||
TrackedIssue unmatched = IssueTransformer.toTrackedIssue(unmatchedPreviousIssue); | |||
if (unmatchedIssue.ruleKey().isManual() && !Issue.STATUS_CLOSED.equals(unmatchedPreviousIssue.getStatus())) { | |||
relocateManualIssue(unmatched, unmatchedIssue, sourceHashHolder); | |||
} | |||
@@ -214,46 +188,29 @@ public class LocalIssueTracking { | |||
} | |||
} | |||
private void addIssuesOnDeletedComponents(Collection<DefaultIssue> issues) { | |||
private void addIssuesOnDeletedComponents(Collection<TrackedIssue> issues) { | |||
for (org.sonar.batch.protocol.input.BatchInput.ServerIssue previous : serverIssueRepository.issuesOnMissingComponents()) { | |||
DefaultIssue dead = toUnmatchedIssue(previous); | |||
TrackedIssue dead = IssueTransformer.toTrackedIssue(previous); | |||
updateUnmatchedIssue(dead, true); | |||
issues.add(dead); | |||
} | |||
} | |||
private DefaultIssue toUnmatchedIssue(org.sonar.batch.protocol.input.BatchInput.ServerIssue serverIssue) { | |||
DefaultIssue issue = new DefaultIssue(); | |||
issue.setKey(serverIssue.getKey()); | |||
issue.setStatus(serverIssue.getStatus()); | |||
issue.setResolution(serverIssue.hasResolution() ? serverIssue.getResolution() : null); | |||
issue.setMessage(serverIssue.hasMsg() ? serverIssue.getMsg() : null); | |||
issue.setLine(serverIssue.hasLine() ? serverIssue.getLine() : null); | |||
issue.setSeverity(serverIssue.getSeverity().name()); | |||
issue.setAssignee(serverIssue.hasAssigneeLogin() ? serverIssue.getAssigneeLogin() : null); | |||
issue.setComponentKey(ComponentKeys.createEffectiveKey(serverIssue.getModuleKey(), serverIssue.hasPath() ? serverIssue.getPath() : null)); | |||
issue.setManualSeverity(serverIssue.getManualSeverity()); | |||
issue.setCreationDate(new Date(serverIssue.getCreationDate())); | |||
issue.setRuleKey(RuleKey.of(serverIssue.getRuleRepository(), serverIssue.getRuleKey())); | |||
issue.setNew(false); | |||
return issue; | |||
} | |||
private void updateUnmatchedIssue(DefaultIssue issue, boolean forceEndOfLife) { | |||
private void updateUnmatchedIssue(TrackedIssue issue, boolean forceEndOfLife) { | |||
ActiveRule activeRule = activeRules.find(issue.ruleKey()); | |||
issue.setNew(false); | |||
boolean manualIssue = issue.ruleKey().isManual(); | |||
boolean isRemovedRule = activeRule == null; | |||
if (manualIssue) { | |||
issue.setBeingClosed(forceEndOfLife || isRemovedRule); | |||
} else { | |||
issue.setBeingClosed(true); | |||
if (isRemovedRule) { | |||
IssueTransformer.resolveRemove(issue); | |||
} else if (forceEndOfLife || !manualIssue) { | |||
IssueTransformer.close(issue); | |||
} | |||
issue.setOnDisabledRule(isRemovedRule); | |||
} | |||
private void relocateManualIssue(DefaultIssue newIssue, ServerIssue oldIssue, SourceHashHolder sourceHashHolder) { | |||
private static void relocateManualIssue(TrackedIssue newIssue, ServerIssue oldIssue, SourceHashHolder sourceHashHolder) { | |||
Integer previousLine = oldIssue.line(); | |||
if (previousLine == null) { | |||
return; | |||
@@ -262,17 +219,12 @@ public class LocalIssueTracking { | |||
Collection<Integer> newLinesWithSameHash = sourceHashHolder.getNewLinesMatching(previousLine); | |||
if (newLinesWithSameHash.isEmpty()) { | |||
if (previousLine > sourceHashHolder.getHashedSource().length()) { | |||
newIssue.setLine(null); | |||
updater.setStatus(newIssue, Issue.STATUS_CLOSED, changeContext); | |||
updater.setResolution(newIssue, Issue.RESOLUTION_REMOVED, changeContext); | |||
updater.setPastLine(newIssue, previousLine); | |||
updater.setPastMessage(newIssue, oldIssue.message(), changeContext); | |||
IssueTransformer.resolveRemove(newIssue); | |||
} | |||
} else if (newLinesWithSameHash.size() == 1) { | |||
Integer newLine = newLinesWithSameHash.iterator().next(); | |||
newIssue.setLine(newLine); | |||
updater.setPastLine(newIssue, previousLine); | |||
updater.setPastMessage(newIssue, oldIssue.message(), changeContext); | |||
newIssue.setStartLine(newLine); | |||
newIssue.setEndLine(newLine); | |||
} | |||
} | |||
} |
@@ -0,0 +1,206 @@ | |||
/* | |||
* SonarQube, open source software quality management tool. | |||
* Copyright (C) 2008-2014 SonarSource | |||
* mailto:contact AT sonarsource DOT com | |||
* | |||
* SonarQube 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. | |||
* | |||
* SonarQube 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.batch.issue.tracking; | |||
import java.io.Serializable; | |||
import java.util.Date; | |||
import org.sonar.api.rule.RuleKey; | |||
public class TrackedIssue implements Serializable { | |||
private static final long serialVersionUID = -1755017079070964287L; | |||
private RuleKey ruleKey; | |||
private String key; | |||
private String severity; | |||
private Integer startLine; | |||
private Integer startLineOffset; | |||
private Integer endLine; | |||
private Integer endLineOffset; | |||
private Double effortToFix; | |||
private boolean isNew; | |||
private Date creationDate; | |||
private String resolution; | |||
private String status; | |||
private String assignee; | |||
private String reporter; | |||
private String componentKey; | |||
private String message; | |||
public String message() { | |||
return message; | |||
} | |||
public void setMessage(String message) { | |||
this.message = message; | |||
} | |||
public String componentKey() { | |||
return componentKey; | |||
} | |||
public void setComponentKey(String componentKey) { | |||
this.componentKey = componentKey; | |||
} | |||
public String key() { | |||
return key; | |||
} | |||
public Integer startLine() { | |||
return startLine; | |||
} | |||
public void setStartLine(Integer startLine) { | |||
this.startLine = startLine; | |||
} | |||
public Integer startLineOffset() { | |||
return startLineOffset; | |||
} | |||
public void setStartLineOffset(Integer startLineOffset) { | |||
this.startLineOffset = startLineOffset; | |||
} | |||
public Integer endLine() { | |||
return endLine; | |||
} | |||
public void setEndLine(Integer endLine) { | |||
this.endLine = endLine; | |||
} | |||
public Integer endLineOffset() { | |||
return endLineOffset; | |||
} | |||
public void setEndLineOffset(Integer endLineOffset) { | |||
this.endLineOffset = endLineOffset; | |||
} | |||
public void setKey(String key) { | |||
this.key = key; | |||
} | |||
public String assignee() { | |||
return assignee; | |||
} | |||
public void setAssignee(String assignee) { | |||
this.assignee = assignee; | |||
} | |||
public String reporter() { | |||
return reporter; | |||
} | |||
public void setReporter(String reporter) { | |||
this.reporter = reporter; | |||
} | |||
public String resolution() { | |||
return resolution; | |||
} | |||
public void setResolution(String resolution) { | |||
this.resolution = resolution; | |||
} | |||
public String status() { | |||
return status; | |||
} | |||
public void setStatus(String status) { | |||
this.status = status; | |||
} | |||
public RuleKey ruleKey() { | |||
return ruleKey; | |||
} | |||
public String severity() { | |||
return severity; | |||
} | |||
public Double effortToFix() { | |||
return effortToFix; | |||
} | |||
public Date getCreationDate() { | |||
return creationDate; | |||
} | |||
public boolean isNew() { | |||
return isNew; | |||
} | |||
public void setNew(boolean isNew) { | |||
this.isNew = isNew; | |||
} | |||
public Date creationDate() { | |||
return creationDate; | |||
} | |||
public void setCreationDate(Date creationDate) { | |||
this.creationDate = creationDate; | |||
} | |||
public void setRuleKey(RuleKey ruleKey) { | |||
this.ruleKey = ruleKey; | |||
} | |||
public void setSeverity(String severity) { | |||
this.severity = severity; | |||
} | |||
public void setEffortToFix(Double effortToFix) { | |||
this.effortToFix = effortToFix; | |||
} | |||
@Override | |||
public int hashCode() { | |||
final int prime = 31; | |||
int result = 1; | |||
result = prime * result + ((key == null) ? 0 : key.hashCode()); | |||
return result; | |||
} | |||
@Override | |||
public boolean equals(Object obj) { | |||
if (obj == null) { | |||
return false; | |||
} | |||
if (getClass() != obj.getClass()) { | |||
return false; | |||
} | |||
TrackedIssue other = (TrackedIssue) obj; | |||
if (key == null) { | |||
if (other.key != null) { | |||
return false; | |||
} | |||
} else if (!key.equals(other.key)) { | |||
return false; | |||
} | |||
return true; | |||
} | |||
} |
@@ -19,8 +19,11 @@ | |||
*/ | |||
package org.sonar.batch.mediumtest; | |||
import org.sonar.batch.issue.tracking.TrackedIssue; | |||
import com.google.common.collect.Iterators; | |||
import com.google.common.collect.Lists; | |||
import java.io.InputStream; | |||
import java.util.ArrayList; | |||
import java.util.Collection; | |||
@@ -28,8 +31,10 @@ import java.util.Collections; | |||
import java.util.HashMap; | |||
import java.util.List; | |||
import java.util.Map; | |||
import javax.annotation.CheckForNull; | |||
import javax.annotation.Nullable; | |||
import org.apache.commons.io.FileUtils; | |||
import org.slf4j.Logger; | |||
import org.slf4j.LoggerFactory; | |||
@@ -42,7 +47,6 @@ import org.sonar.api.batch.fs.TextRange; | |||
import org.sonar.api.batch.fs.internal.DefaultInputDir; | |||
import org.sonar.api.batch.fs.internal.DefaultInputFile; | |||
import org.sonar.api.batch.sensor.highlighting.TypeOfText; | |||
import org.sonar.api.issue.Issue; | |||
import org.sonar.batch.issue.IssueCache; | |||
import org.sonar.batch.protocol.output.BatchReport; | |||
import org.sonar.batch.protocol.output.BatchReport.Component; | |||
@@ -53,14 +57,13 @@ import org.sonar.batch.report.BatchReportUtils; | |||
import org.sonar.batch.report.ReportPublisher; | |||
import org.sonar.batch.scan.ProjectScanContainer; | |||
import org.sonar.batch.scan.filesystem.InputPathCache; | |||
import org.sonar.core.issue.DefaultIssue; | |||
import org.sonar.core.util.CloseableIterator; | |||
public class TaskResult implements org.sonar.batch.mediumtest.ScanTaskObserver { | |||
private static final Logger LOG = LoggerFactory.getLogger(TaskResult.class); | |||
private List<Issue> issues = new ArrayList<>(); | |||
private List<TrackedIssue> issues = new ArrayList<>(); | |||
private Map<String, InputFile> inputFiles = new HashMap<>(); | |||
private Map<String, Component> reportComponents = new HashMap<>(); | |||
private Map<String, InputDir> inputDirs = new HashMap<>(); | |||
@@ -69,7 +72,7 @@ public class TaskResult implements org.sonar.batch.mediumtest.ScanTaskObserver { | |||
@Override | |||
public void scanTaskCompleted(ProjectScanContainer container) { | |||
LOG.info("Store analysis results in memory for later assertions in medium test"); | |||
for (DefaultIssue issue : container.getComponentByType(IssueCache.class).all()) { | |||
for (TrackedIssue issue : container.getComponentByType(IssueCache.class).all()) { | |||
issues.add(issue); | |||
} | |||
@@ -112,7 +115,7 @@ public class TaskResult implements org.sonar.batch.mediumtest.ScanTaskObserver { | |||
} | |||
} | |||
public List<Issue> trackedIssues() { | |||
public List<TrackedIssue> trackedIssues() { | |||
return issues; | |||
} | |||
@@ -19,10 +19,14 @@ | |||
*/ | |||
package org.sonar.batch.postjob; | |||
import org.sonar.batch.issue.tracking.TrackedIssue; | |||
import com.google.common.base.Function; | |||
import com.google.common.base.Predicate; | |||
import com.google.common.collect.Iterables; | |||
import javax.annotation.Nullable; | |||
import org.sonar.api.batch.AnalysisMode; | |||
import org.sonar.api.batch.fs.InputComponent; | |||
import org.sonar.api.batch.postjob.PostJobContext; | |||
@@ -33,7 +37,6 @@ import org.sonar.api.rule.RuleKey; | |||
import org.sonar.batch.index.BatchComponent; | |||
import org.sonar.batch.index.BatchComponentCache; | |||
import org.sonar.batch.issue.IssueCache; | |||
import org.sonar.core.issue.DefaultIssue; | |||
public class DefaultPostJobContext implements PostJobContext { | |||
@@ -61,29 +64,19 @@ public class DefaultPostJobContext implements PostJobContext { | |||
@Override | |||
public Iterable<Issue> issues() { | |||
return Iterables.transform(Iterables.filter(cache.all(), new ResolvedPredicate(false)), new Function<DefaultIssue, Issue>() { | |||
@Override | |||
public Issue apply(DefaultIssue input) { | |||
return new DefaultIssueWrapper(input); | |||
} | |||
}); | |||
return Iterables.transform(Iterables.filter(cache.all(), new ResolvedPredicate(false)), new IssueTransformer()); | |||
} | |||
@Override | |||
public Iterable<Issue> resolvedIssues() { | |||
return Iterables.transform(Iterables.filter(cache.all(), new ResolvedPredicate(true)), new Function<DefaultIssue, Issue>() { | |||
@Override | |||
public Issue apply(DefaultIssue input) { | |||
return new DefaultIssueWrapper(input); | |||
} | |||
}); | |||
return Iterables.transform(Iterables.filter(cache.all(), new ResolvedPredicate(true)), new IssueTransformer()); | |||
} | |||
private class DefaultIssueWrapper implements Issue { | |||
private final DefaultIssue wrapped; | |||
private final TrackedIssue wrapped; | |||
public DefaultIssueWrapper(DefaultIssue wrapped) { | |||
public DefaultIssueWrapper(TrackedIssue wrapped) { | |||
this.wrapped = wrapped; | |||
} | |||
@@ -110,7 +103,7 @@ public class DefaultPostJobContext implements PostJobContext { | |||
@Override | |||
public Integer line() { | |||
return wrapped.line(); | |||
return wrapped.startLine(); | |||
} | |||
@Override | |||
@@ -133,10 +126,16 @@ public class DefaultPostJobContext implements PostJobContext { | |||
public boolean isNew() { | |||
return wrapped.isNew(); | |||
} | |||
} | |||
private class IssueTransformer implements Function<TrackedIssue, Issue> { | |||
@Override | |||
public Issue apply(TrackedIssue input) { | |||
return new DefaultIssueWrapper(input); | |||
} | |||
} | |||
private static class ResolvedPredicate implements Predicate<DefaultIssue> { | |||
private static class ResolvedPredicate implements Predicate<TrackedIssue> { | |||
private final boolean resolved; | |||
private ResolvedPredicate(boolean resolved) { | |||
@@ -144,7 +143,7 @@ public class DefaultPostJobContext implements PostJobContext { | |||
} | |||
@Override | |||
public boolean apply(@Nullable DefaultIssue issue) { | |||
public boolean apply(@Nullable TrackedIssue issue) { | |||
if (issue != null) { | |||
return resolved ? issue.resolution() != null : issue.resolution() == null; | |||
} |
@@ -19,6 +19,8 @@ | |||
*/ | |||
package org.sonar.batch.scan; | |||
import org.sonar.batch.issue.DefaultProjectIssues; | |||
import com.google.common.annotations.VisibleForTesting; | |||
import org.sonar.api.CoreProperties; | |||
import org.sonar.api.batch.InstantiationStrategy; | |||
@@ -47,7 +49,6 @@ import org.sonar.batch.index.BatchComponentCache; | |||
import org.sonar.batch.index.Caches; | |||
import org.sonar.batch.index.DefaultIndex; | |||
import org.sonar.batch.issue.DefaultIssueCallback; | |||
import org.sonar.batch.issue.DefaultProjectIssues; | |||
import org.sonar.batch.issue.IssueCache; | |||
import org.sonar.batch.issue.tracking.DefaultServerLineHashesLoader; | |||
import org.sonar.batch.issue.tracking.IssueTransition; | |||
@@ -91,9 +92,7 @@ import org.sonar.batch.scan.measure.MeasureCache; | |||
import org.sonar.batch.source.CodeColorizers; | |||
import org.sonar.batch.test.TestPlanBuilder; | |||
import org.sonar.batch.test.TestableBuilder; | |||
import org.sonar.core.issue.IssueUpdater; | |||
import org.sonar.core.issue.workflow.FunctionExecutor; | |||
import org.sonar.core.issue.workflow.IssueWorkflow; | |||
import org.sonar.core.platform.ComponentContainer; | |||
public class ProjectScanContainer extends ComponentContainer { | |||
@@ -166,9 +165,7 @@ public class ProjectScanContainer extends ComponentContainer { | |||
new QualityProfileProvider(), | |||
// issues | |||
IssueUpdater.class, | |||
FunctionExecutor.class, | |||
IssueWorkflow.class, | |||
IssueCache.class, | |||
DefaultProjectIssues.class, | |||
IssueTransition.class, |
@@ -19,6 +19,8 @@ | |||
*/ | |||
package org.sonar.batch.scan.report; | |||
import org.sonar.batch.issue.tracking.TrackedIssue; | |||
import com.google.common.annotations.VisibleForTesting; | |||
import org.apache.commons.lang.StringUtils; | |||
import org.sonar.api.Properties; | |||
@@ -30,7 +32,6 @@ import org.sonar.api.utils.log.Logger; | |||
import org.sonar.api.utils.log.Loggers; | |||
import org.sonar.batch.issue.IssueCache; | |||
import org.sonar.batch.scan.filesystem.InputPathCache; | |||
import org.sonar.core.issue.DefaultIssue; | |||
@Properties({ | |||
@Property(key = ConsoleReport.CONSOLE_REPORT_ENABLED_KEY, name = "Enable console report", description = "Set this to true to generate a report in console output", | |||
@@ -65,7 +66,7 @@ public class ConsoleReport implements Reporter { | |||
int newMinorIssues = 0; | |||
int newInfoIssues = 0; | |||
public void process(DefaultIssue issue) { | |||
public void process(TrackedIssue issue) { | |||
if (issue.isNew()) { | |||
totalNewIssues++; | |||
switch (issue.severity()) { | |||
@@ -100,7 +101,7 @@ public class ConsoleReport implements Reporter { | |||
if (settings.getBoolean(CONSOLE_REPORT_ENABLED_KEY)) { | |||
Report r = new Report(); | |||
r.setNoFile(!inputPathCache.allFiles().iterator().hasNext()); | |||
for (DefaultIssue issue : issueCache.all()) { | |||
for (TrackedIssue issue : issueCache.all()) { | |||
r.process(issue); | |||
} | |||
printReport(r); |
@@ -19,13 +19,16 @@ | |||
*/ | |||
package org.sonar.batch.scan.report; | |||
import org.sonar.batch.issue.tracking.TrackedIssue; | |||
import com.google.common.collect.Maps; | |||
import java.util.ArrayList; | |||
import java.util.Date; | |||
import java.util.List; | |||
import java.util.Map; | |||
import org.sonar.api.batch.rule.Rule; | |||
import org.sonar.api.issue.Issue; | |||
import org.sonar.api.rules.RulePriority; | |||
import org.sonar.batch.index.BatchComponent; | |||
@@ -78,16 +81,16 @@ public class IssuesReport { | |||
return new ArrayList<>(resourceReportsByResource.keySet()); | |||
} | |||
public void addIssueOnResource(BatchComponent resource, Issue issue, Rule rule, RulePriority severity) { | |||
public void addIssueOnResource(BatchComponent resource, TrackedIssue issue, Rule rule, RulePriority severity) { | |||
addResource(resource); | |||
getSummary().addIssue(issue, rule, severity); | |||
resourceReportsByResource.get(resource).addIssue(issue, rule, RulePriority.valueOf(issue.severity())); | |||
} | |||
public void addResolvedIssueOnResource(BatchComponent resource, Issue issue, Rule rule, RulePriority severity) { | |||
public void addResolvedIssueOnResource(BatchComponent resource, TrackedIssue issue, Rule rule, RulePriority severity) { | |||
addResource(resource); | |||
getSummary().addResolvedIssue(issue, rule, severity); | |||
resourceReportsByResource.get(resource).addResolvedIssue(issue, rule, RulePriority.valueOf(issue.severity())); | |||
resourceReportsByResource.get(resource).addResolvedIssue(rule, RulePriority.valueOf(issue.severity())); | |||
} | |||
private void addResource(BatchComponent resource) { |
@@ -19,13 +19,15 @@ | |||
*/ | |||
package org.sonar.batch.scan.report; | |||
import org.sonar.batch.issue.tracking.TrackedIssue; | |||
import javax.annotation.CheckForNull; | |||
import org.slf4j.Logger; | |||
import org.slf4j.LoggerFactory; | |||
import org.sonar.api.batch.BatchSide; | |||
import org.sonar.api.batch.rule.Rule; | |||
import org.sonar.api.batch.rule.Rules; | |||
import org.sonar.api.issue.Issue; | |||
import org.sonar.api.resources.Project; | |||
import org.sonar.api.rules.RulePriority; | |||
import org.sonar.batch.DefaultProjectTree; | |||
@@ -33,7 +35,6 @@ import org.sonar.batch.index.BatchComponent; | |||
import org.sonar.batch.index.BatchComponentCache; | |||
import org.sonar.batch.issue.IssueCache; | |||
import org.sonar.batch.scan.filesystem.InputPathCache; | |||
import org.sonar.core.issue.DefaultIssue; | |||
@BatchSide | |||
public class IssuesReportBuilder { | |||
@@ -66,8 +67,8 @@ public class IssuesReportBuilder { | |||
return issuesReport; | |||
} | |||
private void processIssues(IssuesReport issuesReport, Iterable<DefaultIssue> issues) { | |||
for (Issue issue : issues) { | |||
private void processIssues(IssuesReport issuesReport, Iterable<TrackedIssue> issues) { | |||
for (TrackedIssue issue : issues) { | |||
Rule rule = findRule(issue); | |||
RulePriority severity = RulePriority.valueOf(issue.severity()); | |||
BatchComponent resource = resourceCache.get(issue.componentKey()); | |||
@@ -82,7 +83,7 @@ public class IssuesReportBuilder { | |||
} | |||
} | |||
private static boolean validate(Issue issue, Rule rule, BatchComponent resource) { | |||
private static boolean validate(TrackedIssue issue, Rule rule, BatchComponent resource) { | |||
if (rule == null) { | |||
LOG.warn("Unknow rule for issue {}", issue); | |||
return false; | |||
@@ -95,7 +96,7 @@ public class IssuesReportBuilder { | |||
} | |||
@CheckForNull | |||
private Rule findRule(Issue issue) { | |||
private Rule findRule(TrackedIssue issue) { | |||
return rules.find(issue.ruleKey()); | |||
} | |||
@@ -19,8 +19,9 @@ | |||
*/ | |||
package org.sonar.batch.scan.report; | |||
import org.sonar.batch.protocol.input.BatchInput.User; | |||
import org.sonar.batch.issue.tracking.TrackedIssue; | |||
import org.sonar.batch.protocol.input.BatchInput.User; | |||
import com.google.common.annotations.VisibleForTesting; | |||
import java.io.BufferedWriter; | |||
@@ -57,7 +58,6 @@ import org.sonar.batch.issue.IssueCache; | |||
import org.sonar.batch.protocol.input.BatchInput; | |||
import org.sonar.batch.repository.user.UserRepositoryLoader; | |||
import org.sonar.batch.scan.filesystem.InputPathCache; | |||
import org.sonar.core.issue.DefaultIssue; | |||
import static com.google.common.collect.Sets.newHashSet; | |||
@Properties({ | |||
@@ -133,13 +133,17 @@ public class JSONReport implements Reporter { | |||
private void writeJsonIssues(JsonWriter json, Set<RuleKey> ruleKeys, Set<String> logins) throws IOException { | |||
json.name("issues").beginArray(); | |||
for (DefaultIssue issue : getIssues()) { | |||
for (TrackedIssue issue : getIssues()) { | |||
if (issue.resolution() == null) { | |||
json | |||
.beginObject() | |||
.prop("key", issue.key()) | |||
.prop("component", issue.componentKey()) | |||
.prop("line", issue.line()) | |||
.prop("line", issue.startLine()) | |||
.prop("startLine", issue.startLine()) | |||
.prop("startOffset", issue.startLineOffset()) | |||
.prop("endLine", issue.endLine()) | |||
.prop("endOffset", issue.endLineOffset()) | |||
.prop("message", issue.message()) | |||
.prop("severity", issue.severity()) | |||
.prop("rule", issue.ruleKey().toString()) | |||
@@ -240,7 +244,7 @@ public class JSONReport implements Reporter { | |||
} | |||
@VisibleForTesting | |||
Iterable<DefaultIssue> getIssues() { | |||
Iterable<TrackedIssue> getIssues() { | |||
return issueCache.all(); | |||
} | |||
} |
@@ -19,13 +19,16 @@ | |||
*/ | |||
package org.sonar.batch.scan.report; | |||
import org.sonar.batch.issue.tracking.TrackedIssue; | |||
import com.google.common.collect.Maps; | |||
import java.util.ArrayList; | |||
import java.util.Collections; | |||
import java.util.List; | |||
import java.util.Map; | |||
import org.sonar.api.batch.rule.Rule; | |||
import org.sonar.api.issue.Issue; | |||
import org.sonar.api.rules.RulePriority; | |||
public class ReportSummary { | |||
@@ -40,7 +43,7 @@ public class ReportSummary { | |||
return total; | |||
} | |||
public void addIssue(Issue issue, Rule rule, RulePriority severity) { | |||
public void addIssue(TrackedIssue issue, Rule rule, RulePriority severity) { | |||
ReportRuleKey reportRuleKey = new ReportRuleKey(rule, severity); | |||
initMaps(reportRuleKey); | |||
ruleReportByRuleKey.get(reportRuleKey).getTotal().incrementCountInCurrentAnalysis(); | |||
@@ -63,7 +66,7 @@ public class ReportSummary { | |||
return totalByRuleKey; | |||
} | |||
public void addResolvedIssue(Issue issue, Rule rule, RulePriority severity) { | |||
public void addResolvedIssue(TrackedIssue issue, Rule rule, RulePriority severity) { | |||
ReportRuleKey reportRuleKey = new ReportRuleKey(rule, severity); | |||
initMaps(reportRuleKey); | |||
total.incrementResolvedIssuesCount(); |
@@ -19,10 +19,10 @@ | |||
*/ | |||
package org.sonar.batch.scan.report; | |||
import org.sonar.api.batch.rule.Rule; | |||
import org.sonar.batch.issue.tracking.TrackedIssue; | |||
import org.sonar.api.batch.rule.Rule; | |||
import com.google.common.collect.Maps; | |||
import org.sonar.api.issue.Issue; | |||
import org.sonar.api.rules.RulePriority; | |||
import org.sonar.batch.index.BatchComponent; | |||
@@ -37,9 +37,9 @@ public final class ResourceReport { | |||
private final IssueVariation total = new IssueVariation(); | |||
private final Map<ReportRuleKey, RuleReport> ruleReportByRuleKey = Maps.newHashMap(); | |||
private List<Issue> issues = new ArrayList<>(); | |||
private Map<Integer, List<Issue>> issuesPerLine = Maps.newHashMap(); | |||
private Map<Integer, List<Issue>> newIssuesPerLine = Maps.newHashMap(); | |||
private List<TrackedIssue> issues = new ArrayList<>(); | |||
private Map<Integer, List<TrackedIssue>> issuesPerLine = Maps.newHashMap(); | |||
private Map<Integer, List<TrackedIssue>> newIssuesPerLine = Maps.newHashMap(); | |||
private Map<Rule, AtomicInteger> issuesByRule = Maps.newHashMap(); | |||
private Map<RulePriority, AtomicInteger> issuesBySeverity = Maps.newHashMap(); | |||
@@ -63,15 +63,15 @@ public final class ResourceReport { | |||
return total; | |||
} | |||
public List<Issue> getIssues() { | |||
public List<TrackedIssue> getIssues() { | |||
return issues; | |||
} | |||
public Map<Integer, List<Issue>> getIssuesPerLine() { | |||
public Map<Integer, List<TrackedIssue>> getIssuesPerLine() { | |||
return issuesPerLine; | |||
} | |||
public List<Issue> getIssuesAtLine(int lineId, boolean all) { | |||
public List<TrackedIssue> getIssuesAtLine(int lineId, boolean all) { | |||
if (all) { | |||
if (issuesPerLine.containsKey(lineId)) { | |||
return issuesPerLine.get(lineId); | |||
@@ -82,14 +82,14 @@ public final class ResourceReport { | |||
return Collections.emptyList(); | |||
} | |||
public void addIssue(Issue issue, Rule rule, RulePriority severity) { | |||
public void addIssue(TrackedIssue issue, Rule rule, RulePriority severity) { | |||
ReportRuleKey reportRuleKey = new ReportRuleKey(rule, severity); | |||
initMaps(reportRuleKey); | |||
issues.add(issue); | |||
Integer line = issue.line(); | |||
Integer line = issue.startLine(); | |||
line = line != null ? line : 0; | |||
if (!issuesPerLine.containsKey(line)) { | |||
issuesPerLine.put(line, new ArrayList<Issue>()); | |||
issuesPerLine.put(line, new ArrayList<TrackedIssue>()); | |||
} | |||
issuesPerLine.get(line).add(issue); | |||
if (!issuesByRule.containsKey(rule)) { | |||
@@ -104,7 +104,7 @@ public final class ResourceReport { | |||
total.incrementCountInCurrentAnalysis(); | |||
if (issue.isNew()) { | |||
if (!newIssuesPerLine.containsKey(line)) { | |||
newIssuesPerLine.put(line, new ArrayList<Issue>()); | |||
newIssuesPerLine.put(line, new ArrayList<TrackedIssue>()); | |||
} | |||
newIssuesPerLine.get(line).add(issue); | |||
total.incrementNewIssuesCount(); | |||
@@ -112,7 +112,7 @@ public final class ResourceReport { | |||
} | |||
} | |||
public void addResolvedIssue(Issue issue, Rule rule, RulePriority severity) { | |||
public void addResolvedIssue(Rule rule, RulePriority severity) { | |||
ReportRuleKey reportRuleKey = new ReportRuleKey(rule, severity); | |||
initMaps(reportRuleKey); | |||
total.incrementResolvedIssuesCount(); | |||
@@ -139,10 +139,10 @@ public final class ResourceReport { | |||
private boolean hasIssues(Integer lineId, boolean all) { | |||
if (all) { | |||
List<Issue> issuesAtLine = issuesPerLine.get(lineId); | |||
List<TrackedIssue> issuesAtLine = issuesPerLine.get(lineId); | |||
return issuesAtLine != null && !issuesAtLine.isEmpty(); | |||
} | |||
List<Issue> newIssuesAtLine = newIssuesPerLine.get(lineId); | |||
List<TrackedIssue> newIssuesAtLine = newIssuesPerLine.get(lineId); | |||
return newIssuesAtLine != null && !newIssuesAtLine.isEmpty(); | |||
} | |||
@@ -13,7 +13,7 @@ | |||
<#assign issues=resourceReport.getIssues()> | |||
<#list issues as issue> | |||
<#if complete || issue.isNew()> | |||
{'k': '${issue.key()}', 'r': 'R${issue.ruleKey()}', 'l': ${(issue.line()!0)?c}, 'new': ${issue.isNew()?string}, 's': '${issue.severity()?lower_case}'}<#if issue_has_next>,</#if> | |||
{'k': '${issue.key()}', 'r': 'R${issue.ruleKey()}', 'l': ${(issue.startLine()!0)?c}, 'new': ${issue.isNew()?string}, 's': '${issue.severity()?lower_case}'}<#if issue_has_next>,</#if> | |||
</#if> | |||
</#list> | |||
] |
@@ -21,6 +21,9 @@ package org.sonar.batch.issue; | |||
import static org.mockito.Mockito.mock; | |||
import static org.mockito.Mockito.when; | |||
import org.sonar.batch.issue.tracking.TrackedIssue; | |||
import org.sonar.api.batch.rule.Rule; | |||
import org.sonar.api.rule.RuleKey; | |||
import org.sonar.batch.bootstrapper.IssueListener.Issue; | |||
@@ -32,13 +35,11 @@ import org.sonar.batch.repository.user.UserRepositoryLoader; | |||
import org.sonar.batch.bootstrapper.IssueListener; | |||
import org.junit.Before; | |||
import com.google.common.collect.ImmutableList; | |||
import org.sonar.core.issue.DefaultIssue; | |||
import java.util.LinkedList; | |||
import java.util.List; | |||
import static org.mockito.Matchers.any; | |||
import static org.assertj.core.api.Assertions.assertThat; | |||
import org.junit.Test; | |||
@@ -50,14 +51,14 @@ public class DefaultIssueCallbackTest { | |||
@Mock | |||
private Rules rules; | |||
private DefaultIssue issue; | |||
private TrackedIssue issue; | |||
@Before | |||
public void setUp() { | |||
MockitoAnnotations.initMocks(this); | |||
RuleKey ruleKey = RuleKey.of("repo", "key"); | |||
issue = new DefaultIssue(); | |||
issue = new TrackedIssue(); | |||
issue.setKey("key"); | |||
issue.setAssignee("user"); | |||
issue.setRuleKey(ruleKey); |
@@ -19,6 +19,8 @@ | |||
*/ | |||
package org.sonar.batch.issue; | |||
import org.sonar.batch.issue.tracking.TrackedIssue; | |||
import com.google.common.collect.Lists; | |||
import org.junit.Test; | |||
import org.sonar.api.issue.Issue; | |||
@@ -49,9 +51,9 @@ public class DefaultProjectIssuesTest { | |||
DefaultIssue issueOnRoot = new DefaultIssue().setKey("4").setRuleKey(SQUID_RULE_KEY).setSeverity(Severity.CRITICAL).setComponentKey("org.apache:struts"); | |||
DefaultIssue issueInRoot = new DefaultIssue().setKey("5").setRuleKey(SQUID_RULE_KEY).setSeverity(Severity.CRITICAL).setComponentKey("org.apache:struts:FileInRoot"); | |||
when(cache.all()).thenReturn(Arrays.<DefaultIssue> asList( | |||
issueOnRoot, issueInRoot, | |||
issueOnModule, issueInModule, resolvedIssueInModule | |||
when(cache.all()).thenReturn(Arrays.<TrackedIssue>asList( | |||
toTrackedIssue(issueOnRoot), toTrackedIssue(issueInRoot), | |||
toTrackedIssue(issueOnModule), toTrackedIssue(issueInModule), toTrackedIssue(resolvedIssueInModule) | |||
)); | |||
// unresolved issues | |||
@@ -61,4 +63,16 @@ public class DefaultProjectIssuesTest { | |||
List<Issue> resolvedIssues = Lists.newArrayList(projectIssues.resolvedIssues()); | |||
assertThat(resolvedIssues).containsOnly(resolvedIssueInModule); | |||
} | |||
private TrackedIssue toTrackedIssue(DefaultIssue issue) { | |||
TrackedIssue trackedIssue = new TrackedIssue(); | |||
trackedIssue.setKey(issue.key()); | |||
trackedIssue.setRuleKey(issue.ruleKey()); | |||
trackedIssue.setComponentKey(issue.componentKey()); | |||
trackedIssue.setSeverity(issue.severity()); | |||
trackedIssue.setResolution(issue.resolution()); | |||
return trackedIssue; | |||
} | |||
} |
@@ -19,19 +19,17 @@ | |||
*/ | |||
package org.sonar.batch.issue; | |||
import org.sonar.batch.index.AbstractCachesTest; | |||
import org.sonar.batch.issue.tracking.TrackedIssue; | |||
import org.sonar.batch.index.AbstractCachesTest; | |||
import com.google.common.base.Function; | |||
import com.google.common.collect.Collections2; | |||
import com.google.common.collect.ImmutableList; | |||
import org.junit.Test; | |||
import org.sonar.api.issue.Issue; | |||
import org.sonar.core.issue.DefaultIssue; | |||
import org.sonar.api.rule.Severity; | |||
import javax.annotation.Nullable; | |||
import java.util.Arrays; | |||
import java.util.Collection; | |||
import java.util.List; | |||
@@ -42,28 +40,29 @@ public class IssueCacheTest extends AbstractCachesTest { | |||
@Test | |||
public void should_add_new_issue() { | |||
IssueCache cache = new IssueCache(caches); | |||
DefaultIssue issue1 = new DefaultIssue().setKey("111").setComponentKey("org.struts.Action"); | |||
DefaultIssue issue2 = new DefaultIssue().setKey("222").setComponentKey("org.struts.Action"); | |||
DefaultIssue issue3 = new DefaultIssue().setKey("333").setComponentKey("org.struts.Filter").setTags(Arrays.asList("foo", "bar")); | |||
TrackedIssue issue1 = createIssue("111", "org.struts.Action", null); | |||
TrackedIssue issue2 = createIssue("222", "org.struts.Action", null); | |||
TrackedIssue issue3 = createIssue("333", "org.struts.Filter", null); | |||
issue3.setAssignee("foo"); | |||
cache.put(issue1).put(issue2).put(issue3); | |||
assertThat(issueKeys(cache.byComponent("org.struts.Action"))).containsOnly("111", "222"); | |||
assertThat(issueKeys(cache.byComponent("org.struts.Filter"))).containsOnly("333"); | |||
assertThat(cache.byComponent("org.struts.Filter").iterator().next().tags()).containsOnly("foo", "bar"); | |||
assertThat(cache.byComponent("org.struts.Filter").iterator().next().assignee()).isEqualTo("foo"); | |||
} | |||
@Test | |||
public void should_update_existing_issue() { | |||
IssueCache cache = new IssueCache(caches); | |||
DefaultIssue issue = new DefaultIssue().setKey("111").setComponentKey("org.struts.Action").setSeverity(Severity.BLOCKER); | |||
TrackedIssue issue = createIssue("111", "org.struts.Action", Severity.BLOCKER); | |||
cache.put(issue); | |||
issue.setSeverity(Severity.MINOR); | |||
cache.put(issue); | |||
List<DefaultIssue> issues = ImmutableList.copyOf(cache.byComponent("org.struts.Action")); | |||
List<TrackedIssue> issues = ImmutableList.copyOf(cache.byComponent("org.struts.Action")); | |||
assertThat(issues).hasSize(1); | |||
Issue reloaded = issues.iterator().next(); | |||
TrackedIssue reloaded = issues.iterator().next(); | |||
assertThat(reloaded.key()).isEqualTo("111"); | |||
assertThat(reloaded.severity()).isEqualTo(Severity.MINOR); | |||
} | |||
@@ -71,20 +70,29 @@ public class IssueCacheTest extends AbstractCachesTest { | |||
@Test | |||
public void should_get_all_issues() { | |||
IssueCache cache = new IssueCache(caches); | |||
DefaultIssue issue1 = new DefaultIssue().setKey("111").setComponentKey("org.struts.Action").setSeverity(Severity.BLOCKER); | |||
DefaultIssue issue2 = new DefaultIssue().setKey("222").setComponentKey("org.struts.Filter").setSeverity(Severity.INFO); | |||
TrackedIssue issue1 = createIssue("111", "org.struts.Action", Severity.BLOCKER); | |||
TrackedIssue issue2 = createIssue("222", "org.struts.Filter", Severity.INFO); | |||
cache.put(issue1).put(issue2); | |||
List<DefaultIssue> issues = ImmutableList.copyOf(cache.all()); | |||
List<TrackedIssue> issues = ImmutableList.copyOf(cache.all()); | |||
assertThat(issues).containsOnly(issue1, issue2); | |||
} | |||
private Collection<String> issueKeys(Iterable<DefaultIssue> issues) { | |||
return Collections2.transform(ImmutableList.copyOf(issues), new Function<DefaultIssue, String>() { | |||
private Collection<String> issueKeys(Iterable<TrackedIssue> issues) { | |||
return Collections2.transform(ImmutableList.copyOf(issues), new Function<TrackedIssue, String>() { | |||
@Override | |||
public String apply(@Nullable DefaultIssue issue) { | |||
public String apply(@Nullable TrackedIssue issue) { | |||
return issue.key(); | |||
} | |||
}); | |||
} | |||
private TrackedIssue createIssue(String key, String componentKey, String severity) { | |||
TrackedIssue issue = new TrackedIssue(); | |||
issue.setKey(key); | |||
issue.setComponentKey(componentKey); | |||
issue.setSeverity(severity); | |||
return issue; | |||
} | |||
} |
@@ -88,6 +88,10 @@ public class IssuesMediumTest { | |||
List<Issue> issues = result.issuesFor(result.inputFile("xources/hello/HelloJava.xoo")); | |||
assertThat(issues).hasSize(8 /* lines */); | |||
Issue issue = issues.get(0); | |||
assertThat(issue.getTextRange().getStartLine()).isEqualTo(issue.getLine()); | |||
assertThat(issue.getTextRange().getEndLine()).isEqualTo(issue.getLine()); | |||
} | |||
@Test |
@@ -19,8 +19,9 @@ | |||
*/ | |||
package org.sonar.batch.mediumtest.issuesmode; | |||
import org.apache.commons.io.filefilter.FileFilterUtils; | |||
import org.sonar.batch.issue.tracking.TrackedIssue; | |||
import org.apache.commons.io.filefilter.FileFilterUtils; | |||
import org.apache.commons.io.FileUtils; | |||
import org.sonar.xoo.rule.XooRulesDefinition; | |||
import com.google.common.collect.ImmutableMap; | |||
@@ -76,6 +77,10 @@ public class EmptyFileTest { | |||
.property("sonar.xoo.internalKey", "my/internal/key") | |||
.start(); | |||
for(TrackedIssue i : result.trackedIssues()) { | |||
System.out.println(i.startLine() + " " + i.message()); | |||
} | |||
assertThat(result.trackedIssues()).hasSize(11); | |||
} | |||
@@ -19,7 +19,10 @@ | |||
*/ | |||
package org.sonar.batch.mediumtest.issuesmode; | |||
import org.sonar.batch.issue.tracking.TrackedIssue; | |||
import com.google.common.collect.ImmutableMap; | |||
import java.io.File; | |||
import java.io.IOException; | |||
import java.text.ParseException; | |||
@@ -27,6 +30,7 @@ import java.text.SimpleDateFormat; | |||
import java.util.Date; | |||
import java.util.LinkedList; | |||
import java.util.List; | |||
import org.apache.commons.codec.digest.DigestUtils; | |||
import org.apache.commons.io.FileUtils; | |||
import org.apache.commons.io.filefilter.FileFilterUtils; | |||
@@ -35,7 +39,6 @@ import org.junit.Before; | |||
import org.junit.Test; | |||
import org.junit.rules.TemporaryFolder; | |||
import org.sonar.api.CoreProperties; | |||
import org.sonar.api.issue.Issue; | |||
import org.sonar.api.utils.log.LogTester; | |||
import org.sonar.batch.bootstrapper.IssueListener; | |||
import org.sonar.batch.mediumtest.BatchMediumTester; | |||
@@ -45,7 +48,6 @@ import org.sonar.batch.protocol.input.BatchInput.ServerIssue; | |||
import org.sonar.batch.scan.report.ConsoleReport; | |||
import org.sonar.xoo.XooPlugin; | |||
import org.sonar.xoo.rule.XooRulesDefinition; | |||
import static org.assertj.core.api.Assertions.assertThat; | |||
public class IssueModeAndReportsMediumTest { | |||
@@ -153,9 +155,10 @@ public class IssueModeAndReportsMediumTest { | |||
int newIssues = 0; | |||
int openIssues = 0; | |||
int resolvedIssue = 0; | |||
for (Issue issue : result.trackedIssues()) { | |||
for (TrackedIssue issue : result.trackedIssues()) { | |||
System.out | |||
.println(issue.message() + " " + issue.key() + " " + issue.ruleKey() + " " + issue.isNew() + " " + issue.resolution() + " " + issue.componentKey() + " " + issue.line()); | |||
.println(issue.message() + " " + issue.key() + " " + issue.ruleKey() + " " + issue.isNew() + " " + issue.resolution() + " " + issue.componentKey() + " " | |||
+ issue.startLine()); | |||
if (issue.isNew()) { | |||
newIssues++; | |||
} else if (issue.resolution() != null) { |
@@ -19,6 +19,8 @@ | |||
*/ | |||
package org.sonar.batch.mediumtest.issuesmode; | |||
import org.sonar.batch.issue.tracking.TrackedIssue; | |||
import org.assertj.core.api.Condition; | |||
import com.google.common.io.Resources; | |||
import org.sonar.batch.repository.FileData; | |||
@@ -37,7 +39,6 @@ import org.sonar.xoo.rule.XooRulesDefinition; | |||
import org.junit.rules.TemporaryFolder; | |||
import org.sonar.api.utils.log.LogTester; | |||
import org.junit.Test; | |||
import org.sonar.api.issue.Issue; | |||
import org.sonar.batch.mediumtest.TaskResult; | |||
import java.io.File; | |||
@@ -178,9 +179,9 @@ public class ScanOnlyChangedTest { | |||
} | |||
private static void assertNumberIssuesOnFile(TaskResult result, final String fileNameEndsWith, int issues) { | |||
assertThat(result.trackedIssues()).haveExactly(issues, new Condition<Issue>() { | |||
assertThat(result.trackedIssues()).haveExactly(issues, new Condition<TrackedIssue>() { | |||
@Override | |||
public boolean matches(Issue value) { | |||
public boolean matches(TrackedIssue value) { | |||
return value.componentKey().endsWith(fileNameEndsWith); | |||
} | |||
}); | |||
@@ -190,9 +191,10 @@ public class ScanOnlyChangedTest { | |||
int newIssues = 0; | |||
int openIssues = 0; | |||
int resolvedIssue = 0; | |||
for (Issue issue : result.trackedIssues()) { | |||
for (TrackedIssue issue : result.trackedIssues()) { | |||
System.out | |||
.println(issue.message() + " " + issue.key() + " " + issue.ruleKey() + " " + issue.isNew() + " " + issue.resolution() + " " + issue.componentKey() + " " + issue.line()); | |||
.println(issue.message() + " " + issue.key() + " " + issue.ruleKey() + " " + issue.isNew() + " " + issue.resolution() + " " + issue.componentKey() + " " | |||
+ issue.startLine()); | |||
if (issue.isNew()) { | |||
newIssues++; | |||
} else if (issue.resolution() != null) { |
@@ -19,7 +19,10 @@ | |||
*/ | |||
package org.sonar.batch.postjob; | |||
import org.sonar.batch.issue.tracking.TrackedIssue; | |||
import java.util.Arrays; | |||
import org.junit.Before; | |||
import org.junit.Test; | |||
import org.sonar.api.batch.AnalysisMode; | |||
@@ -30,8 +33,6 @@ import org.sonar.api.config.Settings; | |||
import org.sonar.api.resources.File; | |||
import org.sonar.batch.index.BatchComponentCache; | |||
import org.sonar.batch.issue.IssueCache; | |||
import org.sonar.core.issue.DefaultIssue; | |||
import static org.assertj.core.api.Assertions.assertThat; | |||
import static org.mockito.Mockito.mock; | |||
import static org.mockito.Mockito.when; | |||
@@ -58,12 +59,12 @@ public class DefaultPostJobContextTest { | |||
assertThat(context.settings()).isSameAs(settings); | |||
assertThat(context.analysisMode()).isSameAs(analysisMode); | |||
DefaultIssue defaultIssue = new DefaultIssue(); | |||
TrackedIssue defaultIssue = new TrackedIssue(); | |||
defaultIssue.setComponentKey("foo:src/Foo.php"); | |||
defaultIssue.setEffortToFix(2.0); | |||
defaultIssue.setNew(true); | |||
defaultIssue.setKey("xyz"); | |||
defaultIssue.setLine(1); | |||
defaultIssue.setStartLine(1); | |||
defaultIssue.setMessage("msg"); | |||
defaultIssue.setSeverity("BLOCKER"); | |||
when(issueCache.all()).thenReturn(Arrays.asList(defaultIssue)); |
@@ -19,13 +19,15 @@ | |||
*/ | |||
package org.sonar.batch.scan.report; | |||
import javax.annotation.Nullable; | |||
import org.sonar.batch.issue.tracking.TrackedIssue; | |||
import org.junit.Before; | |||
import org.junit.Rule; | |||
import org.junit.Test; | |||
import org.sonar.api.batch.fs.InputFile; | |||
import org.sonar.api.batch.fs.internal.DefaultInputFile; | |||
import org.sonar.api.config.Settings; | |||
import org.sonar.core.issue.DefaultIssue; | |||
import org.sonar.api.rule.Severity; | |||
import org.sonar.api.utils.log.LogTester; | |||
import org.sonar.batch.issue.IssueCache; | |||
@@ -68,7 +70,7 @@ public class ConsoleReportTest { | |||
public void testNoFile() { | |||
settings.setProperty(ConsoleReport.CONSOLE_REPORT_ENABLED_KEY, "true"); | |||
when(inputPathCache.allFiles()).thenReturn(Collections.<InputFile>emptyList()); | |||
when(issueCache.all()).thenReturn(Collections.<DefaultIssue>emptyList()); | |||
when(issueCache.all()).thenReturn(Collections.<TrackedIssue>emptyList()); | |||
report.execute(); | |||
assertThat(getReportLog()).isEqualTo( | |||
"\n\n------------- Issues Report -------------\n\n" + | |||
@@ -80,7 +82,7 @@ public class ConsoleReportTest { | |||
public void testNoNewIssue() { | |||
settings.setProperty(ConsoleReport.CONSOLE_REPORT_ENABLED_KEY, "true"); | |||
when(inputPathCache.allFiles()).thenReturn(Arrays.<InputFile>asList(new DefaultInputFile("foo", "src/Foo.php"))); | |||
when(issueCache.all()).thenReturn(Arrays.asList(new DefaultIssue().setNew(false))); | |||
when(issueCache.all()).thenReturn(Arrays.asList(createIssue(false, null))); | |||
report.execute(); | |||
assertThat(getReportLog()).isEqualTo( | |||
"\n\n------------- Issues Report -------------\n\n" + | |||
@@ -92,7 +94,7 @@ public class ConsoleReportTest { | |||
public void testOneNewIssue() { | |||
settings.setProperty(ConsoleReport.CONSOLE_REPORT_ENABLED_KEY, "true"); | |||
when(inputPathCache.allFiles()).thenReturn(Arrays.<InputFile>asList(new DefaultInputFile("foo", "src/Foo.php"))); | |||
when(issueCache.all()).thenReturn(Arrays.asList(new DefaultIssue().setNew(true).setSeverity(Severity.BLOCKER))); | |||
when(issueCache.all()).thenReturn(Arrays.asList(createIssue(true, Severity.BLOCKER))); | |||
report.execute(); | |||
assertThat(getReportLog()).isEqualTo( | |||
"\n\n------------- Issues Report -------------\n\n" + | |||
@@ -105,11 +107,12 @@ public class ConsoleReportTest { | |||
public void testOneNewIssuePerSeverity() { | |||
settings.setProperty(ConsoleReport.CONSOLE_REPORT_ENABLED_KEY, "true"); | |||
when(inputPathCache.allFiles()).thenReturn(Arrays.<InputFile>asList(new DefaultInputFile("foo", "src/Foo.php"))); | |||
when(issueCache.all()).thenReturn(Arrays.asList(new DefaultIssue().setNew(true).setSeverity(Severity.BLOCKER), | |||
new DefaultIssue().setNew(true).setSeverity(Severity.CRITICAL), | |||
new DefaultIssue().setNew(true).setSeverity(Severity.MAJOR), | |||
new DefaultIssue().setNew(true).setSeverity(Severity.MINOR), | |||
new DefaultIssue().setNew(true).setSeverity(Severity.INFO))); | |||
when(issueCache.all()).thenReturn(Arrays.asList( | |||
createIssue(true, Severity.BLOCKER), | |||
createIssue(true, Severity.CRITICAL), | |||
createIssue(true, Severity.MAJOR), | |||
createIssue(true, Severity.MINOR), | |||
createIssue(true, Severity.INFO))); | |||
report.execute(); | |||
assertThat(getReportLog()).isEqualTo( | |||
"\n\n------------- Issues Report -------------\n\n" + | |||
@@ -131,4 +134,12 @@ public class ConsoleReportTest { | |||
throw new IllegalStateException("No console report"); | |||
} | |||
private TrackedIssue createIssue(boolean isNew, @Nullable String severity) { | |||
TrackedIssue issue = new TrackedIssue(); | |||
issue.setNew(isNew); | |||
issue.setSeverity(severity); | |||
return issue; | |||
} | |||
} |
@@ -19,6 +19,8 @@ | |||
*/ | |||
package org.sonar.batch.scan.report; | |||
import org.sonar.batch.issue.tracking.TrackedIssue; | |||
import com.google.common.collect.Lists; | |||
import java.io.File; | |||
@@ -49,7 +51,6 @@ import org.sonar.batch.issue.IssueCache; | |||
import org.sonar.batch.protocol.input.BatchInput; | |||
import org.sonar.batch.repository.user.UserRepositoryLoader; | |||
import org.sonar.batch.scan.filesystem.InputPathCache; | |||
import org.sonar.core.issue.DefaultIssue; | |||
import org.sonar.test.JsonAssert; | |||
import static org.assertj.core.api.Assertions.assertThat; | |||
import static org.mockito.Mockito.mock; | |||
@@ -99,21 +100,23 @@ public class JSONReportTest { | |||
@Test | |||
public void should_write_json() throws Exception { | |||
DefaultIssue issue = new DefaultIssue() | |||
.setKey("200") | |||
.setComponentKey("struts:src/main/java/org/apache/struts/Action.java") | |||
.setRuleKey(RuleKey.of("squid", "AvoidCycles")) | |||
.setMessage("There are 2 cycles") | |||
.setSeverity("MINOR") | |||
.setStatus(Issue.STATUS_OPEN) | |||
.setResolution(null) | |||
.setLine(1) | |||
.setEffortToFix(3.14) | |||
.setReporter("julien") | |||
.setAssignee("simon") | |||
.setCreationDate(SIMPLE_DATE_FORMAT.parse("2013-04-24")) | |||
.setUpdateDate(SIMPLE_DATE_FORMAT.parse("2013-04-25")) | |||
.setNew(false); | |||
TrackedIssue issue = new TrackedIssue(); | |||
issue.setKey("200"); | |||
issue.setComponentKey("struts:src/main/java/org/apache/struts/Action.java"); | |||
issue.setRuleKey(RuleKey.of("squid", "AvoidCycles")); | |||
issue.setMessage("There are 2 cycles"); | |||
issue.setSeverity("MINOR"); | |||
issue.setStatus(Issue.STATUS_OPEN); | |||
issue.setResolution(null); | |||
issue.setStartLine(1); | |||
issue.setEndLine(2); | |||
issue.setStartLineOffset(3); | |||
issue.setEndLineOffset(4); | |||
issue.setEffortToFix(3.14); | |||
issue.setReporter("julien"); | |||
issue.setAssignee("simon"); | |||
issue.setCreationDate(SIMPLE_DATE_FORMAT.parse("2013-04-24")); | |||
issue.setNew(false); | |||
when(issueCache.all()).thenReturn(Lists.newArrayList(issue)); | |||
BatchInput.User user1 = BatchInput.User.newBuilder().setLogin("julien").setName("Julien").build(); | |||
BatchInput.User user2 = BatchInput.User.newBuilder().setLogin("simon").setName("Simon").build(); | |||
@@ -129,16 +132,14 @@ public class JSONReportTest { | |||
@Test | |||
public void should_exclude_resolved_issues() throws Exception { | |||
RuleKey ruleKey = RuleKey.of("squid", "AvoidCycles"); | |||
DefaultIssue issue = new DefaultIssue() | |||
.setKey("200") | |||
.setComponentKey("struts:src/main/java/org/apache/struts/Action.java") | |||
.setRuleKey(ruleKey) | |||
.setStatus(Issue.STATUS_CLOSED) | |||
.setResolution(Issue.RESOLUTION_FIXED) | |||
.setCreationDate(SIMPLE_DATE_FORMAT.parse("2013-04-24")) | |||
.setUpdateDate(SIMPLE_DATE_FORMAT.parse("2013-04-25")) | |||
.setCloseDate(SIMPLE_DATE_FORMAT.parse("2013-04-26")) | |||
.setNew(false); | |||
TrackedIssue issue = new TrackedIssue(); | |||
issue.setKey("200"); | |||
issue.setComponentKey("struts:src/main/java/org/apache/struts/Action.java"); | |||
issue.setRuleKey(ruleKey); | |||
issue.setStatus(Issue.STATUS_CLOSED); | |||
issue.setResolution(Issue.RESOLUTION_FIXED); | |||
issue.setCreationDate(SIMPLE_DATE_FORMAT.parse("2013-04-24")); | |||
issue.setNew(false); | |||
when(issueCache.all()).thenReturn(Lists.newArrayList(issue)); | |||
StringWriter writer = new StringWriter(); | |||
@@ -149,7 +150,7 @@ public class JSONReportTest { | |||
@Test | |||
public void should_ignore_components_without_issue() { | |||
when(issueCache.all()).thenReturn(Collections.<DefaultIssue>emptyList()); | |||
when(issueCache.all()).thenReturn(Collections.<TrackedIssue>emptyList()); | |||
StringWriter writer = new StringWriter(); | |||
jsonReport.writeJson(writer); | |||
@@ -172,7 +173,7 @@ public class JSONReportTest { | |||
File workDir = temp.newFolder("sonar"); | |||
fs.setWorkDir(workDir); | |||
when(issueCache.all()).thenReturn(Collections.<DefaultIssue>emptyList()); | |||
when(issueCache.all()).thenReturn(Collections.<TrackedIssue>emptyList()); | |||
settings.setProperty("sonar.report.export.path", "output.json"); | |||
@@ -4,7 +4,10 @@ | |||
{ | |||
"key": "200", | |||
"component": "struts:src/main/java/org/apache/struts/Action.java", | |||
"line": 1, | |||
"startLine": 1, | |||
"startOffset": 3, | |||
"endLine": 2, | |||
"endOffset": 4, | |||
"message": "There are 2 cycles", | |||
"severity": "MINOR", | |||
"rule": "squid:AvoidCycles", |
@@ -32,7 +32,6 @@ import java.util.Set; | |||
import javax.annotation.Nullable; | |||
import org.apache.commons.lang.StringUtils; | |||
import org.apache.commons.lang.time.DateUtils; | |||
import org.sonar.api.batch.BatchSide; | |||
import org.sonar.api.issue.ActionPlan; | |||
import org.sonar.api.server.ServerSide; | |||
import org.sonar.api.server.rule.RuleTagFormat; | |||
@@ -42,7 +41,6 @@ import org.sonar.api.utils.Duration; | |||
/** | |||
* Updates issue fields and chooses if changes must be kept in history. | |||
*/ | |||
@BatchSide | |||
@ServerSide | |||
public class IssueUpdater { | |||
@@ -21,7 +21,6 @@ package org.sonar.core.issue.workflow; | |||
import java.util.List; | |||
import org.picocontainer.Startable; | |||
import org.sonar.api.batch.BatchSide; | |||
import org.sonar.api.issue.DefaultTransitions; | |||
import org.sonar.api.issue.Issue; | |||
import org.sonar.api.issue.condition.HasResolution; | |||
@@ -32,7 +31,6 @@ import org.sonar.core.issue.DefaultIssue; | |||
import org.sonar.core.issue.IssueChangeContext; | |||
import org.sonar.core.issue.IssueUpdater; | |||
@BatchSide | |||
@ServerSide | |||
public class IssueWorkflow implements Startable { | |||