insertRuleDescriptionSectionDtos(ruleDefinitionDto, mapper);
}
- private void insertRuleDescriptionSectionDtos(RuleDefinitionDto ruleDefinitionDto, RuleMapper mapper) {
+ private static void insertRuleDescriptionSectionDtos(RuleDefinitionDto ruleDefinitionDto, RuleMapper mapper) {
ruleDefinitionDto.getRuleDescriptionSectionDtos()
.forEach(section -> mapper.insertRuleDescriptionSection(ruleDefinitionDto.getUuid(), section));
}
private final String uuid;
private final String key;
- private final String description;
+ private final String content;
- private RuleDescriptionSectionDto(String uuid, String key, String description) {
+ private RuleDescriptionSectionDto(String uuid, String key, String content) {
this.uuid = uuid;
this.key = key;
- this.description = description;
+ this.content = content;
}
public String getUuid() {
return key;
}
- public String getDescription() {
- return description;
+ public String getContent() {
+ return content;
}
public static RuleDescriptionSectionDto createDefaultRuleDescriptionSection(String uuid, String description) {
return RuleDescriptionSectionDto.builder()
.setDefault()
.uuid(uuid)
- .description(description)
+ .content(description)
.build();
}
return new StringJoiner(", ", RuleDescriptionSectionDto.class.getSimpleName() + "[", "]")
.add("uuid='" + uuid + "'")
.add("key='" + key + "'")
- .add("description='" + description + "'")
+ .add("content='" + content + "'")
.toString();
}
return false;
}
RuleDescriptionSectionDto that = (RuleDescriptionSectionDto) o;
- return Objects.equals(uuid, that.uuid) && Objects.equals(key, that.key) && Objects.equals(description, that.description);
+ return Objects.equals(uuid, that.uuid) && Objects.equals(key, that.key) && Objects.equals(content, that.content);
}
@Override
public int hashCode() {
- return Objects.hash(uuid, key, description);
+ return Objects.hash(uuid, key, content);
}
public static final class RuleDescriptionSectionDtoBuilder {
private String uuid;
private String key = null;
- private String description;
+ private String content;
private RuleDescriptionSectionDtoBuilder() {
}
return this;
}
- public RuleDescriptionSectionDtoBuilder description(String description) {
- this.description = description;
+ public RuleDescriptionSectionDtoBuilder content(String content) {
+ this.content = content;
return this;
}
public RuleDescriptionSectionDto build() {
- return new RuleDescriptionSectionDto(uuid, key, description);
+ return new RuleDescriptionSectionDto(uuid, key, content);
}
}
}
<sql id="selectRuleDescriptionSectionColumns">
rds.uuid as "rds_uuid",
rds.kee as "rds_kee",
- rds.description as "rds_description",
+ rds.content as "rds_content",
</sql>
<sql id="leftOuterJoinRulesDescriptionSections">
<collection property="ruleDescriptionSectionDtos" ofType="org.sonar.db.rule.RuleDescriptionSectionDto">
<id property="uuid" column="rds_uuid"/>
<result property="key" column="rds_kee"/>
- <result property="description" column="rds_description" typeHandler="org.apache.ibatis.type.StringTypeHandler"/>
+ <result property="content" column="rds_content" typeHandler="org.apache.ibatis.type.StringTypeHandler"/>
</collection>
</resultMap>
<sql id="selectRuleDescriptionSectionColumns">
rds.uuid as "rds_uuid",
rds.kee as "rds_kee",
- rds.description as "rds_description",
+ rds.content as "rds_content",
</sql>
<sql id="leftOuterJoinRulesDescriptionSections">
<collection property="ruleDescriptionSectionDtos" ofType="org.sonar.db.rule.RuleDescriptionSectionDto">
<id property="uuid" column="rds_uuid"/>
<result property="key" column="rds_kee"/>
- <result property="description" column="rds_description" typeHandler="org.apache.ibatis.type.StringTypeHandler"/>
+ <result property="content" column="rds_content" typeHandler="org.apache.ibatis.type.StringTypeHandler"/>
</collection>
</resultMap>
<collection property="ruleDescriptionSectionDtos" ofType="org.sonar.db.rule.RuleDescriptionSectionDto">
<id property="uuid" column="rds_uuid"/>
<result property="key" column="rds_kee"/>
- <result property="description" column="rds_description" typeHandler="org.apache.ibatis.type.StringTypeHandler"/>
+ <result property="content" column="rds_content" typeHandler="org.apache.ibatis.type.StringTypeHandler"/>
</collection>
</resultMap>
uuid,
rule_uuid,
kee,
- description
+ content
)
values (
#{dto.uuid,jdbcType=VARCHAR},
#{ruleUuid,jdbcType=VARCHAR},
#{dto.key,jdbcType=VARCHAR},
- #{dto.description,jdbcType=VARCHAR}
+ #{dto.content,jdbcType=VARCHAR}
)
</insert>
"UUID" CHARACTER VARYING(40) NOT NULL,
"RULE_UUID" CHARACTER VARYING(40) NOT NULL,
"KEE" CHARACTER VARYING(50) NOT NULL,
- "DESCRIPTION" CHARACTER LARGE OBJECT NOT NULL
+ "CONTENT" CHARACTER LARGE OBJECT NOT NULL
);
ALTER TABLE "RULE_DESC_SECTIONS" ADD CONSTRAINT "PK_RULE_DESC_SECTIONS" PRIMARY KEY("UUID");
CREATE UNIQUE INDEX "UNIQ_RULE_DESC_SECTIONS_KEE" ON "RULE_DESC_SECTIONS"("RULE_UUID" NULLS FIRST, "KEE" NULLS FIRST);
String language = "java";
RuleDefinitionDto ruleTemplate = createRule(language);
RuleDefinitionDto customRule = createRule(language, RuleStatus.READY, ruleTemplate.getUuid());
- var customRuleDescription = customRule.getDefaultRuleDescriptionSectionDto().getDescription();
+ var customRuleContent = customRule.getDefaultRuleDescriptionSectionDto().getContent();
RuleMetadataDto customRuleMetadata = createRuleMetadata(new RuleMetadataDto()
.setRuleUuid(customRule.getUuid())
.setNoteData("Extended description")
.setTags(Sets.newHashSet("tag1", "tag2", "tag3")));
RuleDefinitionDto rule = createRule(language, RuleStatus.READY, null);
- var ruleDescription = rule.getDefaultRuleDescriptionSectionDto().getDescription();
+ var ruleContent = rule.getDefaultRuleDescriptionSectionDto().getContent();
RuleMetadataDto ruleMetadata = createRuleMetadata(new RuleMetadataDto()
.setRuleUuid(rule.getUuid()));
QProfileDto profile = createProfile(language);
assertThat(exportCustomRuleDto).isNotNull();
assertThat(exportCustomRuleDto.isCustomRule()).isTrue();
assertThat(exportCustomRuleDto.getParams()).isEmpty();
- assertThat(exportCustomRuleDto.getRuleDescriptionSections().iterator().next().getDescription()).isEqualTo(customRuleDescription);
+ assertThat(exportCustomRuleDto.getRuleDescriptionSections().iterator().next().getContent()).isEqualTo(customRuleContent);
assertThat(exportCustomRuleDto.getExtendedDescription()).isEqualTo(customRuleMetadata.getNoteData());
assertThat(exportCustomRuleDto.getName()).isEqualTo(customRule.getName());
assertThat(exportCustomRuleDto.getRuleKey()).isEqualTo(customRule.getKey());
assertThat(exportRuleDto).isNotNull();
assertThat(exportRuleDto.isCustomRule()).isFalse();
assertThat(exportRuleDto.getParams()).isEmpty();
- assertThat(exportRuleDto.getRuleDescriptionSections().iterator().next().getDescription()).isEqualTo(ruleDescription);
+ assertThat(exportRuleDto.getRuleDescriptionSections().iterator().next().getContent()).isEqualTo(ruleContent);
assertThat(exportRuleDto.getExtendedDescription()).isEqualTo(ruleMetadata.getNoteData());
assertThat(exportRuleDto.getName()).isEqualTo(rule.getName());
assertThat(exportRuleDto.getRuleKey()).isEqualTo(rule.getKey());
import java.util.function.Consumer;
import org.apache.commons.lang.RandomStringUtils;
import org.apache.ibatis.exceptions.PersistenceException;
+import org.jetbrains.annotations.NotNull;
import org.junit.Rule;
import org.junit.Test;
import org.sonar.api.rule.RuleKey;
RuleDescriptionSectionDto newSection = RuleDescriptionSectionDto.builder()
.uuid(randomAlphanumeric(20))
.key("new_key")
- .description(randomAlphanumeric(1000))
+ .content(randomAlphanumeric(1000))
.build();
rule.addRuleDescriptionSectionDto(newSection);
RuleDescriptionSectionDto replacingSection = RuleDescriptionSectionDto.builder()
.uuid(randomAlphanumeric(20))
.key(existingSection.getKey())
- .description(randomAlphanumeric(1000))
+ .content(randomAlphanumeric(1000))
.build();
rule.addOrReplaceRuleDescriptionSectionDto(replacingSection);
RuleDescriptionSectionDto ruleDescriptionSectionDto = RuleDescriptionSectionDto.builder()
.key("DESC")
.uuid("uuid")
- .description("my description")
+ .content("my description")
.build();
RuleDefinitionDto r1 = db.rules().insert(r -> {
r.addRuleDescriptionSectionDto(ruleDescriptionSectionDto);
underTest.selectIndexingRules(db.getSession(), accumulator);
- assertThat(accumulator.list)
+ RuleForIndexingDto firstRule = findRuleForIndexingWithUuid(accumulator, r1.getUuid());
+ RuleForIndexingDto secondRule = findRuleForIndexingWithUuid(accumulator, r2.getUuid());
+
+ assertThat(Arrays.asList(firstRule, secondRule))
.extracting(RuleForIndexingDto::getUuid, RuleForIndexingDto::getRuleKey)
.containsExactlyInAnyOrder(tuple(r1.getUuid(), r1.getKey()), tuple(r2.getUuid(), r2.getKey()));
Iterator<RuleForIndexingDto> it = accumulator.list.iterator();
- RuleForIndexingDto firstRule = it.next();
+
assertThat(firstRule.getRepository()).isEqualTo(r1.getRepositoryKey());
assertThat(firstRule.getPluginRuleKey()).isEqualTo(r1.getRuleKey());
assertThat(firstRule.getCreatedAt()).isEqualTo(r1.getCreatedAt());
assertThat(firstRule.getUpdatedAt()).isEqualTo(r1.getUpdatedAt());
- RuleForIndexingDto secondRule = it.next();
assertThat(secondRule.isExternal()).isTrue();
}
underTest.selectIndexingRules(db.getSession(), accumulator);
assertThat(accumulator.list).hasSize(2);
- RuleForIndexingDto firstRule = accumulator.list.get(0);
- RuleForIndexingDto secondRule = accumulator.list.get(1);
+ RuleForIndexingDto firstRule = findRuleForIndexingWithUuid(accumulator, r1.getUuid());
+ RuleForIndexingDto secondRule = findRuleForIndexingWithUuid(accumulator, r2.getUuid());
assertRuleDefinitionFieldsAreEquals(r1, firstRule);
assertRuleMetadataFieldsAreEquals(r1Metadatas, firstRule);
assertThat(secondRule.getTemplateRepository()).isEqualTo(r1.getRepositoryKey());
}
+ @NotNull
+ private static RuleForIndexingDto findRuleForIndexingWithUuid(Accumulator<RuleForIndexingDto> accumulator, String uuid) {
+ return accumulator.list.stream()
+ .filter(rule -> rule.getUuid().equals(uuid))
+ .findFirst().orElseThrow();
+ }
+
@Test
public void scrollIndexingRulesByKeys() {
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2022 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.db.rule;
+
+import org.assertj.core.api.Assertions;
+import org.junit.Test;
+
+public class RuleDescriptionSectionDtoTest {
+ private static final RuleDescriptionSectionDto SECTION = RuleDescriptionSectionDto.builder()
+ .key("key")
+ .uuid("uuid")
+ .content("desc").build();
+
+ @Test
+ public void testEquals() {
+
+ Assertions.assertThat(RuleDescriptionSectionDto.builder()
+ .key("key")
+ .uuid("uuid")
+ .content("desc")
+ .build())
+ .isEqualTo(SECTION);
+
+ Assertions.assertThat(SECTION).isEqualTo(SECTION);
+ }
+
+ @Test
+ public void testToString() {
+ Assertions.assertThat(SECTION).hasToString("RuleDescriptionSectionDto[uuid='uuid', key='key', content='desc']");
+ }
+}
}
public static RuleDefinitionDto newRuleWithoutDescriptionSection(RuleKey ruleKey) {
+ long currentTimeMillis = System.currentTimeMillis();
return new RuleDefinitionDto()
.setRepositoryKey(ruleKey.repository())
.setRuleKey(ruleKey.rule())
.setLanguage("lang_" + randomAlphanumeric(3))
.setGapDescription("gapDescription_" + randomAlphanumeric(5))
.setDefRemediationBaseEffort(nextInt(10) + "h")
- .setDefRemediationGapMultiplier(nextInt(10) + "h")
+ //voluntarily offset the remediation to be able to detect issues
+ .setDefRemediationGapMultiplier((nextInt(10) + 10) + "h")
.setDefRemediationFunction("LINEAR_OFFSET")
- .setCreatedAt(System.currentTimeMillis())
- .setUpdatedAt(System.currentTimeMillis())
+ .setCreatedAt(currentTimeMillis)
+ .setUpdatedAt(currentTimeMillis + 5)
.setScope(Scope.MAIN);
}
.addPkColumn(newVarcharColumnDefBuilder().setColumnName("uuid").setIsNullable(false).setLimit(UUID_SIZE).build())
.addColumn(newVarcharColumnDefBuilder().setColumnName("rule_uuid").setIsNullable(false).setLimit(40).build())
.addColumn(newVarcharColumnDefBuilder().setColumnName("kee").setIsNullable(false).setLimit(50).build())
- .addColumn(newClobColumnDefBuilder().setColumnName("description").setIsNullable(false).build())
+ .addColumn(newClobColumnDefBuilder().setColumnName("content").setIsNullable(false).build())
.build());
}
}
.add(6403, "Upsert value of type in 'user_tokens'", UpsertUserTokensTypeValue.class)
.add(6404, "Make column 'type' in 'user_tokens' not nullable", MakeTypeColumnNotNullableOnUserTokens.class)
.add(6405, "Create table RULE_DESC_SECTIONS", CreateRuleDescSectionsTable.class)
- .add(6406, "Insert descriptions from RULES into RULE_DESC_SECTIONS", InsertRuleDescriptionIntoRuleDescSections.class)
+ .add(6406, "Insert description from RULES into RULE_DESC_SECTIONS", InsertRuleDescriptionIntoRuleDescSections.class)
.add(6407, "Create index for RULE_DESC_SECTIONS", CreateIndexForRuleDescSections.class)
.add(6408, "Drop column DESCRIPTIONS from RULES table", DropRuleDescriptionColumn.class)
;
private static final String SELECT_EXISTING_RULE_DESCRIPTIONS = "select uuid, description from rules where description is not null "
+ "and uuid not in (select rule_uuid from " + RULE_DESCRIPTION_SECTIONS_TABLE + ")";
- private static final String INSERT_INTO_RULE_DESC_SECTIONS = "insert into " + RULE_DESCRIPTION_SECTIONS_TABLE + " (uuid, rule_uuid, kee, description) values "
+ private static final String INSERT_INTO_RULE_DESC_SECTIONS = "insert into " + RULE_DESCRIPTION_SECTIONS_TABLE + " (uuid, rule_uuid, kee, content) values "
+ "(?,?,?,?)";
private final UuidFactory uuidFactory;
insertRuleDescSections(context, selectRuleDb);
}
- private List<RuleDb> findExistingRuleDescriptions(Context context) throws SQLException {
+ private static List<RuleDb> findExistingRuleDescriptions(Context context) throws SQLException {
return context.prepareSelect(SELECT_EXISTING_RULE_DESCRIPTIONS)
.list(r -> new RuleDb(r.getString(1), r.getString(2)));
}
ruleParams.put("uuid", RandomStringUtils.randomAlphanumeric(40));
ruleParams.put("rule_uuid", ruleUuid);
ruleParams.put("kee", key);
- ruleParams.put("description", "descriptions");
+ ruleParams.put("content", "content blablablabla");
db.executeInsert("rule_desc_sections", ruleParams);
}
assertThat(result1)
.containsEntry("RULE_UUID", uuid1)
.containsEntry("KEE", DEFAULT_DESCRIPTION_KEY)
- .containsEntry("DESCRIPTION", description1)
+ .containsEntry("CONTENT", description1)
.extractingByKey("UUID").isNotNull();
}
private Map<String, Object> findRuleSectionDescription(String uuid) {
- return db.selectFirst("select uuid, kee, rule_uuid, description from "
+ return db.selectFirst("select uuid, kee, rule_uuid, content from "
+ RULE_DESCRIPTION_SECTIONS_TABLE + " where rule_uuid = '" + uuid + "'");
}
"UUID" CHARACTER VARYING(40) NOT NULL,
"RULE_UUID" CHARACTER VARYING(40) NOT NULL,
"KEE" CHARACTER VARYING(50) NOT NULL,
- "DESCRIPTION" CHARACTER LARGE OBJECT NOT NULL
+ "CONTENT" CHARACTER LARGE OBJECT NOT NULL
);
ALTER TABLE "RULE_DESC_SECTIONS" ADD CONSTRAINT "PK_RULE_DESC_SECTIONS" PRIMARY KEY("UUID");
"UUID" CHARACTER VARYING(40) NOT NULL,
"RULE_UUID" CHARACTER VARYING(40) NOT NULL,
"KEE" CHARACTER VARYING(50) NOT NULL,
- "DESCRIPTION" CHARACTER LARGE OBJECT NOT NULL
+ "CONTENT" CHARACTER LARGE OBJECT NOT NULL
);
ALTER TABLE "RULE_DESC_SECTIONS" ADD CONSTRAINT "PK_RULE_DESC_SECTIONS" PRIMARY KEY("UUID");
CREATE UNIQUE INDEX "UNIQ_RULE_DESC_SECTIONS_KEE" ON "RULE_DESC_SECTIONS"("RULE_UUID" NULLS FIRST, "KEE" NULLS FIRST);
"Rule " + descriptionFormat + " contains section(s) but has no format set");
switch (nonNullDescriptionFormat) {
case MARKDOWN:
- return Markdown.convertToHtml(ruleDescriptionSectionDto.getDescription());
+ return Markdown.convertToHtml(ruleDescriptionSectionDto.getContent());
case HTML:
- return ruleDescriptionSectionDto.getDescription();
+ return ruleDescriptionSectionDto.getContent();
default:
throw new IllegalStateException(format("Rule description section format '%s' is unknown for rule key '%s'", descriptionFormat, ruleKey));
}
public void getHtmlDescriptionAsIs() {
RuleDefinitionDto rule = new RuleDefinitionDto().setDescriptionFormat(RuleDto.Format.HTML).addRuleDescriptionSectionDto(HTML_SECTION);
String html = RuleDescriptionFormatter.getDescriptionAsHtml(rule);
- assertThat(html).isEqualTo(HTML_SECTION.getDescription());
+ assertThat(html).isEqualTo(HTML_SECTION.getContent());
}
@Test
@Test
public void getHtmlDescriptionForRuleForIndexingDtoAsIs() {
Set<RuleDescriptionSectionDto> sectionsDtos = Sets.newHashSet(
- createDefaultRuleDescriptionSection("uuid", HTML_SECTION.getDescription()));
+ createDefaultRuleDescriptionSection("uuid", HTML_SECTION.getContent()));
RuleForIndexingDto rule = createRuleForIndexingDto(sectionsDtos, RuleDto.Format.HTML);
String html = RuleDescriptionFormatter.getDescriptionAsHtml(rule);
- assertThat(html).isEqualTo(HTML_SECTION.getDescription());
+ assertThat(html).isEqualTo(HTML_SECTION.getContent());
}
@Test
@Test
public void handleNullDescriptionFormatForRuleForIndexingDto() {
Set<RuleDescriptionSectionDto> sectionsDtos = Sets.newHashSet(
- createDefaultRuleDescriptionSection("uuid", HTML_SECTION.getDescription()));
+ createDefaultRuleDescriptionSection("uuid", HTML_SECTION.getContent()));
RuleForIndexingDto rule = createRuleForIndexingDto(sectionsDtos, null);
String result = RuleDescriptionFormatter.getDescriptionAsHtml(rule);
assertThat(result).isNull();
assertThat(rule.getSeverity().name()).isEqualTo(ruleDefinition.getSeverityString());
assertThat(rule.getSystemTags()).isEqualTo(ruleDefinition.getSystemTags().toArray(new String[0]));
assertThat(rule.getTags()).isEmpty();
- assertThat(rule.getDescription()).isEqualTo(ruleDefinition.getDefaultRuleDescriptionSectionDto().getDescription());
+ assertThat(rule.getDescription()).isEqualTo(ruleDefinition.getDefaultRuleDescriptionSectionDto().getContent());
assertThat(rule.getParams()).hasSize(1);
org.sonar.api.rules.RuleParam param = rule.getParams().iterator().next();
import org.sonar.db.qualityprofile.ActiveRuleParamDto;
import org.sonar.db.rule.DeprecatedRuleKeyDto;
import org.sonar.db.rule.RuleDefinitionDto;
+import org.sonar.db.rule.RuleDescriptionSectionDto;
import org.sonar.db.rule.RuleDto.Format;
import org.sonar.db.rule.RuleDto.Scope;
import org.sonar.db.rule.RuleParamDto;
.setIsAdHoc(false)
.setCreatedAt(system2.now())
.setUpdatedAt(system2.now());
- if (isNotEmpty(ruleDef.htmlDescription())) {
- ruleDto.addRuleDescriptionSectionDto(createDefaultRuleDescriptionSection(uuidFactory.create(), ruleDef.htmlDescription()));
+ String htmlDescription = ruleDef.htmlDescription();
+ if (isNotEmpty(htmlDescription)) {
+ ruleDto.addRuleDescriptionSectionDto(createDefaultRuleDescriptionSection(uuidFactory.create(), htmlDescription));
ruleDto.setDescriptionFormat(Format.HTML);
- } else if (isNotEmpty(ruleDef.markdownDescription())) {
- ruleDto.addRuleDescriptionSectionDto(createDefaultRuleDescriptionSection(uuidFactory.create(), ruleDef.markdownDescription()));
- ruleDto.setDescriptionFormat(Format.MARKDOWN);
+ } else {
+ String markdownDescription = ruleDef.markdownDescription();
+ if (isNotEmpty(markdownDescription)) {
+ ruleDto.addRuleDescriptionSectionDto(createDefaultRuleDescriptionSection(uuidFactory.create(), markdownDescription));
+ ruleDto.setDescriptionFormat(Format.MARKDOWN);
+ }
}
DebtRemediationFunction debtRemediationFunction = ruleDef.debtRemediationFunction();
private boolean mergeDescription(RulesDefinition.Rule rule, RuleDefinitionDto ruleDefinitionDto) {
boolean changed = false;
- String currentDescription = ruleDefinitionDto.getDefaultRuleDescriptionSectionDto() != null ? ruleDefinitionDto.getDefaultRuleDescriptionSectionDto().getDescription() : null;
- if (isHtmlDescriptionUpdated(rule, currentDescription)) {
- ruleDefinitionDto.addOrReplaceRuleDescriptionSectionDto(createDefaultRuleDescriptionSection(uuidFactory.create(), rule.htmlDescription()));
+ String currentDescription = Optional.ofNullable(ruleDefinitionDto.getDefaultRuleDescriptionSectionDto())
+ .map(RuleDescriptionSectionDto::getContent)
+ .orElse(null);
+
+ String htmlDescription = rule.htmlDescription();
+ String markdownDescription = rule.markdownDescription();
+ if (isDescriptionUpdated(htmlDescription, currentDescription)) {
+ ruleDefinitionDto.addOrReplaceRuleDescriptionSectionDto(createDefaultRuleDescriptionSection(uuidFactory.create(), htmlDescription));
ruleDefinitionDto.setDescriptionFormat(Format.HTML);
changed = true;
- } else if (isMarkdownDescriptionUpdated(rule, currentDescription)) {
- ruleDefinitionDto.addOrReplaceRuleDescriptionSectionDto(createDefaultRuleDescriptionSection(uuidFactory.create(), rule.markdownDescription()));
+ } else if (isDescriptionUpdated(markdownDescription, currentDescription)) {
+ ruleDefinitionDto.addOrReplaceRuleDescriptionSectionDto(createDefaultRuleDescriptionSection(uuidFactory.create(), markdownDescription));
ruleDefinitionDto.setDescriptionFormat(Format.MARKDOWN);
changed = true;
}
return changed;
}
- private static boolean isMarkdownDescriptionUpdated(RulesDefinition.Rule rule, @Nullable String currentDescription) {
- return isNotEmpty(rule.markdownDescription()) && !Objects.equals(rule.markdownDescription(), currentDescription);
- }
-
- private static boolean isHtmlDescriptionUpdated(RulesDefinition.Rule def, @Nullable String currentDescription) {
- return isNotEmpty(def.htmlDescription()) && !Objects.equals(def.htmlDescription(), currentDescription);
+ private static boolean isDescriptionUpdated(@Nullable String description, @Nullable String currentDescription) {
+ return isNotEmpty(description) && !Objects.equals(description, currentDescription);
}
private static boolean mergeDebtDefinitions(RulesDefinition.Rule def, RuleDefinitionDto dto) {
import org.sonar.db.DbTester;
import org.sonar.db.rule.DeprecatedRuleKeyDto;
import org.sonar.db.rule.RuleDefinitionDto;
+import org.sonar.db.rule.RuleDescriptionSectionDto;
import org.sonar.db.rule.RuleDto;
import org.sonar.db.rule.RuleDto.Scope;
import org.sonar.db.rule.RuleParamDto;
import static org.sonar.api.server.rule.RulesDefinition.NewRule;
import static org.sonar.api.server.rule.RulesDefinition.OwaspTop10;
import static org.sonar.api.server.rule.RulesDefinition.OwaspTop10Version.Y2021;
+import static org.sonar.db.rule.RuleDescriptionSectionDto.DEFAULT_KEY;
import static org.sonar.db.rule.RuleDescriptionSectionDto.createDefaultRuleDescriptionSection;
@RunWith(DataProviderRunner.class)
assertThat(dbClient.ruleDao().selectAllDefinitions(db.getSession())).hasSize(3);
RuleDto rule1 = dbClient.ruleDao().selectOrFailByKey(db.getSession(), RULE_KEY1);
assertThat(rule1.getName()).isEqualTo("One");
- assertThat(rule1.getDefaultRuleDescriptionSection().getDescription()).isEqualTo("Description of One");
+ assertThat(rule1.getDefaultRuleDescriptionSection().getContent()).isEqualTo("Description of One");
assertThat(rule1.getSeverityString()).isEqualTo(BLOCKER);
assertThat(rule1.getTags()).isEmpty();
assertThat(rule1.getSystemTags()).containsOnly("tag1", "tag2", "tag3");
RuleDto hotspotRule = dbClient.ruleDao().selectOrFailByKey(db.getSession(), HOTSPOT_RULE_KEY);
assertThat(hotspotRule.getName()).isEqualTo("Hotspot");
- assertThat(hotspotRule.getDefaultRuleDescriptionSection().getDescription()).isEqualTo("Minimal hotspot");
+ assertThat(hotspotRule.getDefaultRuleDescriptionSection().getContent()).isEqualTo("Minimal hotspot");
assertThat(hotspotRule.getCreatedAt()).isEqualTo(DATE1.getTime());
assertThat(hotspotRule.getUpdatedAt()).isEqualTo(DATE1.getTime());
assertThat(hotspotRule.getType()).isEqualTo(RuleType.SECURITY_HOTSPOT.getDbConstant());
assertThat(dbClient.ruleDao().selectAllDefinitions(db.getSession())).hasSize(2);
RuleDto rule1 = dbClient.ruleDao().selectOrFailByKey(db.getSession(), EXTERNAL_RULE_KEY1);
assertThat(rule1.getName()).isEqualTo("One");
- assertThat(rule1.getDefaultRuleDescriptionSection().getDescription()).isEqualTo("Description of One");
+ assertThat(rule1.getDefaultRuleDescriptionSection().getContent()).isEqualTo("Description of One");
assertThat(rule1.getSeverityString()).isEqualTo(BLOCKER);
assertThat(rule1.getTags()).isEmpty();
assertThat(rule1.getSystemTags()).containsOnly("tag1", "tag2", "tag3");
RuleDto hotspotRule = dbClient.ruleDao().selectOrFailByKey(db.getSession(), EXTERNAL_HOTSPOT_RULE_KEY);
assertThat(hotspotRule.getName()).isEqualTo("Hotspot");
- assertThat(hotspotRule.getDefaultRuleDescriptionSection().getDescription()).isEqualTo("Minimal hotspot");
+ assertThat(hotspotRule.getDefaultRuleDescriptionSection().getContent()).isEqualTo("Minimal hotspot");
assertThat(hotspotRule.getCreatedAt()).isEqualTo(DATE1.getTime());
assertThat(hotspotRule.getUpdatedAt()).isEqualTo(DATE1.getTime());
assertThat(hotspotRule.getType()).isEqualTo(RuleType.SECURITY_HOTSPOT.getDbConstant());
verifyIndicesNotMarkedAsInitialized();
// rule1 has been updated
rule1 = dbClient.ruleDao().selectOrFailByKey(db.getSession(), RULE_KEY1);
- assertThat(rule1.getName()).isEqualTo("One v2");
- assertThat(rule1.getDefaultRuleDescriptionSection().getDescription()).isEqualTo("Description of One v2");
- assertThat(rule1.getSeverityString()).isEqualTo(INFO);
- assertThat(rule1.getTags()).containsOnly("usertag1", "usertag2");
- assertThat(rule1.getSystemTags()).containsOnly("tag1", "tag4");
- assertThat(rule1.getConfigKey()).isEqualTo("config1 v2");
- assertThat(rule1.getNoteData()).isEqualTo("user *note*");
- assertThat(rule1.getNoteUserUuid()).isEqualTo("marius");
- assertThat(rule1.getStatus()).isEqualTo(READY);
- assertThat(rule1.getType()).isEqualTo(RuleType.BUG.getDbConstant());
- assertThat(rule1.getCreatedAt()).isEqualTo(DATE1.getTime());
- assertThat(rule1.getUpdatedAt()).isEqualTo(DATE2.getTime());
+ assertThatRule1IsV2(rule1);
List<RuleParamDto> params = dbClient.ruleDao().selectRuleParamsByRuleKey(db.getSession(), RULE_KEY1);
assertThat(params).hasSize(2);
// verify repositories
assertThat(dbClient.ruleRepositoryDao().selectAll(db.getSession())).extracting(RuleRepositoryDto::getKey).containsOnly("fake");
+
+ system.setNow(DATE3.getTime());
+ execute(new FakeRepositoryV3());
+ rule3 = dbClient.ruleDao().selectOrFailByKey(db.getSession(), RULE_KEY3);
+ assertThat(rule3.getDefaultRuleDescriptionSection().getContent()).isEqualTo("Rule Three V2");
+ assertThat(rule3.getDescriptionFormat()).isEqualTo(RuleDto.Format.MARKDOWN);
+ }
+
+ private void assertThatRule1IsV2(RuleDto rule1) {
+ assertThat(rule1.getName()).isEqualTo("One v2");
+ RuleDescriptionSectionDto defaultRuleDescriptionSection = rule1.getDefaultRuleDescriptionSection();
+ assertThat(defaultRuleDescriptionSection.getContent()).isEqualTo("Description of One v2");
+ assertThat(defaultRuleDescriptionSection.getKey()).isEqualTo(DEFAULT_KEY);
+ assertThat(rule1.getDescriptionFormat()).isEqualTo(RuleDto.Format.HTML);
+ assertThat(rule1.getSeverityString()).isEqualTo(INFO);
+ assertThat(rule1.getTags()).containsOnly("usertag1", "usertag2");
+ assertThat(rule1.getSystemTags()).containsOnly("tag1", "tag4");
+ assertThat(rule1.getConfigKey()).isEqualTo("config1 v2");
+ assertThat(rule1.getNoteData()).isEqualTo("user *note*");
+ assertThat(rule1.getNoteUserUuid()).isEqualTo("marius");
+ assertThat(rule1.getStatus()).isEqualTo(READY);
+ assertThat(rule1.getType()).isEqualTo(RuleType.BUG.getDbConstant());
+ assertThat(rule1.getCreatedAt()).isEqualTo(DATE1.getTime());
+ assertThat(rule1.getUpdatedAt()).isEqualTo(DATE2.getTime());
}
@Test
// rule1 has been updated
RuleDto rule1 = dbClient.ruleDao().selectOrFailByKey(db.getSession(), RuleKey.of("fake", "rule"));
assertThat(rule1.getName()).isEqualTo("Name2");
- assertThat(rule1.getDefaultRuleDescriptionSection().getDescription()).isEqualTo("Description");
+ assertThat(rule1.getDefaultRuleDescriptionSection().getContent()).isEqualTo("Description");
assertThat(ruleIndex.search(new RuleQuery().setQueryText("Name2"), new SearchOptions()).getTotal()).isOne();
assertThat(ruleIndex.search(new RuleQuery().setQueryText("Name1"), new SearchOptions()).getTotal()).isZero();
RuleDto rule2 = dbClient.ruleDao().selectOrFailByKey(db.getSession(), RuleKey.of(repository, ruleKey2));
assertThat(rule2.getUuid()).isEqualTo(rule1.getUuid());
assertThat(rule2.getName()).isEqualTo("Name2");
- assertThat(rule2.getDefaultRuleDescriptionSection().getDescription()).isEqualTo(rule1.getDefaultRuleDescriptionSection().getDescription());
+ assertThat(rule2.getDefaultRuleDescriptionSection().getContent()).isEqualTo(rule1.getDefaultRuleDescriptionSection().getContent());
SearchIdResult<String> searchRule2 = ruleIndex.search(new RuleQuery().setQueryText("Name2"), new SearchOptions());
assertThat(searchRule2.getUuids()).containsOnly(rule2.getUuid());
RuleDto rule2 = dbClient.ruleDao().selectOrFailByKey(db.getSession(), RuleKey.of(repository2, ruleKey));
assertThat(rule2.getUuid()).isEqualTo(rule1.getUuid());
assertThat(rule2.getName()).isEqualTo("Name2");
- assertThat(rule2.getDefaultRuleDescriptionSection().getDescription()).isEqualTo(rule1.getDefaultRuleDescriptionSection().getDescription());
+ assertThat(rule2.getDefaultRuleDescriptionSection().getContent()).isEqualTo(rule1.getDefaultRuleDescriptionSection().getContent());
SearchIdResult<String> searchRule2 = ruleIndex.search(new RuleQuery().setQueryText("Name2"), new SearchOptions());
assertThat(searchRule2.getUuids()).containsOnly(rule2.getUuid());
RuleDto rule2 = dbClient.ruleDao().selectOrFailByKey(db.getSession(), RuleKey.of(repo2, ruleKey2));
assertThat(rule2.getUuid()).isEqualTo(rule1.getUuid());
assertThat(rule2.getName()).isEqualTo(rule1.getName());
- assertThat(rule2.getDefaultRuleDescriptionSection().getDescription()).isEqualTo(rule1.getDefaultRuleDescriptionSection().getDescription());
+ assertThat(rule2.getDefaultRuleDescriptionSection().getContent()).isEqualTo(rule1.getDefaultRuleDescriptionSection().getContent());
assertThat(ruleIndex.search(new RuleQuery().setQueryText(name), new SearchOptions()).getUuids())
.containsOnly(rule2.getUuid());
// rule1 has been updated
RuleDto rule1 = dbClient.ruleDao().selectOrFailByKey(db.getSession(), RuleKey.of("fake", "rule"));
assertThat(rule1.getName()).isEqualTo("Name");
- assertThat(rule1.getDefaultRuleDescriptionSection().getDescription()).isEqualTo("Desc2");
+ assertThat(rule1.getDefaultRuleDescriptionSection().getContent()).isEqualTo("Desc2");
assertThat(ruleIndex.search(new RuleQuery().setQueryText("Desc2"), new SearchOptions()).getTotal()).isOne();
assertThat(ruleIndex.search(new RuleQuery().setQueryText("Desc1"), new SearchOptions()).getTotal()).isZero();
NewRepository repo = context.createExternalRepository("fake", rule.getLanguage());
repo.createRule(rule.getRuleKey())
.setName(rule.getName())
- .setHtmlDescription(rule.getDefaultRuleDescriptionSectionDto().getDescription());
+ .setHtmlDescription(rule.getDefaultRuleDescriptionSectionDto().getContent());
repo.done();
});
}
}
+ static class FakeRepositoryV3 implements RulesDefinition {
+ @Override
+ public void define(Context context) {
+ NewRepository repo = context.createRepository("fake", "java");
+ // rule 3 is dropped
+ repo.createRule(RULE_KEY3.rule())
+ .setName("Three")
+ .setMarkdownDescription("Rule Three V2");
+
+ repo.done();
+ }
+ }
+
static class ExternalRuleRepository implements RulesDefinition {
@Override
public void define(Context context) {
importedRule.setType(exportRuleDto.getRuleType().name());
exportRuleDto.getRuleDescriptionSections()
.stream()
- .map(r -> new NewRuleDescriptionSection(r.getKey(), r.getDescription()))
+ .map(r -> new NewRuleDescriptionSection(r.getKey(), r.getContent()))
.forEach(importedRule::addRuleDescriptionSection);
importedRule.setParameters(exportRuleDto.getParams().stream().collect(Collectors.toMap(ExportRuleParamDto::getKey, ExportRuleParamDto::getValue)));
importedRules.add(importedRule);
private static final String ATTRIBUTE_DESCRIPTION_SECTIONS = "descriptionSections";
private static final String ATTRIBUTE_DESCRIPTION_SECTION = "descriptionSection";
private static final String ATTRIBUTE_DESCRIPTION_SECTION_KEY = "key";
- private static final String ATTRIBUTE_DESCRIPTION_SECTION_DESCRIPTION = "content";
+ private static final String ATTRIBUTE_DESCRIPTION_SECTION_CONTENT = "content";
private static final String ATTRIBUTE_REPOSITORY_KEY = "repositoryKey";
private static final String ATTRIBUTE_KEY = "key";
private static final String ATTRIBUTE_PRIORITY = "priority";
xml.prop(ATTRIBUTE_TEMPLATE_KEY, ruleToExport.getTemplateRuleKey().rule());
if (!ruleToExport.getRuleDescriptionSections().isEmpty()) {
ruleToExport.getDefaultRuleDescriptionSectionDto()
- .map(RuleDescriptionSectionDto::getDescription)
+ .map(RuleDescriptionSectionDto::getContent)
.ifPresent(desc -> xml.prop(ATTRIBUTE_DESCRIPTION, desc));
}
xml.begin(ATTRIBUTE_DESCRIPTION_SECTIONS);
for (RuleDescriptionSectionDto ruleDescriptionSection : ruleToExport.getRuleDescriptionSections()) {
xml.begin(ATTRIBUTE_DESCRIPTION_SECTION)
.prop(ATTRIBUTE_DESCRIPTION_SECTION_KEY, ruleDescriptionSection.getKey())
- .prop(ATTRIBUTE_DESCRIPTION_SECTION_DESCRIPTION, ruleDescriptionSection.getDescription())
+ .prop(ATTRIBUTE_DESCRIPTION_SECTION_CONTENT, ruleDescriptionSection.getContent())
.end();
}
xml.end(ATTRIBUTE_DESCRIPTION_SECTIONS);
String nodeName = propCursor.getLocalName();
if (StringUtils.equals(ATTRIBUTE_DESCRIPTION_SECTION_KEY, nodeName)) {
key = StringUtils.trim(propCursor.collectDescendantText(false));
- } else if (StringUtils.equals(ATTRIBUTE_DESCRIPTION_SECTION_DESCRIPTION, nodeName)) {
+ } else if (StringUtils.equals(ATTRIBUTE_DESCRIPTION_SECTION_CONTENT, nodeName)) {
description = StringUtils.trim(propCursor.collectDescendantText(false));
}
}
public class NewRuleDescriptionSection {
private final String key;
- private final String description;
+ private final String content;
- public NewRuleDescriptionSection(String key, String description) {
+ public NewRuleDescriptionSection(String key, String content) {
this.key = key;
- this.description = description;
+ this.content = content;
}
public String getKey() {
return key;
}
- public String getDescription() {
- return description;
+ public String getContent() {
+ return content;
}
}
}
private static boolean noDescriptionSectionHasContent(NewCustomRule newRule) {
- return newRule.getRuleDescriptionSections().stream().map(NewRuleDescriptionSection::getDescription).allMatch(Strings::isNullOrEmpty);
+ return newRule.getRuleDescriptionSections().stream().map(NewRuleDescriptionSection::getContent).allMatch(Strings::isNullOrEmpty);
}
private static void validateRuleKey(List<String> errors, String ruleKey) {
RuleDescriptionSectionDto ruleDescriptionSectionDto = RuleDescriptionSectionDto.builder()
.uuid(uuidFactory.create())
.key(ruleDescriptionSection.getKey())
- .description(ruleDescriptionSection.getDescription())
+ .content(ruleDescriptionSection.getContent())
.build();
ruleDefinition.addRuleDescriptionSectionDto(ruleDescriptionSectionDto);
}
listResponseBuilder.build().writeTo(wsResponse.stream().output());
}
- private ListResponse.Rule toRule(ListResponse.Rule.Builder ruleBuilder, RuleDefinitionDto dto) {
+ private static ListResponse.Rule toRule(ListResponse.Rule.Builder ruleBuilder, RuleDefinitionDto dto) {
return ruleBuilder
.clear()
.setRepository(dto.getRepositoryKey())
private static String concatenateSectionTemporaryForSonar16302(RuleDefinitionDto ruleDto) {
return ruleDto.getRuleDescriptionSectionDtos().stream()
- .map(RuleDescriptionSectionDto::getDescription)
+ .map(RuleDescriptionSectionDto::getContent)
.collect(joining());
}
"<priority>" + activeRule.getSeverityString() + "</priority>" +
"<name>" + rule.getName() + "</name>" +
"<templateKey>" + templateRule.getKey().rule() + "</templateKey>" +
- "<description>" + rule.getDefaultRuleDescriptionSectionDto().getDescription() + "</description>" +
- "<descriptionSections><descriptionSection><key>default</key><content>" + rule.getDefaultRuleDescriptionSectionDto().getDescription() + "</content></descriptionSection></descriptionSections>" +
+ "<description>" + rule.getDefaultRuleDescriptionSectionDto().getContent() + "</description>" +
+ "<descriptionSections><descriptionSection><key>default</key><content>" + rule.getDefaultRuleDescriptionSectionDto().getContent() + "</content></descriptionSection></descriptionSections>" +
"<parameters><parameter>" +
"<key>" + param.getName() + "</key>" +
"<value>20</value>" +
"<priority>CRITICAL</priority>" +
"<name>custom rule name</name>" +
"<templateKey>rule_mc8</templateKey>" +
- "<descriptionSections><descriptionSection><key>default</key><content>custom rule description</content></descriptionSection></descriptionSections>" +
+ "<descriptionSections><descriptionSection><key>default</key><content>custom rule section content</content></descriptionSection></descriptionSections>" +
"<parameters><parameter>" +
"<key>bar</key>" +
"<value>baz</value>" +
assertThat(importedRule.getRuleDescriptionSections()).hasSize(1);
var section = importedRule.getRuleDescriptionSections().iterator().next();
assertThat(section.getKey()).isEqualTo("default");
- assertThat(section.getDescription()).isEqualTo("custom rule description");
+ assertThat(section.getContent()).isEqualTo("custom rule section content");
}
}
assertThat(rule.getPluginKey()).isEqualTo("sonarjava");
assertThat(rule.getTemplateUuid()).isEqualTo(templateRule.getUuid());
assertThat(rule.getName()).isEqualTo("My custom");
- assertThat(rule.getDefaultRuleDescriptionSection().getDescription()).isEqualTo("Some description");
+ assertThat(rule.getDefaultRuleDescriptionSection().getContent()).isEqualTo("Some description");
assertThat(rule.getSeverityString()).isEqualTo("MAJOR");
assertThat(rule.getStatus()).isEqualTo(RuleStatus.READY);
assertThat(rule.getLanguage()).isEqualTo("java");
assertThat(rule.getPluginKey()).isEqualTo("sonarjava");
assertThat(rule.getTemplateUuid()).isEqualTo(templateRule.getUuid());
assertThat(rule.getName()).isEqualTo("My custom");
- assertThat(rule.getDefaultRuleDescriptionSection().getDescription()).isEqualTo("new description section");
+ assertThat(rule.getDefaultRuleDescriptionSection().getContent()).isEqualTo("new description section");
assertThat(rule.getSeverityString()).isEqualTo("MAJOR");
assertThat(rule.getStatus()).isEqualTo(RuleStatus.READY);
assertThat(rule.getLanguage()).isEqualTo("java");
// These values should be the same than before
assertThat(result.getName()).isEqualTo("Old name");
- assertThat(result.getDefaultRuleDescriptionSectionDto().getDescription()).isEqualTo("Old description");
+ assertThat(result.getDefaultRuleDescriptionSectionDto().getContent()).isEqualTo("Old description");
assertThat(result.getSeverityString()).isEqualTo(Severity.INFO);
List<RuleParamDto> params = dbTester.getDbClient().ruleDao().selectRuleParamsByRuleKey(dbSession, customRuleKey);
RuleDto customRuleReloaded = db.getDbClient().ruleDao().selectOrFailByKey(dbSession, customRule.getKey());
assertThat(customRuleReloaded).isNotNull();
assertThat(customRuleReloaded.getName()).isEqualTo("New name");
- assertThat(customRuleReloaded.getDefaultRuleDescriptionSection().getDescription()).isEqualTo("New description");
+ assertThat(customRuleReloaded.getDefaultRuleDescriptionSection().getContent()).isEqualTo("New description");
assertThat(customRuleReloaded.getSeverityString()).isEqualTo("MAJOR");
assertThat(customRuleReloaded.getStatus()).isEqualTo(RuleStatus.READY);