group=org.sonarsource.sonarqube
version=10.1
-pluginApiVersion=9.16.0.560
+pluginApiVersion=9.17.0.587
description=Open source platform for continuous inspection of code quality
projectTitle=SonarQube
org.gradle.jvmargs=-Xmx2048m
assertThat(issue.getLocations()).isNull();
assertThat(issue.parseLocations()).isNull();
assertThat(issue.isExternal()).isTrue();
+ assertThat(issue.getTags()).containsOnly("tag1", "tag2");
+ assertThat(issue.getCodeVariants()).containsOnly("variant1", "variant2");
assertFalse(issue.isQuickFixAvailable());
}
dto.setIssueCreationTime(1_450_000_000_000L);
dto.setIssueUpdateTime(1_450_000_000_000L);
dto.setIssueCloseTime(1_450_000_000_000L);
+ dto.setTags(Set.of("tag1", "tag2"));
+ dto.setCodeVariants(Set.of("variant1", "variant2"));
return dto;
}
import java.util.Date;
import java.util.List;
import java.util.Random;
+import java.util.Set;
import java.util.function.Consumer;
import java.util.stream.IntStream;
import org.apache.ibatis.session.ResultContext;
assertThat(result.getIssueCloseTime()).isEqualTo(1_403_000_000_000L);
assertThat(result.getCreatedAt()).isEqualTo(1_400_000_000_000L);
assertThat(result.getUpdatedAt()).isEqualTo(1_500_000_000_000L);
+ assertThat(result.getTags()).containsOnly("tag1", "tag2");
+ assertThat(result.getCodeVariants()).containsOnly("variant1", "variant2");
}
@Test
update.setAssigneeUuid("karadoc");
update.setChecksum("123456789");
update.setMessage("the message");
+ update.setTags(Set.of("tag3", "tag4"));
+ update.setCodeVariants(Set.of("variant3", "variant4"));
update.setIssueCreationTime(1_550_000_000_000L);
update.setIssueUpdateTime(1_550_000_000_000L);
assertThat(result.getIssueCloseTime()).isEqualTo(1_550_000_000_000L);
assertThat(result.getCreatedAt()).isEqualTo(1_400_000_000_000L);
assertThat(result.getUpdatedAt()).isEqualTo(1_550_000_000_000L);
+ assertThat(result.getTags()).containsOnly("tag3", "tag4");
+ assertThat(result.getCodeVariants()).containsOnly("variant3", "variant4");
}
@Test
.setGap(1.12d)
.setEffort(50L)
.setIssueUpdateTime(1_600_000_000_000L)
- .setUpdatedAt(1_600_000_000_000L);
+ .setUpdatedAt(1_600_000_000_000L)
+ .setTags(Set.of("tag2", "tag3"))
+ .setCodeVariants(Set.of("variant2", "variant3"));
// selected after last update -> ok
dto.setSelectedAt(1500000000000L);
assertThat(result.getEffort()).isEqualTo(50L);
assertThat(result.getIssueUpdateTime()).isEqualTo(1_600_000_000_000L);
assertThat(result.getUpdatedAt()).isEqualTo(1_600_000_000_000L);
+ assertThat(result.getTags()).containsOnly("tag2", "tag3");
+ assertThat(result.getCodeVariants()).containsOnly("variant2", "variant3");
}
@Test
.setGap(1.12d)
.setEffort(50L)
.setIssueUpdateTime(1_600_000_000_000L)
- .setUpdatedAt(1_600_000_000_000L);
+ .setUpdatedAt(1_600_000_000_000L)
+ .setTags(Set.of("tag2", "tag3"))
+ .setCodeVariants(Set.of("variant2", "variant3"));
// selected before last update -> ko
dto.setSelectedAt(1400000000000L);
assertThat(result.getEffort()).isEqualTo(10L);
assertThat(result.getIssueUpdateTime()).isEqualTo(1_402_000_000_000L);
assertThat(result.getUpdatedAt()).isEqualTo(1_500_000_000_000L);
+ assertThat(result.getTags()).containsOnly("tag1", "tag2");
+ assertThat(result.getCodeVariants()).containsOnly("variant1", "variant2");
}
@Test
.setIssueUpdateTime(1_402_000_000_000L)
.setIssueCloseTime(1_403_000_000_000L)
.setCreatedAt(1_400_000_000_000L)
- .setUpdatedAt(1_500_000_000_000L);
+ .setUpdatedAt(1_500_000_000_000L)
+ .setTags(Set.of("tag1", "tag2"))
+ .setCodeVariants(Set.of("variant1", "variant2"));
}
private static class RecorderResultHandler implements ResultHandler<IssueDto> {
public final class IssueDto implements Serializable {
public static final int AUTHOR_MAX_SIZE = 255;
- private static final char TAGS_SEPARATOR = ',';
- private static final Joiner TAGS_JOINER = Joiner.on(TAGS_SEPARATOR).skipNulls();
- private static final Splitter TAGS_SPLITTER = Splitter.on(',').trimResults().omitEmptyStrings();
+ private static final char STRING_LIST_SEPARATOR = ',';
+ private static final Joiner STRING_LIST_JOINER = Joiner.on(STRING_LIST_SEPARATOR).skipNulls();
+ private static final Splitter STRING_LIST_SPLITTER = Splitter.on(',').trimResults().omitEmptyStrings();
private int type;
private String kee;
private String projectKey;
private String filePath;
private String tags;
+ private String codeVariants;
// populate only when retrieving closed issue for issue tracking
private String closedChangeData;
.setSelectedAt(issue.selectedAt())
.setQuickFixAvailable(issue.isQuickFixAvailable())
.setIsNewCodeReferenceIssue(issue.isNewCodeReferenceIssue())
+ .setCodeVariants(issue.codeVariants())
// technical dates
.setCreatedAt(now)
.setSelectedAt(issue.selectedAt())
.setQuickFixAvailable(issue.isQuickFixAvailable())
.setIsNewCodeReferenceIssue(issue.isNewCodeReferenceIssue())
+ .setCodeVariants(issue.codeVariants())
// technical date
.setUpdatedAt(now);
}
public Set<String> getTags() {
- return ImmutableSet.copyOf(TAGS_SPLITTER.split(tags == null ? "" : tags));
+ return ImmutableSet.copyOf(STRING_LIST_SPLITTER.split(tags == null ? "" : tags));
}
public IssueDto setTags(@Nullable Collection<String> tags) {
if (tags == null || tags.isEmpty()) {
setTagsString(null);
} else {
- setTagsString(TAGS_JOINER.join(tags));
+ setTagsString(STRING_LIST_JOINER.join(tags));
}
return this;
}
return tags;
}
+ public Set<String> getCodeVariants() {
+ return ImmutableSet.copyOf(STRING_LIST_SPLITTER.split(codeVariants == null ? "" : codeVariants));
+ }
+
+ public String getCodeVariantsString() {
+ return codeVariants;
+ }
+
+ public IssueDto setCodeVariants(@Nullable Collection<String> codeVariants) {
+ if (codeVariants == null || codeVariants.isEmpty()) {
+ setCodeVariantsString(null);
+ } else {
+ setCodeVariantsString(STRING_LIST_JOINER.join(codeVariants));
+ }
+ return this;
+ }
+
+ public IssueDto setCodeVariantsString(@Nullable String codeVariants) {
+ checkArgument(codeVariants == null || codeVariants.length() <= 4000,
+ "Value is too long for column ISSUES.CODE_VARIANTS: %codeVariants", codeVariants);
+ this.codeVariants = codeVariants;
+ return this;
+ }
+
@CheckForNull
public byte[] getLocations() {
return locations;
issue.setIsFromExternalRuleEngine(isExternal);
issue.setQuickFixAvailable(quickFixAvailable);
issue.setIsNewCodeReferenceIssue(isNewCodeReferenceIssue);
+ issue.setCodeVariants(getCodeVariants());
return issue;
}
}
i.project_uuid as projectUuid,
i.issue_type as type,
i.quick_fix_available as quickFixAvailable,
+ i.code_variants as codeVariantsString,
<include refid="isNewCodeReferenceIssue"/>
</sql>
i.component_uuid,
i.project_uuid,
i.issue_type,
- i.quick_fix_available
+ i.quick_fix_available,
+ i.code_variants
</sql>
<sql id="isNewCodeReferenceIssue" databaseId="mssql">
INSERT INTO issues (kee, rule_uuid, severity, manual_severity,
message, message_formattings, line, locations, gap, effort, status, tags, rule_description_context_key,
resolution, checksum, assignee, author_login, issue_creation_date, issue_update_date,
- issue_close_date, created_at, updated_at, component_uuid, project_uuid, issue_type, quick_fix_available)
+ issue_close_date, created_at, updated_at, component_uuid, project_uuid, issue_type, quick_fix_available, code_variants)
VALUES (
#{kee,jdbcType=VARCHAR},
#{ruleUuid,jdbcType=VARCHAR},
#{issueCreationTime,jdbcType=BIGINT},#{issueUpdateTime,jdbcType=BIGINT}, #{issueCloseTime,jdbcType=BIGINT},
#{createdAt,jdbcType=BIGINT}, #{updatedAt,jdbcType=BIGINT},
#{componentUuid,jdbcType=VARCHAR}, #{projectUuid,jdbcType=VARCHAR}, #{type,jdbcType=INTEGER},
- #{quickFixAvailable, jdbcType=BOOLEAN})
+ #{quickFixAvailable, jdbcType=BOOLEAN},
+ #{codeVariantsString,jdbcType=VARCHAR})
</insert>
<insert id="insertAsNewCodeOnReferenceBranch" parameterType="NewCodeReferenceIssue" useGeneratedKeys="false">
issue_update_date=#{issueUpdateTime,jdbcType=BIGINT},
issue_close_date=#{issueCloseTime,jdbcType=BIGINT},
updated_at=#{updatedAt,jdbcType=BIGINT},
- issue_type=#{type,jdbcType=INTEGER}
+ issue_type=#{type,jdbcType=INTEGER},
+ code_variants=#{codeVariantsString,jdbcType=VARCHAR}
where kee = #{kee}
</update>
issue_update_date=#{issueUpdateTime,jdbcType=BIGINT},
issue_close_date=#{issueCloseTime,jdbcType=BIGINT},
updated_at=#{updatedAt,jdbcType=BIGINT},
- issue_type=#{type,jdbcType=INTEGER}
+ issue_type=#{type,jdbcType=INTEGER},
+ code_variants=#{codeVariantsString,jdbcType=VARCHAR}
where kee = #{kee} and updated_at <= #{selectedAt}
</update>
</select>
</mapper>
-
"FROM_HOTSPOT" BOOLEAN,
"QUICK_FIX_AVAILABLE" BOOLEAN,
"RULE_DESCRIPTION_CONTEXT_KEY" CHARACTER VARYING(50),
- "MESSAGE_FORMATTINGS" BINARY LARGE OBJECT
+ "MESSAGE_FORMATTINGS" BINARY LARGE OBJECT,
+ "CODE_VARIANTS" CHARACTER VARYING(4000)
);
ALTER TABLE "ISSUES" ADD CONSTRAINT "PK_ISSUES" PRIMARY KEY("KEE");
CREATE INDEX "ISSUES_ASSIGNEE" ON "ISSUES"("ASSIGNEE" NULLS FIRST);
assertThat(dto.getTags()).isEmpty();
}
+ @Test
+ public void setCodeVariants_shouldReturnCodeVariants() {
+ IssueDto dto = new IssueDto();
+ assertThat(dto.getCodeVariants()).isEmpty();
+ assertThat(dto.getCodeVariantsString()).isNull();
+
+ dto.setCodeVariants(Arrays.asList("variant1", "variant2", "variant3"));
+ assertThat(dto.getCodeVariants()).containsOnly("variant1", "variant2", "variant3");
+ assertThat(dto.getCodeVariantsString()).isEqualTo("variant1,variant2,variant3");
+
+ dto.setCodeVariants(null);
+ assertThat(dto.getCodeVariants()).isEmpty();
+ assertThat(dto.getCodeVariantsString()).isNull();
+
+ dto.setCodeVariants(List.of());
+ assertThat(dto.getCodeVariants()).isEmpty();
+ assertThat(dto.getCodeVariantsString()).isNull();
+ }
+
+ @Test
+ public void setCodeVariantsString_shouldReturnCodeVariants() {
+ IssueDto dto = new IssueDto();
+
+ dto.setCodeVariantsString("variant1, variant2 ,,variant4");
+ assertThat(dto.getCodeVariants()).containsOnly("variant1", "variant2", "variant4");
+
+ dto.setCodeVariantsString(null);
+ assertThat(dto.getCodeVariants()).isEmpty();
+
+ dto.setCodeVariantsString("");
+ assertThat(dto.getCodeVariants()).isEmpty();
+ }
+
@Test
public void toDtoForComputationInsert_givenDefaultIssueWithAllFields_returnFullIssueDto() {
long now = System.currentTimeMillis();
IssueDto::getGap, IssueDto::getEffort, IssueDto::getResolution, IssueDto::getStatus, IssueDto::getSeverity)
.containsExactly(1, "message", 1.0, 1L, Issue.RESOLUTION_FALSE_POSITIVE, Issue.STATUS_CLOSED, "BLOCKER");
- assertThat(issueDto).extracting(IssueDto::getTags, IssueDto::getAuthorLogin)
- .containsExactly(Set.of("todo"), "admin");
+ assertThat(issueDto).extracting(IssueDto::getTags, IssueDto::getCodeVariants, IssueDto::getAuthorLogin)
+ .containsExactly(Set.of("todo"), Set.of("variant1", "variant2"), "admin");
assertThat(issueDto).extracting(IssueDto::isManualSeverity, IssueDto::getChecksum, IssueDto::getAssigneeUuid,
IssueDto::isExternal, IssueDto::getComponentUuid, IssueDto::getComponentKey,
IssueDto::getGap, IssueDto::getEffort, IssueDto::getResolution, IssueDto::getStatus, IssueDto::getSeverity)
.containsExactly(1, "message", 1.0, 1L, Issue.RESOLUTION_FALSE_POSITIVE, Issue.STATUS_CLOSED, "BLOCKER");
- assertThat(issueDto).extracting(IssueDto::getTags, IssueDto::getAuthorLogin)
- .containsExactly(Set.of("todo"), "admin");
+ assertThat(issueDto).extracting(IssueDto::getTags, IssueDto::getCodeVariants, IssueDto::getAuthorLogin)
+ .containsExactly(Set.of("todo"), Set.of("variant1", "variant2"), "admin");
assertThat(issueDto).extracting(IssueDto::isManualSeverity, IssueDto::getChecksum, IssueDto::getAssigneeUuid,
IssueDto::isExternal, IssueDto::getComponentUuid, IssueDto::getComponentKey, IssueDto::getProjectUuid, IssueDto::getProjectKey)
.setSelectedAt(dateNow.getTime())
.setQuickFixAvailable(true)
.setIsNewCodeReferenceIssue(true)
- .setRuleDescriptionContextKey(TEST_CONTEXT_KEY);
+ .setRuleDescriptionContextKey(TEST_CONTEXT_KEY)
+ .setCodeVariants(List.of("variant1", "variant2"));
return defaultIssue;
}
}
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2023 SonarSource SA
+ * mailto:info AT sonarsource DOT com
+ *
+ * This program 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.
+ *
+ * This program 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.server.platform.db.migration.version.v101;
+
+import java.sql.Connection;
+import java.sql.SQLException;
+import org.sonar.db.Database;
+import org.sonar.db.DatabaseUtils;
+import org.sonar.server.platform.db.migration.def.ColumnDef;
+import org.sonar.server.platform.db.migration.def.VarcharColumnDef;
+import org.sonar.server.platform.db.migration.sql.AddColumnsBuilder;
+import org.sonar.server.platform.db.migration.step.DdlChange;
+
+public class AddCodeVariantsColumnInIssuesTable extends DdlChange {
+
+ private static final String TABLE_NAME = "issues";
+ private static final String COLUMN_NAME = "code_variants";
+ private static final int COLUMN_SIZE = 4000;
+
+ public AddCodeVariantsColumnInIssuesTable(Database db) {
+ super(db);
+ }
+
+ @Override
+ public void execute(Context context) throws SQLException {
+ try (Connection connection = getDatabase().getDataSource().getConnection()) {
+ if (!DatabaseUtils.tableColumnExists(connection, TABLE_NAME, COLUMN_NAME)) {
+ ColumnDef columnDef = VarcharColumnDef.newVarcharColumnDefBuilder()
+ .setColumnName(COLUMN_NAME)
+ .setLimit(COLUMN_SIZE)
+ .setIsNullable(true)
+ .build();
+ context.execute(new AddColumnsBuilder(getDialect(), TABLE_NAME).addColumn(columnDef).build());
+ }
+ }
+ }
+}
.add(10_1_013, "Increase size of 'ce_queue.task_type' from 15 to 40 characters", IncreaseTaskTypeColumnSizeInCeQueue.class)
.add(10_1_014, "Increase size of 'ce_activity.task_type' from 15 to 40 characters", IncreaseTaskTypeColumnSizeInCeActivity.class)
.add(10_1_015, "Add 'external_groups' table.", CreateExternalGroupsTable.class)
- .add(10_1_016, "Add index on 'external_groups(external_identity_provider, external_id).", CreateIndexOnExternalIdAndIdentityOnExternalGroupsTable.class);
+ .add(10_1_016, "Add index on 'external_groups(external_identity_provider, external_id).", CreateIndexOnExternalIdAndIdentityOnExternalGroupsTable.class)
+ .add(10_1_017, "Add 'code_variants' column in 'issues' table", AddCodeVariantsColumnInIssuesTable.class);
}
}
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2023 SonarSource SA
+ * mailto:info AT sonarsource DOT com
+ *
+ * This program 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.
+ *
+ * This program 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.server.platform.db.migration.version.v101;
+
+import java.sql.SQLException;
+import org.junit.Rule;
+import org.junit.Test;
+import org.sonar.db.CoreDbTester;
+
+import static java.sql.Types.VARCHAR;
+
+public class AddCodeVariantsColumnInIssuesTableTest {
+
+ private static final String TABLE_NAME = "issues";
+ private static final String COLUMN_NAME = "code_variants";
+ private static final int COLUMN_SIZE = 4000;
+
+ @Rule
+ public final CoreDbTester db = CoreDbTester.createForSchema(AddCodeVariantsColumnInIssuesTableTest.class, "schema.sql");
+
+ private final AddCodeVariantsColumnInIssuesTable underTest = new AddCodeVariantsColumnInIssuesTable(db.database());
+
+ @Test
+ public void migration_should_add_column() throws SQLException {
+ db.assertColumnDoesNotExist(TABLE_NAME, COLUMN_NAME);
+ underTest.execute();
+ db.assertColumnDefinition(TABLE_NAME, COLUMN_NAME, VARCHAR, COLUMN_SIZE, true);
+ }
+
+ @Test
+ public void migration_should_be_reentrant() throws SQLException {
+ db.assertColumnDoesNotExist(TABLE_NAME, COLUMN_NAME);
+ underTest.execute();
+ underTest.execute();
+ db.assertColumnDefinition(TABLE_NAME, COLUMN_NAME, VARCHAR, COLUMN_SIZE, true);
+ }
+}
--- /dev/null
+CREATE TABLE "ISSUES"(
+ "KEE" CHARACTER VARYING(50) NOT NULL,
+ "RULE_UUID" CHARACTER VARYING(40),
+ "SEVERITY" CHARACTER VARYING(10),
+ "MANUAL_SEVERITY" BOOLEAN NOT NULL,
+ "MESSAGE" CHARACTER VARYING(4000),
+ "LINE" INTEGER,
+ "GAP" DOUBLE PRECISION,
+ "STATUS" CHARACTER VARYING(20),
+ "RESOLUTION" CHARACTER VARYING(20),
+ "CHECKSUM" CHARACTER VARYING(1000),
+ "ASSIGNEE" CHARACTER VARYING(255),
+ "AUTHOR_LOGIN" CHARACTER VARYING(255),
+ "EFFORT" INTEGER,
+ "CREATED_AT" BIGINT,
+ "UPDATED_AT" BIGINT,
+ "ISSUE_CREATION_DATE" BIGINT,
+ "ISSUE_UPDATE_DATE" BIGINT,
+ "ISSUE_CLOSE_DATE" BIGINT,
+ "TAGS" CHARACTER VARYING(4000),
+ "COMPONENT_UUID" CHARACTER VARYING(50),
+ "PROJECT_UUID" CHARACTER VARYING(50),
+ "LOCATIONS" BINARY LARGE OBJECT,
+ "ISSUE_TYPE" TINYINT,
+ "FROM_HOTSPOT" BOOLEAN,
+ "QUICK_FIX_AVAILABLE" BOOLEAN,
+ "RULE_DESCRIPTION_CONTEXT_KEY" CHARACTER VARYING(50),
+ "MESSAGE_FORMATTINGS" BINARY LARGE OBJECT
+);
+ALTER TABLE "ISSUES" ADD CONSTRAINT "PK_ISSUES" PRIMARY KEY("KEE");
+CREATE INDEX "ISSUES_ASSIGNEE" ON "ISSUES"("ASSIGNEE" NULLS FIRST);
+CREATE INDEX "ISSUES_COMPONENT_UUID" ON "ISSUES"("COMPONENT_UUID" NULLS FIRST);
+CREATE INDEX "ISSUES_CREATION_DATE" ON "ISSUES"("ISSUE_CREATION_DATE" NULLS FIRST);
+CREATE INDEX "ISSUES_PROJECT_UUID" ON "ISSUES"("PROJECT_UUID" NULLS FIRST);
+CREATE INDEX "ISSUES_RESOLUTION" ON "ISSUES"("RESOLUTION" NULLS FIRST);
+CREATE INDEX "ISSUES_UPDATED_AT" ON "ISSUES"("UPDATED_AT" NULLS FIRST);
+CREATE INDEX "ISSUES_RULE_UUID" ON "ISSUES"("RULE_UUID" NULLS FIRST);
private String authorLogin = null;
private List<DefaultIssueComment> comments = null;
private Set<String> tags = null;
+ private Set<String> codeVariants = null;
// temporarily an Object as long as DefaultIssue is used by sonar-batch
private Object locations = null;
@Override
public Set<String> tags() {
if (tags == null) {
- return ImmutableSet.of();
+ return Set.of();
} else {
return ImmutableSet.copyOf(tags);
}
return this;
}
+ @Override
+ public Set<String> codeVariants() {
+ if (codeVariants == null) {
+ return Set.of();
+ } else {
+ return ImmutableSet.copyOf(codeVariants);
+ }
+ }
+
+ public DefaultIssue setCodeVariants(Collection<String> codeVariants) {
+ this.codeVariants = new LinkedHashSet<>(codeVariants);
+ return this;
+ }
+
public Optional<String> getRuleDescriptionContextKey() {
return Optional.ofNullable(ruleDescriptionContextKey);
}
import java.text.SimpleDateFormat;
import java.util.List;
+import java.util.Set;
import org.apache.commons.lang.StringUtils;
import org.junit.Test;
import org.sonar.api.issue.Issue;
import org.sonar.api.utils.Duration;
import static org.assertj.core.api.Assertions.assertThat;
-import static org.assertj.core.api.Assertions.assertThatThrownBy;
import static org.junit.Assert.fail;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
.setCloseDate(new SimpleDateFormat("yyyy-MM-dd").parse("2013-08-21"))
.setSelectedAt(1400000000000L)
.setRuleDescriptionContextKey(TEST_CONTEXT_KEY)
- .setType(RuleType.BUG);
+ .setType(RuleType.BUG)
+ .setTags(Set.of("tag1", "tag2"))
+ .setCodeVariants(Set.of("variant1", "variant2"));
assertThat((Object) issue.getLocations()).isEqualTo("loc");
assertThat(issue.locationsChanged()).isTrue();
assertThat(issue.selectedAt()).isEqualTo(1400000000000L);
assertThat(issue.getRuleDescriptionContextKey()).contains(TEST_CONTEXT_KEY);
assertThat(issue.type()).isEqualTo(RuleType.BUG);
+ assertThat(issue.tags()).containsOnly("tag1", "tag2");
+ assertThat(issue.codeVariants()).containsOnly("variant1", "variant2");
}
@Test
*/
package org.sonar.api.batch.sensor.issue.internal;
+import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import javax.annotation.Nullable;
private Severity overriddenSeverity;
private boolean quickFixAvailable = false;
private String ruleDescriptionContextKey;
+ private List<String> codeVariants;
public DefaultIssue(DefaultInputProject project) {
this(project, null);
return this;
}
+ @Override
+ public DefaultIssue setCodeVariants(@Nullable Iterable<String> codeVariants) {
+ if (codeVariants != null) {
+ List<String> codeVariantsList = new ArrayList<>();
+ codeVariants.forEach(codeVariantsList::add);
+ this.codeVariants = codeVariantsList;
+ }
+ return this;
+ }
+
@Override
public boolean isQuickFixAvailable() {
return quickFixAvailable;
throw new UnsupportedOperationException();
}
+ @Override
+ public List<String> codeVariants() {
+ return codeVariants;
+ }
+
@Override
public Severity overriddenSeverity() {
return this.overriddenSeverity;
.message("Wrong way!"))
.forRule(RULE_KEY)
.gap(10.0)
- .setRuleDescriptionContextKey("spring");
+ .setRuleDescriptionContextKey("spring")
+ .setCodeVariants(List.of("variant1", "variant2"));
assertThat(issue.primaryLocation().inputComponent()).isEqualTo(inputFile);
assertThat(issue.ruleKey()).isEqualTo(RuleKey.of("repo", "rule"));
assertThat(issue.gap()).isEqualTo(10.0);
assertThat(issue.primaryLocation().message()).isEqualTo("Wrong way!");
assertThat(issue.ruleDescriptionContextKey()).contains("spring");
+ assertThat(issue.codeVariants()).containsOnly("variant1", "variant2");
issue.save();