private static boolean noSonar(DefaultInputComponent inputComponent, Issue issue) { TextRange textRange = issue.primaryLocation().textRange(); return inputComponent.isFile() && textRange != null && ((DefaultInputFile) inputComponent).hasNoSonarAt(textRange.start().line()) && !StringUtils.containsIgnoreCase(issue.ruleKey().rule(), "nosonar"); }
private static void applyFlows(Consumer<ScannerReport.Flow> consumer, ScannerReport.IssueLocation.Builder locationBuilder, ScannerReport.TextRange.Builder textRangeBuilder, Collection<Flow> flows) { ScannerReport.Flow.Builder flowBuilder = ScannerReport.Flow.newBuilder(); for (Flow flow : flows) { if (flow.locations().isEmpty()) { return; } flowBuilder.clear(); for (org.sonar.api.batch.sensor.issue.IssueLocation location : flow.locations()) { int locationComponentRef = ((DefaultInputComponent) location.inputComponent()).scannerId(); locationBuilder.clear(); locationBuilder.setComponentRef(locationComponentRef); String message = location.message(); if (message != null) { locationBuilder.setMsg(message); } TextRange textRange = location.textRange(); if (textRange != null) { locationBuilder.setTextRange(toProtobufTextRange(textRangeBuilder, textRange)); } flowBuilder.addLocation(locationBuilder.build()); } consumer.accept(flowBuilder.build()); } }
@Test public void move_directory_issue_to_project_root() { SensorStorage storage = mock(SensorStorage.class); DefaultIssue issue = new DefaultIssue(project, storage) .at(new DefaultIssueLocation() .on(new DefaultInputDir("foo", "src/main").setModuleBaseDir(project.getBaseDir())) .message("Wrong way!")) .forRule(RuleKey.of("repo", "rule")) .overrideSeverity(Severity.BLOCKER); assertThat(issue.primaryLocation().inputComponent()).isEqualTo(project); assertThat(issue.ruleKey()).isEqualTo(RuleKey.of("repo", "rule")); assertThat(issue.primaryLocation().textRange()).isNull(); assertThat(issue.primaryLocation().message()).isEqualTo("[src/main] Wrong way!"); assertThat(issue.overriddenSeverity()).isEqualTo(Severity.BLOCKER); issue.save(); verify(storage).store(issue); }
@Test public void build_file_issue() { SensorStorage storage = mock(SensorStorage.class); DefaultExternalIssue issue = new DefaultExternalIssue(project, storage) .at(new DefaultIssueLocation() .on(inputFile) .at(inputFile.selectLine(1)) .message("Wrong way!")) .forRule(RuleKey.of("repo", "rule")) .remediationEffortMinutes(10l) .type(RuleType.BUG) .severity(Severity.BLOCKER); assertThat(issue.primaryLocation().inputComponent()).isEqualTo(inputFile); assertThat(issue.ruleKey()).isEqualTo(RuleKey.of("external_repo", "rule")); assertThat(issue.engineId()).isEqualTo("repo"); assertThat(issue.ruleId()).isEqualTo("rule"); assertThat(issue.primaryLocation().textRange().start().line()).isEqualTo(1); assertThat(issue.remediationEffort()).isEqualTo(10l); assertThat(issue.type()).isEqualTo(RuleType.BUG); assertThat(issue.severity()).isEqualTo(Severity.BLOCKER); assertThat(issue.primaryLocation().message()).isEqualTo("Wrong way!"); issue.save(); verify(storage).store(issue); }
@Test public void build_file_issue() { SensorStorage storage = mock(SensorStorage.class); DefaultIssue issue = new DefaultIssue(project, storage) .at(new DefaultIssueLocation() .on(inputFile) .at(inputFile.selectLine(1)) .message("Wrong way!")) .forRule(RuleKey.of("repo", "rule")) .gap(10.0); assertThat(issue.primaryLocation().inputComponent()).isEqualTo(inputFile); assertThat(issue.ruleKey()).isEqualTo(RuleKey.of("repo", "rule")); assertThat(issue.primaryLocation().textRange().start().line()).isEqualTo(1); assertThat(issue.gap()).isEqualTo(10.0); assertThat(issue.primaryLocation().message()).isEqualTo("Wrong way!"); issue.save(); verify(storage).store(issue); }
@Test public void move_submodule_issue_to_project_root() { File subModuleDirectory = new File(project.getBaseDir().toString(), "bar"); subModuleDirectory.mkdir(); ProjectDefinition subModuleDefinition = ProjectDefinition.create() .setKey("foo/bar") .setBaseDir(subModuleDirectory) .setWorkDir(subModuleDirectory); project.definition().addSubProject(subModuleDefinition); DefaultInputModule subModule = new DefaultInputModule(subModuleDefinition); SensorStorage storage = mock(SensorStorage.class); DefaultIssue issue = new DefaultIssue(project, storage) .at(new DefaultIssueLocation() .on(subModule) .message("Wrong way!")) .forRule(RuleKey.of("repo", "rule")) .overrideSeverity(Severity.BLOCKER); assertThat(issue.primaryLocation().inputComponent()).isEqualTo(project); assertThat(issue.ruleKey()).isEqualTo(RuleKey.of("repo", "rule")); assertThat(issue.primaryLocation().textRange()).isNull(); assertThat(issue.primaryLocation().message()).isEqualTo("[bar] Wrong way!"); assertThat(issue.overriddenSeverity()).isEqualTo(Severity.BLOCKER); issue.save(); verify(storage).store(issue); }
@Test public void build_project_issue() throws IOException { SensorStorage storage = mock(SensorStorage.class); DefaultInputModule inputModule = new DefaultInputModule(ProjectDefinition.create().setKey("foo").setBaseDir(temp.newFolder()).setWorkDir(temp.newFolder())); DefaultIssue issue = new DefaultIssue(project, storage) .at(new DefaultIssueLocation() .on(inputModule) .message("Wrong way!")) .forRule(RuleKey.of("repo", "rule")) .gap(10.0); assertThat(issue.primaryLocation().inputComponent()).isEqualTo(inputModule); assertThat(issue.ruleKey()).isEqualTo(RuleKey.of("repo", "rule")); assertThat(issue.primaryLocation().textRange()).isNull(); assertThat(issue.gap()).isEqualTo(10.0); assertThat(issue.primaryLocation().message()).isEqualTo("Wrong way!"); issue.save(); verify(storage).store(issue); }
private static ScannerReport.Issue createReportIssue(Issue issue, int componentRef, String activeRuleSeverity) { String primaryMessage = nullToEmpty(issue.primaryLocation().message()); org.sonar.api.batch.rule.Severity overriddenSeverity = issue.overriddenSeverity(); Severity severity = overriddenSeverity != null ? Severity.valueOf(overriddenSeverity.name()) : Severity.valueOf(activeRuleSeverity); ScannerReport.Issue.Builder builder = ScannerReport.Issue.newBuilder(); ScannerReport.IssueLocation.Builder locationBuilder = IssueLocation.newBuilder(); ScannerReport.TextRange.Builder textRangeBuilder = ScannerReport.TextRange.newBuilder(); // non-null fields builder.setSeverity(severity); builder.setRuleRepository(issue.ruleKey().repository()); builder.setRuleKey(issue.ruleKey().rule()); builder.setMsg(primaryMessage); locationBuilder.setMsg(primaryMessage); locationBuilder.setComponentRef(componentRef); TextRange primaryTextRange = issue.primaryLocation().textRange(); if (primaryTextRange != null) { builder.setTextRange(toProtobufTextRange(textRangeBuilder, primaryTextRange)); } Double gap = issue.gap(); if (gap != null) { builder.setGap(gap); } applyFlows(builder::addFlow, locationBuilder, textRangeBuilder, issue.flows()); return builder.build(); }
private static ScannerReport.ExternalIssue createReportExternalIssue(ExternalIssue issue, int componentRef) { // primary location of an external issue must have a message String primaryMessage = issue.primaryLocation().message(); Severity severity = Severity.valueOf(issue.severity().name()); IssueType issueType = IssueType.valueOf(issue.type().name()); ScannerReport.ExternalIssue.Builder builder = ScannerReport.ExternalIssue.newBuilder(); ScannerReport.IssueLocation.Builder locationBuilder = IssueLocation.newBuilder(); ScannerReport.TextRange.Builder textRangeBuilder = ScannerReport.TextRange.newBuilder(); // non-null fields builder.setSeverity(severity); builder.setType(issueType); builder.setEngineId(issue.engineId()); builder.setRuleId(issue.ruleId()); builder.setMsg(primaryMessage); locationBuilder.setMsg(primaryMessage); locationBuilder.setComponentRef(componentRef); TextRange primaryTextRange = issue.primaryLocation().textRange(); if (primaryTextRange != null) { builder.setTextRange(toProtobufTextRange(textRangeBuilder, primaryTextRange)); } Long effort = issue.remediationEffort(); if (effort != null) { builder.setEffort(effort); } applyFlows(builder::addFlow, locationBuilder, textRangeBuilder, issue.flows()); return builder.build(); }
public DefaultFlow(List<IssueLocation> issueLocations) { this.locations = issueLocations.stream() .map(i -> new DefaultLocation( i.inputComponent().isFile() ? ((SonarLintInputFile) i.inputComponent()).getClientInputFile() : null, i.textRange(), i.message())) .collect(Collectors.toList()); }
@Override public Integer line() { TextRange textRange = newIssue.primaryLocation().textRange(); return textRange != null ? textRange.start().line() : null; }
private static boolean noSonar(DefaultInputComponent inputComponent, Issue issue) { TextRange textRange = issue.primaryLocation().textRange(); return inputComponent.isFile() && textRange != null && ((DefaultInputFile) inputComponent).hasNoSonarAt(textRange.start().line()) && !StringUtils.containsIgnoreCase(issue.ruleKey().rule(), "nosonar"); }
@Test void issues_with_sonarqube_72() throws IOException { SensorContextTester context = ExternalLinterSensorHelper.createContext(7, 2); context.settings().setProperty("sonar.go.govet.reportPaths", REPORT_BASE_PATH.resolve("govet-report.txt").toString()); List<ExternalIssue> externalIssues = ExternalLinterSensorHelper.executeSensor(new GoVetReportSensor(), context); assertThat(externalIssues).hasSize(3); ExternalIssue first = externalIssues.get(0); assertThat(first.ruleKey().rule()).isEqualTo("nilfunc"); assertThat(first.severity()).isEqualTo(Severity.MAJOR); assertThat(first.primaryLocation().message()).isEqualTo("comparison of function Foo == nil is always false"); assertThat(first.primaryLocation().textRange().start().line()).isEqualTo(1); ExternalIssue second = externalIssues.get(1); assertThat(second.ruleKey().rule()).isEqualTo("printf"); assertThat(second.severity()).isEqualTo(Severity.MAJOR); assertThat(second.primaryLocation().message()).isEqualTo("Printf format %s has arg &str of wrong type *string"); assertThat(second.primaryLocation().textRange().start().line()).isEqualTo(2); ExternalIssue third = externalIssues.get(2); assertThat(third.ruleKey().rule()).isEqualTo("unreachable"); assertThat(third.severity()).isEqualTo(Severity.MAJOR); assertThat(third.primaryLocation().message()).isEqualTo("unreachable code"); assertThat(third.primaryLocation().textRange().start().line()).isEqualTo(2); assertThat(logTester.logs(LoggerLevel.ERROR)).isEmpty(); }
private static boolean noSonar(InputComponent inputComponent, Issue issue) { TextRange textRange = issue.primaryLocation().textRange(); return inputComponent.isFile() && textRange != null && ((SonarLintInputFile) inputComponent).hasNoSonarAt(textRange.start().line()) && !StringUtils.containsIgnoreCase(issue.ruleKey().rule(), "nosonar"); }
@Test void issues_with_sonarqube_72() throws IOException { SensorContextTester context = ExternalLinterSensorHelper.createContext(7, 2); context.settings().setProperty("sonar.go.golint.reportPaths", REPORT_BASE_PATH.resolve("golint-report.txt").toString()); List<ExternalIssue> externalIssues = ExternalLinterSensorHelper.executeSensor(new GoLintReportSensor(), context); assertThat(externalIssues).hasSize(2); ExternalIssue first = externalIssues.get(0); assertThat(first.type()).isEqualTo(RuleType.CODE_SMELL); assertThat(first.severity()).isEqualTo(Severity.MAJOR); assertThat(first.ruleKey().repository()).isEqualTo("golint"); assertThat(first.ruleKey().rule()).isEqualTo("PackageComment"); assertThat(first.primaryLocation().message()).isEqualTo("package comment should be of the form \"Package samples ...\""); assertThat(first.primaryLocation().textRange().start().line()).isEqualTo(1); ExternalIssue second = externalIssues.get(1); assertThat(second.type()).isEqualTo(RuleType.CODE_SMELL); assertThat(second.severity()).isEqualTo(Severity.MAJOR); assertThat(second.ruleKey().repository()).isEqualTo("golint"); assertThat(second.ruleKey().rule()).isEqualTo("Exported"); assertThat(second.primaryLocation().message()).isEqualTo("exported type User should have comment or be unexported"); assertThat(second.primaryLocation().textRange().start().line()).isEqualTo(2); assertThat(logTester.logs(LoggerLevel.ERROR)).isEmpty(); }
private static void applyFlows(Consumer<ScannerReport.Flow> consumer, ScannerReport.IssueLocation.Builder locationBuilder, ScannerReport.TextRange.Builder textRangeBuilder, Collection<Flow> flows) { ScannerReport.Flow.Builder flowBuilder = ScannerReport.Flow.newBuilder(); for (Flow flow : flows) { if (flow.locations().isEmpty()) { return; } flowBuilder.clear(); for (org.sonar.api.batch.sensor.issue.IssueLocation location : flow.locations()) { int locationComponentRef = ((DefaultInputComponent) location.inputComponent()).scannerId(); locationBuilder.clear(); locationBuilder.setComponentRef(locationComponentRef); String message = location.message(); if (message != null) { locationBuilder.setMsg(message); } TextRange textRange = location.textRange(); if (textRange != null) { locationBuilder.setTextRange(toProtobufTextRange(textRangeBuilder, textRange)); } flowBuilder.addLocation(locationBuilder.build()); } consumer.accept(flowBuilder.build()); } }
private void applyFlows(Issue issue) { for (Flow flow : issue.flows()) { if (!flow.locations().isEmpty()) { flowBuilder.clear(); for (org.sonar.api.batch.sensor.issue.IssueLocation location : flow.locations()) { locationBuilder.clear(); locationBuilder.setComponentRef(componentCache.get(location.inputComponent()).batchId()); String message = location.message(); if (message != null) { locationBuilder.setMsg(message); } TextRange textRange = location.textRange(); if (textRange != null) { locationBuilder.setTextRange(toProtobufTextRange(textRange)); } flowBuilder.addLocation(locationBuilder.build()); } builder.addFlow(flowBuilder.build()); } } }
private static ScannerReport.Issue createReportIssue(Issue issue, int componentRef, String activeRuleSeverity) { String primaryMessage = nullToEmpty(issue.primaryLocation().message()); org.sonar.api.batch.rule.Severity overriddenSeverity = issue.overriddenSeverity(); Severity severity = overriddenSeverity != null ? Severity.valueOf(overriddenSeverity.name()) : Severity.valueOf(activeRuleSeverity); ScannerReport.Issue.Builder builder = ScannerReport.Issue.newBuilder(); ScannerReport.IssueLocation.Builder locationBuilder = IssueLocation.newBuilder(); ScannerReport.TextRange.Builder textRangeBuilder = ScannerReport.TextRange.newBuilder(); // non-null fields builder.setSeverity(severity); builder.setRuleRepository(issue.ruleKey().repository()); builder.setRuleKey(issue.ruleKey().rule()); builder.setMsg(primaryMessage); locationBuilder.setMsg(primaryMessage); locationBuilder.setComponentRef(componentRef); TextRange primaryTextRange = issue.primaryLocation().textRange(); if (primaryTextRange != null) { builder.setTextRange(toProtobufTextRange(textRangeBuilder, primaryTextRange)); } Double gap = issue.gap(); if (gap != null) { builder.setGap(gap); } applyFlows(builder::addFlow, locationBuilder, textRangeBuilder, issue.flows()); return builder.build(); }
@Override public void store(Issue issue) { InputComponent inputComponent = issue.primaryLocation().inputComponent(); DefaultRule rule = validateRule(issue); ActiveRule activeRule = activeRules.find(issue.ruleKey()); if (activeRule == null) { // rule does not exist or is not enabled -> ignore the issue return; } if (noSonar(inputComponent, issue)) { return; } String primaryMessage = defaultIfEmpty(issue.primaryLocation().message(), rule.name()); org.sonar.api.batch.rule.Severity overriddenSeverity = issue.overriddenSeverity(); String severity = overriddenSeverity != null ? overriddenSeverity.name() : activeRule.severity(); String type = rule.type(); List<org.sonarsource.sonarlint.core.client.api.common.analysis.Issue.Flow> flows = mapFlows(issue.flows()); DefaultClientIssue newIssue = new DefaultClientIssue(severity, type, activeRule, rules.find(activeRule.ruleKey()), primaryMessage, issue.primaryLocation().textRange(), inputComponent.isFile() ? ((SonarLintInputFile) inputComponent).getClientInputFile() : null, flows); if (filters.accept(inputComponent, newIssue)) { issueListener.handle(newIssue); } }
private static ScannerReport.ExternalIssue createReportExternalIssue(ExternalIssue issue, int componentRef) { // primary location of an external issue must have a message String primaryMessage = issue.primaryLocation().message(); Severity severity = Severity.valueOf(issue.severity().name()); IssueType issueType = IssueType.valueOf(issue.type().name()); ScannerReport.ExternalIssue.Builder builder = ScannerReport.ExternalIssue.newBuilder(); ScannerReport.IssueLocation.Builder locationBuilder = IssueLocation.newBuilder(); ScannerReport.TextRange.Builder textRangeBuilder = ScannerReport.TextRange.newBuilder(); // non-null fields builder.setSeverity(severity); builder.setType(issueType); builder.setEngineId(issue.engineId()); builder.setRuleId(issue.ruleId()); builder.setMsg(primaryMessage); locationBuilder.setMsg(primaryMessage); locationBuilder.setComponentRef(componentRef); TextRange primaryTextRange = issue.primaryLocation().textRange(); if (primaryTextRange != null) { builder.setTextRange(toProtobufTextRange(textRangeBuilder, primaryTextRange)); } Long effort = issue.remediationEffort(); if (effort != null) { builder.setEffort(effort); } applyFlows(builder::addFlow, locationBuilder, textRangeBuilder, issue.flows()); return builder.build(); }