Browse Source

SONAR-13582 Drop 'Language specific parameters' setting

tags/10.5.0.89998
Julien HENRY 1 month ago
parent
commit
93ac36f764
15 changed files with 167 additions and 377 deletions
  1. 1
    1
      server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/qualitymodel/MaintainabilityMeasuresVisitor.java
  2. 3
    3
      server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/qualitymodel/NewMaintainabilityMeasuresVisitor.java
  3. 1
    78
      server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/qualitymodel/RatingSettings.java
  4. 22
    24
      server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/qualitymodel/MaintainabilityMeasuresVisitorTest.java
  5. 8
    21
      server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/qualitymodel/NewMaintainabilityMeasuresVisitorTest.java
  6. 2
    53
      server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/qualitymodel/RatingSettingsTest.java
  7. 86
    0
      server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v105/DeleteLanguageSpecificParametersPropertySetIT.java
  8. 2
    1
      server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v105/DbVersion105.java
  9. 39
    0
      server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v105/DeleteLanguageSpecificParametersPropertySet.java
  10. 0
    26
      server/sonar-web/src/main/js/helpers/mocks/definitions-list.ts
  11. 0
    57
      server/sonar-webserver-core/src/main/java/org/sonar/server/platform/db/CheckLanguageSpecificParamsAtStartup.java
  12. 0
    81
      server/sonar-webserver-core/src/test/java/org/sonar/server/platform/db/CheckLanguageSpecificParamsAtStartupTest.java
  13. 0
    2
      server/sonar-webserver/src/main/java/org/sonar/server/platform/platformlevel/PlatformLevel4.java
  14. 2
    20
      sonar-core/src/main/java/org/sonar/core/config/DebtProperties.java
  15. 1
    10
      sonar-ws/src/testFixtures/java/org/sonarqube/ws/tester/QModelTester.java

+ 1
- 1
server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/qualitymodel/MaintainabilityMeasuresVisitor.java View File

@@ -94,7 +94,7 @@ public class MaintainabilityMeasuresVisitor extends PathAwareVisitorAdapter<Main
private long computeDevelopmentCost(Component file) {
Optional<Measure> measure = measureRepository.getRawMeasure(file, nclocMetric);
long ncloc = measure.map(Measure::getIntValue).orElse(0);
return ncloc * ratingSettings.getDevCost(file.getFileAttributes().getLanguageKey());
return ncloc * ratingSettings.getDevCost();
}

private void computeAndSaveMeasures(Component component, Path<Counter> path) {

+ 3
- 3
server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/qualitymodel/NewMaintainabilityMeasuresVisitor.java View File

@@ -22,10 +22,10 @@ package org.sonar.ce.task.projectanalysis.qualitymodel;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
import org.sonar.api.measures.CoreMetrics;
import org.sonar.api.utils.KeyValueFormat;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.sonar.api.measures.CoreMetrics;
import org.sonar.api.utils.KeyValueFormat;
import org.sonar.ce.task.projectanalysis.component.Component;
import org.sonar.ce.task.projectanalysis.component.CrawlerDepthLimit;
import org.sonar.ce.task.projectanalysis.component.PathAwareVisitorAdapter;
@@ -159,7 +159,7 @@ public class NewMaintainabilityMeasuresVisitor extends PathAwareVisitorAdapter<N
private void initNewDebtRatioCounter(Counter devCostCounter, Component file, Measure nclocDataMeasure, Set<Integer> changedLines) {
boolean hasDevCost = false;

long lineDevCost = ratingSettings.getDevCost(file.getFileAttributes().getLanguageKey());
long lineDevCost = ratingSettings.getDevCost();
for (Integer nclocLineIndex : nclocLineIndexes(nclocDataMeasure)) {
if (changedLines.contains(nclocLineIndex)) {
devCostCounter.incrementDevCost(lineDevCost);

+ 1
- 78
server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/qualitymodel/RatingSettings.java View File

@@ -19,73 +19,31 @@
*/
package org.sonar.ce.task.projectanalysis.qualitymodel;

import com.google.common.collect.ImmutableMap;
import java.util.Map;
import javax.annotation.CheckForNull;
import javax.annotation.Nullable;
import javax.annotation.concurrent.Immutable;
import org.sonar.api.ce.ComputeEngineSide;
import org.sonar.api.config.Configuration;
import org.sonar.api.utils.MessageException;
import org.sonar.server.measure.DebtRatingGrid;

import static java.lang.String.format;
import static org.sonar.api.CoreProperties.DEVELOPMENT_COST;
import static org.sonar.api.CoreProperties.LANGUAGE_SPECIFIC_PARAMETERS;
import static org.sonar.api.CoreProperties.LANGUAGE_SPECIFIC_PARAMETERS_LANGUAGE_KEY;
import static org.sonar.api.CoreProperties.LANGUAGE_SPECIFIC_PARAMETERS_MAN_DAYS_KEY;
import static org.sonar.api.CoreProperties.LANGUAGE_SPECIFIC_PARAMETERS_SIZE_METRIC_KEY;

@ComputeEngineSide
public class RatingSettings {

private final DebtRatingGrid ratingGrid;
private final long defaultDevCost;
private final Map<String, LanguageSpecificConfiguration> languageSpecificConfigurationByLanguageKey;

public RatingSettings(Configuration config) {
ratingGrid = new DebtRatingGrid(config);
defaultDevCost = initDefaultDevelopmentCost(config);
languageSpecificConfigurationByLanguageKey = initLanguageSpecificConfigurationByLanguageKey(config);
}

public DebtRatingGrid getDebtRatingGrid() {
return ratingGrid;
}

public long getDevCost(@Nullable String languageKey) {
if (languageKey != null) {
try {
LanguageSpecificConfiguration languageSpecificConfig = getSpecificParametersForLanguage(languageKey);
if (languageSpecificConfig != null && languageSpecificConfig.getManDays() != null) {
return Long.parseLong(languageSpecificConfig.getManDays());
}
} catch (NumberFormatException e) {
throw new IllegalArgumentException(format("The manDays for language %s is not a valid long number", languageKey), e);
}
}

public long getDevCost() {
return defaultDevCost;
}

@CheckForNull
private LanguageSpecificConfiguration getSpecificParametersForLanguage(String languageKey) {
return languageSpecificConfigurationByLanguageKey.get(languageKey);
}

private static Map<String, LanguageSpecificConfiguration> initLanguageSpecificConfigurationByLanguageKey(Configuration config) {
ImmutableMap.Builder<String, LanguageSpecificConfiguration> builder = ImmutableMap.builder();
String[] languageConfigIndexes = config.getStringArray(LANGUAGE_SPECIFIC_PARAMETERS);
for (String languageConfigIndex : languageConfigIndexes) {
String languagePropertyKey = LANGUAGE_SPECIFIC_PARAMETERS + "." + languageConfigIndex + "." + LANGUAGE_SPECIFIC_PARAMETERS_LANGUAGE_KEY;
String languageKey = config.get(languagePropertyKey)
.orElseThrow(() -> MessageException.of("Technical debt configuration is corrupted. At least one language specific parameter has no Language key. " +
"Contact your administrator to update this configuration in the global administration section of SonarQube."));
builder.put(languageKey, LanguageSpecificConfiguration.create(config, languageConfigIndex));
}
return builder.build();
}

private static long initDefaultDevelopmentCost(Configuration config) {
try {
return Long.parseLong(config.get(DEVELOPMENT_COST).get());
@@ -95,39 +53,4 @@ public class RatingSettings {
}
}

@Immutable
private static class LanguageSpecificConfiguration {
private final String language;
private final String manDays;
private final String metricKey;

private LanguageSpecificConfiguration(String language, String manDays, String metricKey) {
this.language = language;
this.manDays = manDays;
this.metricKey = metricKey;
}

static LanguageSpecificConfiguration create(Configuration config, String configurationId) {

String configurationPrefix = LANGUAGE_SPECIFIC_PARAMETERS + "." + configurationId + ".";

String language = config.get(configurationPrefix + LANGUAGE_SPECIFIC_PARAMETERS_LANGUAGE_KEY).orElse(null);
String manDays = config.get(configurationPrefix + LANGUAGE_SPECIFIC_PARAMETERS_MAN_DAYS_KEY).orElse(null);
String metric = config.get(configurationPrefix + LANGUAGE_SPECIFIC_PARAMETERS_SIZE_METRIC_KEY).orElse(null);

return new LanguageSpecificConfiguration(language, manDays, metric);
}

String getLanguage() {
return language;
}

String getManDays() {
return manDays;
}

String getMetricKey() {
return metricKey;
}
}
}

+ 22
- 24
server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/qualitymodel/MaintainabilityMeasuresVisitorTest.java View File

@@ -68,8 +68,7 @@ public class MaintainabilityMeasuresVisitorTest {

static final double[] RATING_GRID = new double[] {0.1, 0.2, 0.5, 1};

static final long DEV_COST_LANGUAGE_1 = 30;
static final long DEV_COST_LANGUAGE_2 = 42;
static final long DEV_COST = 30;

static final int PROJECT_REF = 1;
static final int DIRECTORY_REF = 123;
@@ -111,8 +110,7 @@ public class MaintainabilityMeasuresVisitorTest {
public void setUp() {
// assumes rating configuration is consistent
when(ratingSettings.getDebtRatingGrid()).thenReturn(new DebtRatingGrid(RATING_GRID));
when(ratingSettings.getDevCost(LANGUAGE_KEY_1)).thenReturn(DEV_COST_LANGUAGE_1);
when(ratingSettings.getDevCost(LANGUAGE_KEY_2)).thenReturn(DEV_COST_LANGUAGE_2);
when(ratingSettings.getDevCost()).thenReturn(DEV_COST);

underTest = new VisitorsCrawler(singletonList(new MaintainabilityMeasuresVisitor(metricRepository, measureRepository, ratingSettings)));
}
@@ -167,26 +165,26 @@ public class MaintainabilityMeasuresVisitorTest {
underTest.visit(root);

// verify measures on files
verifyAddedRawMeasure(1112, DEVELOPMENT_COST_KEY, Long.toString(ncloc1112 * DEV_COST_LANGUAGE_2));
verifyAddedRawMeasure(1113, DEVELOPMENT_COST_KEY, Long.toString(ncloc1113 * DEV_COST_LANGUAGE_1));
verifyAddedRawMeasure(1121, DEVELOPMENT_COST_KEY, Long.toString(nclocValue1121 * DEV_COST_LANGUAGE_2));
verifyAddedRawMeasure(1211, DEVELOPMENT_COST_KEY, Long.toString(ncloc1211 * DEV_COST_LANGUAGE_1));
verifyAddedRawMeasure(1112, DEVELOPMENT_COST_KEY, Long.toString(ncloc1112 * DEV_COST));
verifyAddedRawMeasure(1113, DEVELOPMENT_COST_KEY, Long.toString(ncloc1113 * DEV_COST));
verifyAddedRawMeasure(1121, DEVELOPMENT_COST_KEY, Long.toString(nclocValue1121 * DEV_COST));
verifyAddedRawMeasure(1211, DEVELOPMENT_COST_KEY, Long.toString(ncloc1211 * DEV_COST));

// directory has no children => no file => 0 everywhere and A rating
verifyAddedRawMeasure(122, DEVELOPMENT_COST_KEY, "0");

// directory has children => dev cost is aggregated
verifyAddedRawMeasure(111, DEVELOPMENT_COST_KEY, Long.toString(
ncloc1112 * DEV_COST_LANGUAGE_2 +
ncloc1113 * DEV_COST_LANGUAGE_1));
verifyAddedRawMeasure(112, DEVELOPMENT_COST_KEY, Long.toString(nclocValue1121 * DEV_COST_LANGUAGE_2));
verifyAddedRawMeasure(121, DEVELOPMENT_COST_KEY, Long.toString(ncloc1211 * DEV_COST_LANGUAGE_1));
ncloc1112 * DEV_COST +
ncloc1113 * DEV_COST));
verifyAddedRawMeasure(112, DEVELOPMENT_COST_KEY, Long.toString(nclocValue1121 * DEV_COST));
verifyAddedRawMeasure(121, DEVELOPMENT_COST_KEY, Long.toString(ncloc1211 * DEV_COST));

verifyAddedRawMeasure(1, DEVELOPMENT_COST_KEY, Long.toString(
ncloc1112 * DEV_COST_LANGUAGE_2 +
ncloc1113 * DEV_COST_LANGUAGE_1 +
nclocValue1121 * DEV_COST_LANGUAGE_2 +
ncloc1211 * DEV_COST_LANGUAGE_1));
ncloc1112 * DEV_COST +
ncloc1113 * DEV_COST +
nclocValue1121 * DEV_COST +
ncloc1211 * DEV_COST));
}

@Test
@@ -211,10 +209,10 @@ public class MaintainabilityMeasuresVisitorTest {

underTest.visit(ROOT_PROJECT);

verifyAddedRawMeasure(FILE_1_REF, SQALE_DEBT_RATIO_KEY, file1MaintainabilityCost * 1d / (file1Ncloc * DEV_COST_LANGUAGE_1) * 100);
verifyAddedRawMeasure(FILE_2_REF, SQALE_DEBT_RATIO_KEY, file2MaintainabilityCost * 1d / (file2Ncloc * DEV_COST_LANGUAGE_1) * 100);
verifyAddedRawMeasure(DIRECTORY_REF, SQALE_DEBT_RATIO_KEY, directoryMaintainabilityCost * 1d / ((file1Ncloc + file2Ncloc) * DEV_COST_LANGUAGE_1) * 100);
verifyAddedRawMeasure(PROJECT_REF, SQALE_DEBT_RATIO_KEY, projectMaintainabilityCost * 1d / ((file1Ncloc + file2Ncloc) * DEV_COST_LANGUAGE_1) * 100);
verifyAddedRawMeasure(FILE_1_REF, SQALE_DEBT_RATIO_KEY, file1MaintainabilityCost * 1d / (file1Ncloc * DEV_COST) * 100);
verifyAddedRawMeasure(FILE_2_REF, SQALE_DEBT_RATIO_KEY, file2MaintainabilityCost * 1d / (file2Ncloc * DEV_COST) * 100);
verifyAddedRawMeasure(DIRECTORY_REF, SQALE_DEBT_RATIO_KEY, directoryMaintainabilityCost * 1d / ((file1Ncloc + file2Ncloc) * DEV_COST) * 100);
verifyAddedRawMeasure(PROJECT_REF, SQALE_DEBT_RATIO_KEY, projectMaintainabilityCost * 1d / ((file1Ncloc + file2Ncloc) * DEV_COST) * 100);
}

@Test
@@ -261,13 +259,13 @@ public class MaintainabilityMeasuresVisitorTest {
underTest.visit(ROOT_PROJECT);

verifyAddedRawMeasure(FILE_1_REF, EFFORT_TO_REACH_MAINTAINABILITY_RATING_A_KEY,
(long) (file1Effort - RATING_GRID[0] * file1Ncloc * DEV_COST_LANGUAGE_1));
(long) (file1Effort - RATING_GRID[0] * file1Ncloc * DEV_COST));
verifyAddedRawMeasure(FILE_2_REF, EFFORT_TO_REACH_MAINTAINABILITY_RATING_A_KEY,
(long) (file2Effort - RATING_GRID[0] * file2Ncloc * DEV_COST_LANGUAGE_1));
(long) (file2Effort - RATING_GRID[0] * file2Ncloc * DEV_COST));
verifyAddedRawMeasure(DIRECTORY_REF, EFFORT_TO_REACH_MAINTAINABILITY_RATING_A_KEY,
(long) (dirEffort - RATING_GRID[0] * (file1Ncloc + file2Ncloc) * DEV_COST_LANGUAGE_1));
(long) (dirEffort - RATING_GRID[0] * (file1Ncloc + file2Ncloc) * DEV_COST));
verifyAddedRawMeasure(PROJECT_REF, EFFORT_TO_REACH_MAINTAINABILITY_RATING_A_KEY,
(long) (projectEffort - RATING_GRID[0] * (file1Ncloc + file2Ncloc) * DEV_COST_LANGUAGE_1));
(long) (projectEffort - RATING_GRID[0] * (file1Ncloc + file2Ncloc) * DEV_COST));
}

@Test

+ 8
- 21
server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/qualitymodel/NewMaintainabilityMeasuresVisitorTest.java View File

@@ -64,12 +64,12 @@ import static org.sonar.ce.task.projectanalysis.measure.MeasureAssert.assertThat
import static org.sonar.server.measure.Rating.A;
import static org.sonar.server.measure.Rating.D;

public class NewMaintainabilityMeasuresVisitorTest {
public class NewMaintainabilityMeasuresVisitorTest {

private static final double[] RATING_GRID = new double[] {0.1, 0.2, 0.5, 1};
private static final double[] RATING_GRID = new double[]{0.1, 0.2, 0.5, 1};

private static final String LANGUAGE_1_KEY = "language 1 key";
private static final long LANGUAGE_1_DEV_COST = 30L;
private static final long DEV_COST = 30L;
private static final int ROOT_REF = 1;
private static final int LANGUAGE_1_FILE_REF = 11111;
private static final Offset<Double> VALUE_COMPARISON_OFFSET = Offset.offset(0.01);
@@ -94,6 +94,7 @@ public class NewMaintainabilityMeasuresVisitorTest {
@Before
public void setUp() {
when(ratingSettings.getDebtRatingGrid()).thenReturn(new DebtRatingGrid(RATING_GRID));
when(ratingSettings.getDevCost()).thenReturn(DEV_COST);
underTest = new VisitorsCrawler(Arrays.asList(new NewMaintainabilityMeasuresVisitor(metricRepository, measureRepository, newLinesRepository, ratingSettings)));
}

@@ -122,7 +123,6 @@ public class NewMaintainabilityMeasuresVisitorTest {
@Test
public void file_has_no_new_debt_ratio_variation_if_new_lines_not_available() {
when(newLinesRepository.newLinesAvailable()).thenReturn(false);
when(ratingSettings.getDevCost(LANGUAGE_1_KEY)).thenReturn(LANGUAGE_1_DEV_COST);
setupOneFileAloneInAProject(50, Flag.SRC_FILE, Flag.WITH_NCLOC, Flag.NO_NEW_LINES);
measureRepository.addRawMeasure(ROOT_REF, NEW_TECHNICAL_DEBT_KEY, createNewDebtMeasure(50));

@@ -152,7 +152,6 @@ public class NewMaintainabilityMeasuresVisitorTest {
@Test
public void file_has_new_debt_ratio_if_some_lines_are_new() {
when(newLinesRepository.newLinesAvailable()).thenReturn(true);
when(ratingSettings.getDevCost(LANGUAGE_1_KEY)).thenReturn(LANGUAGE_1_DEV_COST);
setupOneFileAloneInAProject(50, Flag.SRC_FILE, Flag.WITH_NCLOC, Flag.WITH_NEW_LINES);
measureRepository.addRawMeasure(ROOT_REF, NEW_TECHNICAL_DEBT_KEY, createNewDebtMeasure(50));

@@ -164,7 +163,7 @@ public class NewMaintainabilityMeasuresVisitorTest {

@Test
public void new_debt_ratio_changes_with_language_cost() {
when(ratingSettings.getDevCost(LANGUAGE_1_KEY)).thenReturn(LANGUAGE_1_DEV_COST * 10);
when(ratingSettings.getDevCost()).thenReturn(DEV_COST * 10);
setupOneFileAloneInAProject(50, Flag.SRC_FILE, Flag.WITH_NCLOC, Flag.WITH_NEW_LINES);
measureRepository.addRawMeasure(ROOT_REF, NEW_TECHNICAL_DEBT_KEY, createNewDebtMeasure(50));

@@ -176,7 +175,6 @@ public class NewMaintainabilityMeasuresVisitorTest {

@Test
public void new_debt_ratio_changes_with_new_technical_debt() {
when(ratingSettings.getDevCost(LANGUAGE_1_KEY)).thenReturn(LANGUAGE_1_DEV_COST);
setupOneFileAloneInAProject(500, Flag.SRC_FILE, Flag.WITH_NCLOC, Flag.WITH_NEW_LINES);
measureRepository.addRawMeasure(ROOT_REF, NEW_TECHNICAL_DEBT_KEY, createNewDebtMeasure(500));

@@ -188,7 +186,6 @@ public class NewMaintainabilityMeasuresVisitorTest {

@Test
public void new_debt_ratio_on_non_file_level_is_based_on_new_technical_debt_of_that_level() {
when(ratingSettings.getDevCost(LANGUAGE_1_KEY)).thenReturn(LANGUAGE_1_DEV_COST);
setupOneFileAloneInAProject(500, Flag.SRC_FILE, Flag.WITH_NCLOC, Flag.WITH_NEW_LINES);
measureRepository.addRawMeasure(ROOT_REF, NEW_TECHNICAL_DEBT_KEY, createNewDebtMeasure(1200));

@@ -200,7 +197,6 @@ public class NewMaintainabilityMeasuresVisitorTest {

@Test
public void new_debt_ratio_when_file_is_unit_test() {
when(ratingSettings.getDevCost(LANGUAGE_1_KEY)).thenReturn(LANGUAGE_1_DEV_COST);
setupOneFileAloneInAProject(500, Flag.UT_FILE, Flag.WITH_NCLOC, Flag.WITH_NEW_LINES);
measureRepository.addRawMeasure(ROOT_REF, NEW_TECHNICAL_DEBT_KEY, createNewDebtMeasure(1200));

@@ -213,7 +209,6 @@ public class NewMaintainabilityMeasuresVisitorTest {
@Test
public void new_debt_ratio_is_0_when_file_has_no_new_lines() {
when(newLinesRepository.newLinesAvailable()).thenReturn(true);
when(ratingSettings.getDevCost(LANGUAGE_1_KEY)).thenReturn(LANGUAGE_1_DEV_COST);
setupOneFileAloneInAProject(50, Flag.SRC_FILE, Flag.WITH_NCLOC, Flag.NO_NEW_LINES);
measureRepository.addRawMeasure(ROOT_REF, NEW_TECHNICAL_DEBT_KEY, createNewDebtMeasure(50));

@@ -226,7 +221,6 @@ public class NewMaintainabilityMeasuresVisitorTest {
@Test
public void new_debt_ratio_is_0_on_non_file_level_when_no_file_has_new_lines() {
when(newLinesRepository.newLinesAvailable()).thenReturn(true);
when(ratingSettings.getDevCost(LANGUAGE_1_KEY)).thenReturn(LANGUAGE_1_DEV_COST);
setupOneFileAloneInAProject(50, Flag.SRC_FILE, Flag.WITH_NCLOC, Flag.NO_NEW_LINES);
measureRepository.addRawMeasure(ROOT_REF, NEW_TECHNICAL_DEBT_KEY, createNewDebtMeasure(200));

@@ -238,7 +232,6 @@ public class NewMaintainabilityMeasuresVisitorTest {

@Test
public void new_debt_ratio_is_0_when_there_is_no_ncloc_in_file() {
when(ratingSettings.getDevCost(LANGUAGE_1_KEY)).thenReturn(LANGUAGE_1_DEV_COST);
setupOneFileAloneInAProject(50, Flag.SRC_FILE, Flag.NO_NCLOC, Flag.WITH_NEW_LINES);
measureRepository.addRawMeasure(ROOT_REF, NEW_TECHNICAL_DEBT_KEY, createNewDebtMeasure(50));

@@ -250,7 +243,6 @@ public class NewMaintainabilityMeasuresVisitorTest {

@Test
public void new_debt_ratio_is_0_on_non_file_level_when_one_file_has_zero_new_debt_because_of_no_changeset() {
when(ratingSettings.getDevCost(LANGUAGE_1_KEY)).thenReturn(LANGUAGE_1_DEV_COST);
setupOneFileAloneInAProject(50, Flag.SRC_FILE, Flag.NO_NCLOC, Flag.WITH_NEW_LINES);
measureRepository.addRawMeasure(ROOT_REF, NEW_TECHNICAL_DEBT_KEY, createNewDebtMeasure(200));

@@ -262,7 +254,6 @@ public class NewMaintainabilityMeasuresVisitorTest {

@Test
public void new_debt_ratio_is_0_when_ncloc_measure_is_missing() {
when(ratingSettings.getDevCost(LANGUAGE_1_KEY)).thenReturn(LANGUAGE_1_DEV_COST);
setupOneFileAloneInAProject(50, Flag.SRC_FILE, Flag.MISSING_MEASURE_NCLOC, Flag.WITH_NEW_LINES);
measureRepository.addRawMeasure(ROOT_REF, NEW_TECHNICAL_DEBT_KEY, createNewDebtMeasure(50));

@@ -274,7 +265,6 @@ public class NewMaintainabilityMeasuresVisitorTest {

@Test
public void leaf_components_always_have_a_measure_when_at_least_one_period_exist_and_ratio_is_computed_from_current_level_new_debt() {
when(ratingSettings.getDevCost(LANGUAGE_1_KEY)).thenReturn(LANGUAGE_1_DEV_COST);
Component file = builder(FILE, LANGUAGE_1_FILE_REF).setFileAttributes(new FileAttributes(false, LANGUAGE_1_KEY, 1)).build();
treeRootHolder.setRoot(
builder(PROJECT, ROOT_REF)
@@ -301,7 +291,6 @@ public class NewMaintainabilityMeasuresVisitorTest {

@Test
public void compute_new_maintainability_rating() {
when(ratingSettings.getDevCost(LANGUAGE_1_KEY)).thenReturn(LANGUAGE_1_DEV_COST);
ReportComponent file = builder(FILE, LANGUAGE_1_FILE_REF).setFileAttributes(new FileAttributes(false, LANGUAGE_1_KEY, 1)).build();
treeRootHolder.setRoot(
builder(PROJECT, ROOT_REF)
@@ -332,7 +321,6 @@ public class NewMaintainabilityMeasuresVisitorTest {
public void compute_new_development_cost() {
ReportComponent file1 = builder(FILE, LANGUAGE_1_FILE_REF).setFileAttributes(new FileAttributes(false, LANGUAGE_1_KEY, 4)).build();
ReportComponent file2 = builder(FILE, 22_222).setFileAttributes(new FileAttributes(false, LANGUAGE_1_KEY, 6)).build();
when(ratingSettings.getDevCost(LANGUAGE_1_KEY)).thenReturn(LANGUAGE_1_DEV_COST);
treeRootHolder.setRoot(
builder(PROJECT, ROOT_REF)
.addChildren(
@@ -353,15 +341,14 @@ public class NewMaintainabilityMeasuresVisitorTest {

underTest.visit(treeRootHolder.getRoot());

assertNewDevelopmentCostValues(ROOT_REF, 5 * LANGUAGE_1_DEV_COST);
assertNewDevelopmentCostValues(LANGUAGE_1_FILE_REF, 2 * LANGUAGE_1_DEV_COST);
assertNewDevelopmentCostValues(22_222, 3 * LANGUAGE_1_DEV_COST);
assertNewDevelopmentCostValues(ROOT_REF, 5 * DEV_COST);
assertNewDevelopmentCostValues(LANGUAGE_1_FILE_REF, 2 * DEV_COST);
assertNewDevelopmentCostValues(22_222, 3 * DEV_COST);
}

@Test
public void compute_new_maintainability_rating_to_A_when_no_debt() {
when(newLinesRepository.newLinesAvailable()).thenReturn(true);
when(ratingSettings.getDevCost(LANGUAGE_1_KEY)).thenReturn(LANGUAGE_1_DEV_COST);
treeRootHolder.setRoot(
builder(PROJECT, ROOT_REF)
.addChildren(

+ 2
- 53
server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/qualitymodel/RatingSettingsTest.java View File

@@ -23,23 +23,17 @@ import org.junit.Test;
import org.sonar.api.CoreProperties;
import org.sonar.api.config.PropertyDefinitions;
import org.sonar.api.config.internal.MapSettings;
import org.sonar.api.measures.CoreMetrics;
import org.sonar.api.utils.MessageException;
import org.sonar.api.utils.System2;
import org.sonar.core.config.CorePropertyDefinitions;

import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatThrownBy;
import static org.sonar.api.CoreProperties.DEVELOPMENT_COST;
import static org.sonar.api.CoreProperties.LANGUAGE_SPECIFIC_PARAMETERS;
import static org.sonar.api.CoreProperties.LANGUAGE_SPECIFIC_PARAMETERS_LANGUAGE_KEY;
import static org.sonar.api.CoreProperties.LANGUAGE_SPECIFIC_PARAMETERS_MAN_DAYS_KEY;

public class RatingSettingsTest {

private MapSettings settings = new MapSettings(new PropertyDefinitions(System2.INSTANCE, CorePropertyDefinitions.all()));


@Test
public void load_rating_grid() {
settings.setProperty(CoreProperties.RATING_GRID, "1,3.4,8,50");
@@ -54,31 +48,11 @@ public class RatingSettingsTest {
}

@Test
public void load_work_units_for_language() {
public void load_dev_cost() {
settings.setProperty(DEVELOPMENT_COST, "50");
RatingSettings configurationLoader = new RatingSettings(settings.asConfig());

assertThat(configurationLoader.getDevCost("defaultLanguage")).isEqualTo(50L);
}

@Test
public void load_overridden_values_for_language() {

String aLanguage = "aLanguage";
String anotherLanguage = "anotherLanguage";

settings.setProperty(LANGUAGE_SPECIFIC_PARAMETERS, "0,1");
settings.setProperty(LANGUAGE_SPECIFIC_PARAMETERS + "." + "0" + "." + LANGUAGE_SPECIFIC_PARAMETERS_LANGUAGE_KEY, aLanguage);
settings.setProperty(LANGUAGE_SPECIFIC_PARAMETERS + "." + "0" + "." + LANGUAGE_SPECIFIC_PARAMETERS_MAN_DAYS_KEY, "30");
settings.setProperty(LANGUAGE_SPECIFIC_PARAMETERS + "." + "0" + "." + CoreProperties.LANGUAGE_SPECIFIC_PARAMETERS_SIZE_METRIC_KEY, CoreMetrics.NCLOC_KEY);
settings.setProperty(LANGUAGE_SPECIFIC_PARAMETERS + "." + "1" + "." + LANGUAGE_SPECIFIC_PARAMETERS_LANGUAGE_KEY, anotherLanguage);
settings.setProperty(LANGUAGE_SPECIFIC_PARAMETERS + "." + "1" + "." + LANGUAGE_SPECIFIC_PARAMETERS_MAN_DAYS_KEY, "40");
settings.setProperty(LANGUAGE_SPECIFIC_PARAMETERS + "." + "1" + "." + CoreProperties.LANGUAGE_SPECIFIC_PARAMETERS_SIZE_METRIC_KEY, CoreMetrics.COMPLEXITY_KEY);

RatingSettings configurationLoader = new RatingSettings(settings.asConfig());

assertThat(configurationLoader.getDevCost(aLanguage)).isEqualTo(30L);
assertThat(configurationLoader.getDevCost(anotherLanguage)).isEqualTo(40L);
assertThat(configurationLoader.getDevCost()).isEqualTo(50L);
}

@Test
@@ -91,29 +65,4 @@ public class RatingSettingsTest {

}

@Test
public void use_generic_value_when_specific_setting_is_missing() {
String aLanguage = "aLanguage";

settings.setProperty(DEVELOPMENT_COST, "30");
settings.setProperty(LANGUAGE_SPECIFIC_PARAMETERS, "0");
settings.setProperty(LANGUAGE_SPECIFIC_PARAMETERS + "." + "0" + "." + LANGUAGE_SPECIFIC_PARAMETERS_LANGUAGE_KEY, aLanguage);
settings.setProperty(LANGUAGE_SPECIFIC_PARAMETERS + "." + "0" + "." + LANGUAGE_SPECIFIC_PARAMETERS_MAN_DAYS_KEY, "40");

RatingSettings configurationLoader = new RatingSettings(settings.asConfig());

assertThat(configurationLoader.getDevCost(aLanguage)).isEqualTo(40L);
}

@Test
public void constructor_fails_with_ME_if_language_specific_parameter_language_is_missing() {
settings.setProperty(DEVELOPMENT_COST, "30");
settings.setProperty(LANGUAGE_SPECIFIC_PARAMETERS, "0");
settings.setProperty(LANGUAGE_SPECIFIC_PARAMETERS + "." + "0" + "." + LANGUAGE_SPECIFIC_PARAMETERS_MAN_DAYS_KEY, "40");

assertThatThrownBy(() -> new RatingSettings(settings.asConfig()))
.isInstanceOf(MessageException.class)
.hasMessage("Technical debt configuration is corrupted. At least one language specific parameter has no Language key. " +
"Contact your administrator to update this configuration in the global administration section of SonarQube.");
}
}

+ 86
- 0
server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v105/DeleteLanguageSpecificParametersPropertySetIT.java View File

@@ -0,0 +1,86 @@
/*
* SonarQube
* Copyright (C) 2009-2024 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.v105;

import java.sql.SQLException;
import org.assertj.core.api.Assertions;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.RegisterExtension;
import org.sonar.db.MigrationDbTester;
import org.sonar.server.platform.db.migration.step.DataChange;

class DeleteLanguageSpecificParametersPropertySetIT {

@RegisterExtension
public final MigrationDbTester db = MigrationDbTester.createForMigrationStep(DeleteLanguageSpecificParametersPropertySet.class);
private final DataChange underTest = new DeleteLanguageSpecificParametersPropertySet(db.database());

@Test
void migration_should_remove_root_property_and_children() throws SQLException {
insertLanguageSpecificParametersPropertySet(db);

underTest.execute();

Assertions.assertThat(db.select("select * from properties")).isEmpty();
}

@Test
void migration_is_reentrant() throws SQLException {
insertLanguageSpecificParametersPropertySet(db);

underTest.execute();
underTest.execute();

Assertions.assertThat(db.select("select * from properties")).isEmpty();
}

private void insertLanguageSpecificParametersPropertySet(MigrationDbTester db) {
db.executeInsert("properties ",
"prop_key", "languageSpecificParameters",
"is_empty", false,
"text_value", "0,1",
"created_at", 100_000L,
"uuid", "some-random-uuid1");
db.executeInsert("properties ",
"prop_key", "languageSpecificParameters.0.language",
"is_empty", false,
"text_value", "java",
"created_at", 100_000L,
"uuid", "some-random-uuid2");
db.executeInsert("properties ",
"prop_key", "languageSpecificParameters.0.man_days",
"is_empty", false,
"text_value", "10",
"created_at", 100_000L,
"uuid", "some-random-uuid3");
db.executeInsert("properties ",
"prop_key", "languageSpecificParameters.1.language",
"is_empty", false,
"text_value", "php",
"created_at", 100_000L,
"uuid", "some-random-uuid4");
db.executeInsert("properties ",
"prop_key", "languageSpecificParameters.1.man_days",
"is_empty", false,
"text_value", "20",
"created_at", 100_000L,
"uuid", "some-random-uuid5");
}
}

+ 2
- 1
server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v105/DbVersion105.java View File

@@ -46,6 +46,7 @@ public class DbVersion105 implements DbVersion {
.add(10_5_002, "Drop column 'uuid' from 'issues_impacts' table", DropUuidColumnInIssuesImpactsTable.class)
.add(10_5_003, "Drop column 'uuid' from 'rules_default_impacts' table", DropUuidColumnInRulesDefaultImpactsTable.class)
.add(10_5_004, "Create primary key on 'issues_impacts' table", CreatePrimaryKeyOnIssuesImpactsTable.class)
.add(10_5_005, "Create primary key on 'rules_default_impacts' table", CreatePrimaryKeyOnRulesDefaultImpactsTable.class);
.add(10_5_005, "Create primary key on 'rules_default_impacts' table", CreatePrimaryKeyOnRulesDefaultImpactsTable.class)
.add(10_5_006, "Delete 'languageSpecificParameters' property set from 'properties' table", DeleteLanguageSpecificParametersPropertySet.class);
}
}

+ 39
- 0
server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v105/DeleteLanguageSpecificParametersPropertySet.java View File

@@ -0,0 +1,39 @@
/*
* SonarQube
* Copyright (C) 2009-2024 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.v105;

import java.sql.SQLException;
import org.sonar.db.Database;
import org.sonar.server.platform.db.migration.step.DataChange;

public class DeleteLanguageSpecificParametersPropertySet extends DataChange {

public DeleteLanguageSpecificParametersPropertySet(Database db) {
super(db);
}

@Override
protected void execute(Context context) throws SQLException {
context.prepareUpsert("delete from properties where prop_key like ?")
.setString(1, "languageSpecificParameters%")
.execute()
.commit();
}
}

+ 0
- 26
server/sonar-web/src/main/js/helpers/mocks/definitions-list.ts View File

@@ -2321,32 +2321,6 @@ export const definitions: ExtendedSettingDefinition[] = [
fields: [],
deprecatedKey: 'workUnitsBySizePoint',
},
{
key: 'languageSpecificParameters',
name: 'Language specific parameters',
description:
'DEPRECATED - The parameters specified here for a given language will override the general parameters defined in this section.',
type: SettingType.PROPERTY_SET,
category: 'technicalDebt',
subCategory: 'technicalDebt',
options: [],
fields: [
{
key: 'language',
name: 'Language Key',
description: 'Ex: java, cs, cpp...',
options: [],
},
{
key: 'man_days',
name: 'Development cost',
description: 'If left blank, the generic value defined in this section will be used.',
type: SettingType.FLOAT,
options: [],
},
],
deprecatedKey: 'languageSpecificParameters',
},
{
key: 'sonar.technicalDebt.ratingGrid',
name: 'Maintainability rating grid',

+ 0
- 57
server/sonar-webserver-core/src/main/java/org/sonar/server/platform/db/CheckLanguageSpecificParamsAtStartup.java View File

@@ -1,57 +0,0 @@
/*
* SonarQube
* Copyright (C) 2009-2024 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;

import org.sonar.api.Startable;
import org.sonar.api.config.Configuration;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import static org.sonar.api.CoreProperties.LANGUAGE_SPECIFIC_PARAMETERS;

/**
* Checks if there are any language specific parameters set for calculating technical debt as functionality is deprecated from 9.9.
* If found, it is logged as a warning. This requires to be defined in platform level 4 ({@link org.sonar.server.platform.platformlevel.PlatformLevel4}).
*/
public class CheckLanguageSpecificParamsAtStartup implements Startable {

private static final Logger LOG = LoggerFactory.getLogger(CheckLanguageSpecificParamsAtStartup.class);

private final Configuration config;

public CheckLanguageSpecificParamsAtStartup(Configuration config) {
this.config = config;
}

@Override
public void start() {
String[] languageSpecificParams = config.getStringArray(LANGUAGE_SPECIFIC_PARAMETERS);
if (languageSpecificParams.length > 0) {
LOG.warn("The development cost used for calculating the technical debt is currently configured with {} language specific parameters [Key: languageSpecificParameters]. " +
"Please be aware that this functionality is deprecated, and will be removed in a future version.", languageSpecificParams.length);
}
}

@Override
public void stop() {
// do nothing
}

}

+ 0
- 81
server/sonar-webserver-core/src/test/java/org/sonar/server/platform/db/CheckLanguageSpecificParamsAtStartupTest.java View File

@@ -1,81 +0,0 @@
/*
* SonarQube
* Copyright (C) 2009-2024 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;

import org.junit.After;
import org.junit.ClassRule;
import org.junit.Rule;
import org.junit.Test;
import org.slf4j.event.Level;
import org.sonar.api.CoreProperties;
import org.sonar.api.config.internal.MapSettings;
import org.sonar.api.measures.CoreMetrics;
import org.sonar.api.testfixtures.log.LogTester;
import org.sonar.api.utils.System2;
import org.sonar.api.utils.log.LoggerLevel;
import org.sonar.db.DbTester;

import static org.assertj.core.api.Assertions.assertThat;
import static org.sonar.api.CoreProperties.LANGUAGE_SPECIFIC_PARAMETERS;
import static org.sonar.api.CoreProperties.LANGUAGE_SPECIFIC_PARAMETERS_LANGUAGE_KEY;
import static org.sonar.api.CoreProperties.LANGUAGE_SPECIFIC_PARAMETERS_MAN_DAYS_KEY;

public class CheckLanguageSpecificParamsAtStartupTest {

@ClassRule
public static LogTester logTester = new LogTester().setLevel(LoggerLevel.WARN);
@Rule
public final DbTester dbTester = DbTester.create(System2.INSTANCE);
private final MapSettings settings = new MapSettings();
private final CheckLanguageSpecificParamsAtStartup underTest = new CheckLanguageSpecificParamsAtStartup(settings.asConfig());

@After
public void tearDown() {
logTester.clear();
underTest.stop();
}

@Test
public void log_shows_when_language_specific_params_used() {
String aLanguage = "aLanguage";
String anotherLanguage = "anotherLanguage";
settings.setProperty(LANGUAGE_SPECIFIC_PARAMETERS, "0,1");
settings.setProperty(LANGUAGE_SPECIFIC_PARAMETERS + "." + "0" + "." + LANGUAGE_SPECIFIC_PARAMETERS_LANGUAGE_KEY, aLanguage);
settings.setProperty(LANGUAGE_SPECIFIC_PARAMETERS + "." + "0" + "." + LANGUAGE_SPECIFIC_PARAMETERS_MAN_DAYS_KEY, "30");
settings.setProperty(LANGUAGE_SPECIFIC_PARAMETERS + "." + "0" + "." + CoreProperties.LANGUAGE_SPECIFIC_PARAMETERS_SIZE_METRIC_KEY, CoreMetrics.NCLOC_KEY);
settings.setProperty(LANGUAGE_SPECIFIC_PARAMETERS + "." + "1" + "." + LANGUAGE_SPECIFIC_PARAMETERS_LANGUAGE_KEY, anotherLanguage);
settings.setProperty(LANGUAGE_SPECIFIC_PARAMETERS + "." + "1" + "." + LANGUAGE_SPECIFIC_PARAMETERS_MAN_DAYS_KEY, "40");
settings.setProperty(LANGUAGE_SPECIFIC_PARAMETERS + "." + "1" + "." + CoreProperties.LANGUAGE_SPECIFIC_PARAMETERS_SIZE_METRIC_KEY, CoreMetrics.COMPLEXITY_KEY);

underTest.start();
assertThat(logTester.logs(Level.WARN))
.contains("The development cost used for calculating the technical debt is currently configured with 2 language specific parameters [Key: languageSpecificParameters]. " +
"Please be aware that this functionality is deprecated, and will be removed in a future version.");
}

@Test
public void log_does_not_show_when_language_specific_params_used() {
underTest.start();
boolean noneMatch = logTester.logs(Level.WARN).stream()
.noneMatch(s -> s.startsWith("The development cost used for calculating the technical debt is currently configured with"));
assertThat(noneMatch).isTrue();
}

}

+ 0
- 2
server/sonar-webserver/src/main/java/org/sonar/server/platform/platformlevel/PlatformLevel4.java View File

@@ -179,7 +179,6 @@ import org.sonar.server.platform.PersistentSettings;
import org.sonar.server.platform.SystemInfoWriterModule;
import org.sonar.server.platform.WebCoreExtensionsInstaller;
import org.sonar.server.platform.db.CheckAnyonePermissionsAtStartup;
import org.sonar.server.platform.db.CheckLanguageSpecificParamsAtStartup;
import org.sonar.server.platform.web.ActionDeprecationLoggerInterceptor;
import org.sonar.server.platform.web.SonarLintConnectionFilter;
import org.sonar.server.platform.web.WebServiceFilter;
@@ -435,7 +434,6 @@ public class PlatformLevel4 extends PlatformLevel {
UserPermissionChanger.class,
GroupPermissionChanger.class,
CheckAnyonePermissionsAtStartup.class,
CheckLanguageSpecificParamsAtStartup.class,
VisibilityService.class,

// components

+ 2
- 20
sonar-core/src/main/java/org/sonar/core/config/DebtProperties.java View File

@@ -34,7 +34,7 @@ class DebtProperties {
static List<PropertyDefinition> all() {
return List.of(
PropertyDefinition.builder(CoreProperties.DEVELOPMENT_COST)
.defaultValue("" + CoreProperties.DEVELOPMENT_COST_DEF_VALUE)
.defaultValue(CoreProperties.DEVELOPMENT_COST_DEF_VALUE)
.name("Development cost")
.description("Cost to develop one line of code (LOC). Example: if the cost to develop 1 LOC has been estimated " +
"at 30 minutes, then the value of this property would be 30.")
@@ -43,7 +43,7 @@ class DebtProperties {
.build(),

PropertyDefinition.builder(CoreProperties.RATING_GRID)
.defaultValue("" + CoreProperties.RATING_GRID_DEF_VALUES)
.defaultValue(CoreProperties.RATING_GRID_DEF_VALUES)
.name("Maintainability rating grid")
.description("Maintainability ratings range from A (very good) to E (very bad). The rating is determined by the value of " +
"the Technical Debt Ratio, which compares the technical debt on a project to the cost it would take to rewrite " +
@@ -52,24 +52,6 @@ class DebtProperties {
"2,500 LOC will have a technical debt ratio of 24000/(30 * 2,500) = 0.32. That yields a maintainability rating of D.")
.category(CoreProperties.CATEGORY_TECHNICAL_DEBT)
.deprecatedKey("ratingGrid")
.build(),

PropertyDefinition.builder(CoreProperties.LANGUAGE_SPECIFIC_PARAMETERS)
.name("Language specific parameters")
.description("DEPRECATED - The parameters specified here for a given language will override the general parameters defined in this section.")
.category(CoreProperties.CATEGORY_TECHNICAL_DEBT)
.deprecatedKey("languageSpecificParameters")
.fields(
PropertyFieldDefinition.build(CoreProperties.LANGUAGE_SPECIFIC_PARAMETERS_LANGUAGE_KEY)
.name("Language Key")
.description("Ex: java, cs, cpp...")
.type(PropertyType.STRING)
.build(),
PropertyFieldDefinition.build(CoreProperties.LANGUAGE_SPECIFIC_PARAMETERS_MAN_DAYS_KEY)
.name("Development cost")
.description("If left blank, the generic value defined in this section will be used.")
.type(PropertyType.FLOAT)
.build())
.build());
}
}

+ 1
- 10
sonar-ws/src/testFixtures/java/org/sonarqube/ws/tester/QModelTester.java View File

@@ -26,9 +26,6 @@ public class QModelTester {

private static final String DEV_COST_PROPERTY = "sonar.technicalDebt.developmentCost";
private static final String RATING_GRID_PROPERTY = "sonar.technicalDebt.ratingGrid";
private static final String DEV_COST_LANGUAGE_PROPERTY = "languageSpecificParameters";
private static final String DEV_COST_LANGUAGE_NAME_PROPERTY = DEV_COST_LANGUAGE_PROPERTY + ".0.language";
private static final String DEV_COST_LANGUAGE_COST_PROPERTY = DEV_COST_LANGUAGE_PROPERTY + ".0.man_days";
private static final Joiner COMMA_JOINER = Joiner.on(",");

private final TesterSession session;
@@ -41,18 +38,12 @@ public class QModelTester {
session.settings().setGlobalSettings(DEV_COST_PROPERTY, Integer.toString(developmentCost));
}

public void updateLanguageDevelopmentCost(String language, int developmentCost) {
session.settings().setGlobalSettings(DEV_COST_LANGUAGE_PROPERTY, "0");
session.settings().setGlobalSettings(DEV_COST_LANGUAGE_NAME_PROPERTY, language);
session.settings().setGlobalSettings(DEV_COST_LANGUAGE_COST_PROPERTY, Integer.toString(developmentCost));
}

public void updateRatingGrid(Double... ratingGrid) {
Preconditions.checkState(ratingGrid.length == 4, "Rating grid must contains 4 values");
session.settings().setGlobalSettings(RATING_GRID_PROPERTY, COMMA_JOINER.join(ratingGrid));
}

public void reset() {
session.settings().resetSettings(DEV_COST_LANGUAGE_PROPERTY, DEV_COST_LANGUAGE_NAME_PROPERTY, DEV_COST_LANGUAGE_COST_PROPERTY, RATING_GRID_PROPERTY, DEV_COST_PROPERTY);
session.settings().resetSettings(RATING_GRID_PROPERTY, DEV_COST_PROPERTY);
}
}

Loading…
Cancel
Save