if (context.getSonarQubeVersion().isGreaterThanOrEqual(Version.create(6, 6))) {
context.addExtension(XooBuiltInQualityProfilesDefinition.class);
}
- // TODO change to v7.2 once version of SQ was updated
- if (context.getSonarQubeVersion().isGreaterThanOrEqual(Version.create(7, 1))) {
+ if (context.getSonarQubeVersion().isGreaterThanOrEqual(Version.create(7, 2))) {
context.addExtension(OneExternalIssuePerLineSensor.class);
}
}
.on(file)
.at(file.selectLine(line))
.message("This issue is generated on each line"))
- .ruleTitle(NAME)
- .descriptionUrl("http://oneexternalissueperline.xoo.net")
.severity(Severity.valueOf(SEVERITY))
.remediationEffort(EFFORT)
.type(type)
Severity severity();
- /**
- * Link to a page describing more details about the rule that triggered this issue.
- */
- @CheckForNull
- String descriptionUrl();
-
/**
* Effort to fix the issue, in minutes.
*/
* Type of the issue.
*/
RuleType type();
-
- /**
- * Short description of the rule. Should not depend on the issue being raised.
- */
- String ruleTitle();
+
}
*/
NewExternalIssue addLocation(NewIssueLocation secondaryLocation);
- /**
- * Add a URL pointing to more information about the rule triggering this issue.
- */
- NewExternalIssue descriptionUrl(String url);
-
/**
* Register a flow for this issue. A flow is an ordered list of issue locations that help to understand the issue.
* It should be a <b>path that backtracks the issue from its primary location to the start of the flow</b>.
*/
NewIssueLocation newLocation();
- /**
- * Add the description of the rule. Should not depend on the issue being raised.
- */
- NewExternalIssue ruleTitle(String title);
-
/**
* Save the issue. If rule key is unknown or rule not enabled in the current quality profile then a warning is logged but no exception
* is thrown.
public class DefaultExternalIssue extends AbstractDefaultIssue<DefaultExternalIssue> implements ExternalIssue, NewExternalIssue {
private Long effort;
private Severity severity;
- private String url;
private RuleType type;
- private String ruleTitle;
public DefaultExternalIssue() {
super(null);
requireNonNull(this.ruleKey, "Rule key is mandatory on external issue");
checkState(primaryLocation != null, "Primary location is mandatory on every external issue");
checkState(primaryLocation.inputComponent().isFile(), "External issues must be located in files");
- checkState(ruleTitle != null, "Rule title is mandatory on every external issue");
checkState(severity != null, "Severity is mandatory on every external issue");
checkState(type != null, "Type is mandatory on every external issue");
storage.store(this);
}
- @Override
- public DefaultExternalIssue descriptionUrl(String url) {
- this.url = url;
- return this;
- }
-
- @Override
- public String descriptionUrl() {
- return url;
- }
-
@Override
public RuleType type() {
return type;
return this;
}
- @Override
- public String ruleTitle() {
- return ruleTitle;
- }
-
- @Override
- public DefaultExternalIssue ruleTitle(String ruleTitle) {
- this.ruleTitle = ruleTitle;
- return this;
- }
}
.forRule(RuleKey.of("repo", "rule"))
.type(RuleType.BUG)
.severity(Severity.BLOCKER)
- .ruleTitle("title")
.save();
newExternalIssue = tester.newExternalIssue();
newExternalIssue
.type(RuleType.BUG)
.severity(Severity.BLOCKER)
.forRule(RuleKey.of("repo", "rule"))
- .ruleTitle("title")
.save();
assertThat(tester.allExternalIssues()).hasSize(2);
}
.message("Wrong way!"))
.forRule(RuleKey.of("repo", "rule"))
.remediationEffort(10l)
- .descriptionUrl("url")
.type(RuleType.BUG)
- .ruleTitle("rule")
.severity(Severity.BLOCKER);
assertThat(issue.primaryLocation().inputComponent()).isEqualTo(inputFile);
assertThat(issue.ruleKey()).isEqualTo(RuleKey.of("repo", "rule"));
assertThat(issue.primaryLocation().textRange().start().line()).isEqualTo(1);
assertThat(issue.remediationEffort()).isEqualTo(10l);
- assertThat(issue.descriptionUrl()).isEqualTo("url");
assertThat(issue.type()).isEqualTo(RuleType.BUG);
assertThat(issue.severity()).isEqualTo(Severity.BLOCKER);
- assertThat(issue.ruleTitle()).isEqualTo("rule");
assertThat(issue.primaryLocation().message()).isEqualTo("Wrong way!");
issue.save();
.message("Wrong way!"))
.forRule(RuleKey.of("repo", "rule"))
.remediationEffort(10l)
- .descriptionUrl("url")
- .ruleTitle("rule")
.severity(Severity.BLOCKER);
exception.expect(IllegalStateException.class);
.message("Wrong way!"))
.forRule(RuleKey.of("repo", "rule"))
.remediationEffort(10l)
- .descriptionUrl("url")
- .ruleTitle("rule")
.severity(Severity.BLOCKER);
exception.expect(IllegalStateException.class);
.message("Wrong way!"))
.forRule(RuleKey.of("repo", "rule"))
.remediationEffort(10l)
- .descriptionUrl("url")
- .ruleTitle("rule")
.type(RuleType.BUG);
exception.expect(IllegalStateException.class);
issue.save();
}
- @Test
- public void fail_to_store_if_no_rule_title() {
- SensorStorage storage = mock(SensorStorage.class);
- DefaultExternalIssue issue = new DefaultExternalIssue(storage)
- .at(new DefaultIssueLocation()
- .on(inputFile)
- .at(inputFile.selectLine(1))
- .message("Wrong way!"))
- .forRule(RuleKey.of("repo", "rule"))
- .remediationEffort(10l)
- .descriptionUrl("url")
- .severity(Severity.BLOCKER)
- .type(RuleType.BUG);
-
- exception.expect(IllegalStateException.class);
- exception.expectMessage("Rule title is mandatory");
- issue.save();
- }
-
}
}
private static ScannerReport.ExternalIssue createReportExternalIssue(ExternalIssue issue, int componentRef) {
- String primaryMessage = Strings.isNullOrEmpty(issue.primaryLocation().message()) ? issue.ruleTitle() : issue.primaryLocation().message();
+ String primaryMessage = Strings.isNullOrEmpty(issue.primaryLocation().message()) ? issue.ruleKey().toString() : issue.primaryLocation().message();
Severity severity = Severity.valueOf(issue.severity().name());
ScannerReport.ExternalIssue.Builder builder = ScannerReport.ExternalIssue.newBuilder();
builder.setSeverity(severity);
builder.setRuleRepository(issue.ruleKey().repository());
builder.setRuleKey(issue.ruleKey().rule());
- builder.setRuleTitle(issue.ruleTitle());
builder.setMsg(primaryMessage);
locationBuilder.setMsg(primaryMessage);
return this;
}
- @Override
- public NewExternalIssue descriptionUrl(String url) {
- // no op
- return this;
- }
-
@Override
public NewExternalIssue addFlow(Iterable<NewIssueLocation> flowLocations) {
// no op
return new DefaultIssueLocation();
}
- @Override
- public NewExternalIssue ruleTitle(String title) {
- // no op
- return this;
- }
-
@Override
public void save() {
// no op
DefaultExternalIssue issue = new DefaultExternalIssue()
.at(new DefaultIssueLocation().on(file).at(file.selectLine(3)).message("Foo"))
.forRule(SQUID_RULE_KEY)
- .severity(org.sonar.api.batch.rule.Severity.CRITICAL)
- .ruleTitle("title");
+ .severity(org.sonar.api.batch.rule.Severity.CRITICAL);
moduleIssues.initAndAddExternalIssue(issue);
// Will be identical to the first location of the first flow
TextRange text_range = 6;
repeated Flow flow = 7;
- // Can be empty as the field is optional
- string descriptionUrl = 8;
- IssueType type = 9;
- string rule_title = 10;
+ IssueType type = 8;
}
enum IssueType {