private File baseDir; | private File baseDir; | ||||
private File workDir; | private File workDir; | ||||
private File buildDir; | |||||
private Map<String, String> properties = new LinkedHashMap<>(); | private Map<String, String> properties = new LinkedHashMap<>(); | ||||
private ProjectDefinition parent = null; | private ProjectDefinition parent = null; | ||||
private List<ProjectDefinition> subProjects = new ArrayList<>(); | private List<ProjectDefinition> subProjects = new ArrayList<>(); | ||||
return workDir; | return workDir; | ||||
} | } | ||||
/** | |||||
* @deprecated since 6.1 notion of buildDir is not well defined | |||||
*/ | |||||
@Deprecated | |||||
public ProjectDefinition setBuildDir(File d) { | |||||
this.buildDir = d; | |||||
return this; | |||||
} | |||||
/** | |||||
* @deprecated since 6.1 notion of buildDir is not well defined | |||||
*/ | |||||
@Deprecated | |||||
public File getBuildDir() { | |||||
return buildDir; | |||||
} | |||||
/** | |||||
* @deprecated since 5.0 use {@link #properties()} | |||||
*/ | |||||
@Deprecated | |||||
public Properties getProperties() { | |||||
Properties result = new Properties(); | |||||
for (Map.Entry<String, String> entry : properties.entrySet()) { | |||||
result.setProperty(entry.getKey(), entry.getValue()); | |||||
} | |||||
return result; | |||||
} | |||||
public Map<String, String> properties() { | public Map<String, String> properties() { | ||||
return properties; | return properties; | ||||
} | } | ||||
/** | |||||
* Copies specified properties into this object. | |||||
* | |||||
* @since 2.12 | |||||
* @deprecated since 5.0 use {@link #setProperties(Map)} | |||||
*/ | |||||
@Deprecated | |||||
public ProjectDefinition setProperties(Properties properties) { | |||||
for (Entry<Object, Object> entry : properties.entrySet()) { | |||||
this.properties.put(entry.getKey().toString(), entry.getValue().toString()); | |||||
} | |||||
return this; | |||||
} | |||||
public ProjectDefinition setProperties(Map<String, String> properties) { | public ProjectDefinition setProperties(Map<String, String> properties) { | ||||
this.properties.putAll(properties); | this.properties.putAll(properties); | ||||
return this; | return this; |
*/ | */ | ||||
package org.sonar.api.batch.bootstrap; | package org.sonar.api.batch.bootstrap; | ||||
import java.util.Properties; | |||||
import java.util.HashMap; | |||||
import java.util.Map; | |||||
import org.junit.Test; | import org.junit.Test; | ||||
import org.sonar.api.CoreProperties; | import org.sonar.api.CoreProperties; | ||||
@Test | @Test | ||||
public void shouldGetKeyFromProperties() { | public void shouldGetKeyFromProperties() { | ||||
Properties props = new Properties(); | |||||
props.setProperty(CoreProperties.PROJECT_KEY_PROPERTY, "foo"); | |||||
Map<String, String> props = new HashMap<>(); | |||||
props.put(CoreProperties.PROJECT_KEY_PROPERTY, "foo"); | |||||
ProjectDefinition def = ProjectDefinition.create(); | ProjectDefinition def = ProjectDefinition.create(); | ||||
def.setProperties(props); | def.setProperties(props); | ||||
assertThat(def.getKey()).isEqualTo("foo"); | assertThat(def.getKey()).isEqualTo("foo"); |
import java.util.HashMap; | import java.util.HashMap; | ||||
import java.util.Map; | import java.util.Map; | ||||
import javax.annotation.CheckForNull; | |||||
import javax.annotation.Nullable; | import javax.annotation.Nullable; | ||||
import org.apache.commons.lang.StringUtils; | import org.apache.commons.lang.StringUtils; | ||||
public final class LoggingConfiguration { | public final class LoggingConfiguration { | ||||
public static final String PROPERTY_ROOT_LOGGER_LEVEL = "ROOT_LOGGER_LEVEL"; | public static final String PROPERTY_ROOT_LOGGER_LEVEL = "ROOT_LOGGER_LEVEL"; | ||||
/** | |||||
* @deprecated since 5.2 there is no more db access from scanner side | |||||
*/ | |||||
@Deprecated | |||||
public static final String PROPERTY_SQL_LOGGER_LEVEL = "SQL_LOGGER_LEVEL"; | |||||
public static final String PROPERTY_FORMAT = "FORMAT"; | public static final String PROPERTY_FORMAT = "FORMAT"; | ||||
public static final String LEVEL_ROOT_VERBOSE = "DEBUG"; | public static final String LEVEL_ROOT_VERBOSE = "DEBUG"; | ||||
return setVerbose(verbose); | return setVerbose(verbose); | ||||
} | } | ||||
@CheckForNull | |||||
private static String getFallback(String key, Map<String, String> properties, @Nullable Map<String, String> fallback) { | |||||
if (properties.containsKey(key)) { | |||||
return properties.get(key); | |||||
} | |||||
if (fallback != null) { | |||||
return fallback.get(key); | |||||
} | |||||
return null; | |||||
} | |||||
public LoggingConfiguration setRootLevel(String level) { | public LoggingConfiguration setRootLevel(String level) { | ||||
return addSubstitutionVariable(PROPERTY_ROOT_LOGGER_LEVEL, level); | return addSubstitutionVariable(PROPERTY_ROOT_LOGGER_LEVEL, level); | ||||
} | } | ||||
return addSubstitutionVariable(PROPERTY_FORMAT, StringUtils.defaultIfBlank(format, FORMAT_DEFAULT)); | return addSubstitutionVariable(PROPERTY_FORMAT, StringUtils.defaultIfBlank(format, FORMAT_DEFAULT)); | ||||
} | } | ||||
public LoggingConfiguration addSubstitutionVariable(String key, String value) { | |||||
private LoggingConfiguration addSubstitutionVariable(String key, String value) { | |||||
substitutionVariables.put(key, value); | substitutionVariables.put(key, value); | ||||
return this; | return this; | ||||
} | } |
import java.util.List; | import java.util.List; | ||||
import java.util.Set; | import java.util.Set; | ||||
import java.util.stream.Collectors; | import java.util.stream.Collectors; | ||||
import org.sonar.api.batch.sensor.Sensor; | |||||
import org.sonar.api.batch.sensor.SensorContext; | import org.sonar.api.batch.sensor.SensorContext; | ||||
import org.sonar.api.batch.sensor.SensorDescriptor; | import org.sonar.api.batch.sensor.SensorDescriptor; | ||||
import org.sonar.api.config.PropertyDefinition; | import org.sonar.api.config.PropertyDefinition; | ||||
import org.sonar.api.resources.Qualifiers; | import org.sonar.api.resources.Qualifiers; | ||||
import org.sonar.api.scanner.sensor.ProjectSensor; | |||||
import org.sonar.api.utils.log.Logger; | import org.sonar.api.utils.log.Logger; | ||||
import org.sonar.api.utils.log.Loggers; | import org.sonar.api.utils.log.Loggers; | ||||
import org.sonar.scanner.config.DefaultConfiguration; | import org.sonar.scanner.config.DefaultConfiguration; | ||||
import static java.util.Arrays.asList; | |||||
import static org.sonar.api.CoreProperties.CATEGORY_CODE_COVERAGE; | import static org.sonar.api.CoreProperties.CATEGORY_CODE_COVERAGE; | ||||
public class GenericCoverageSensor implements Sensor { | |||||
public class GenericCoverageSensor implements ProjectSensor { | |||||
private static final Logger LOG = Loggers.get(GenericCoverageSensor.class); | private static final Logger LOG = Loggers.get(GenericCoverageSensor.class); | ||||
static final String REPORT_PATHS_PROPERTY_KEY = "sonar.coverageReportPaths"; | static final String REPORT_PATHS_PROPERTY_KEY = "sonar.coverageReportPaths"; | ||||
/** | |||||
* @deprecated since 6.2 | |||||
*/ | |||||
@Deprecated | |||||
static final String OLD_REPORT_PATH_PROPERTY_KEY = "sonar.genericcoverage.reportPath"; | |||||
/** | |||||
* @deprecated since 6.2 | |||||
*/ | |||||
@Deprecated | |||||
static final String OLD_COVERAGE_REPORT_PATHS_PROPERTY_KEY = "sonar.genericcoverage.reportPaths"; | |||||
/** | |||||
* @deprecated since 6.2 | |||||
*/ | |||||
@Deprecated | |||||
static final String OLD_IT_COVERAGE_REPORT_PATHS_PROPERTY_KEY = "sonar.genericcoverage.itReportPaths"; | |||||
/** | |||||
* @deprecated since 6.2 | |||||
*/ | |||||
@Deprecated | |||||
static final String OLD_OVERALL_COVERAGE_REPORT_PATHS_PROPERTY_KEY = "sonar.genericcoverage.overallReportPaths"; | |||||
private final DefaultConfiguration config; | private final DefaultConfiguration config; | ||||
public GenericCoverageSensor(DefaultConfiguration config) { | public GenericCoverageSensor(DefaultConfiguration config) { | ||||
.category(CATEGORY_CODE_COVERAGE) | .category(CATEGORY_CODE_COVERAGE) | ||||
.onQualifiers(Qualifiers.PROJECT) | .onQualifiers(Qualifiers.PROJECT) | ||||
.multiValues(true) | .multiValues(true) | ||||
.deprecatedKey(OLD_COVERAGE_REPORT_PATHS_PROPERTY_KEY) | |||||
.build()); | .build()); | ||||
} | } | ||||
@Override | @Override | ||||
public void describe(SensorDescriptor descriptor) { | public void describe(SensorDescriptor descriptor) { | ||||
descriptor.name("Generic Coverage Report") | descriptor.name("Generic Coverage Report") | ||||
.global() | |||||
.onlyWhenConfiguration(c -> asList(REPORT_PATHS_PROPERTY_KEY, OLD_REPORT_PATH_PROPERTY_KEY, OLD_COVERAGE_REPORT_PATHS_PROPERTY_KEY, | |||||
OLD_IT_COVERAGE_REPORT_PATHS_PROPERTY_KEY, OLD_OVERALL_COVERAGE_REPORT_PATHS_PROPERTY_KEY) | |||||
.stream() | |||||
.anyMatch(c::hasKey)); | |||||
.onlyWhenConfiguration(c -> c.hasKey(REPORT_PATHS_PROPERTY_KEY)); | |||||
} | } | ||||
@Override | @Override | ||||
} | } | ||||
Set<String> loadReportPaths() { | Set<String> loadReportPaths() { | ||||
Set<String> reportPaths = new LinkedHashSet<>(); | |||||
reportPaths.addAll(Arrays.asList(config.getStringArray(REPORT_PATHS_PROPERTY_KEY))); | |||||
loadDeprecated(reportPaths, OLD_REPORT_PATH_PROPERTY_KEY); | |||||
loadArrayDeprecated(reportPaths, OLD_COVERAGE_REPORT_PATHS_PROPERTY_KEY); | |||||
loadArrayDeprecated(reportPaths, OLD_IT_COVERAGE_REPORT_PATHS_PROPERTY_KEY); | |||||
loadArrayDeprecated(reportPaths, OLD_OVERALL_COVERAGE_REPORT_PATHS_PROPERTY_KEY); | |||||
return reportPaths; | |||||
return new LinkedHashSet<>(Arrays.asList(config.getStringArray(REPORT_PATHS_PROPERTY_KEY))); | |||||
} | } | ||||
} | } |
import java.util.Map.Entry; | import java.util.Map.Entry; | ||||
import java.util.Objects; | import java.util.Objects; | ||||
import java.util.stream.Stream; | import java.util.stream.Stream; | ||||
import javax.annotation.CheckForNull; | |||||
import javax.annotation.Nullable; | import javax.annotation.Nullable; | ||||
import org.apache.commons.lang.ArrayUtils; | import org.apache.commons.lang.ArrayUtils; | ||||
import org.apache.commons.lang.StringUtils; | import org.apache.commons.lang.StringUtils; | ||||
private static final String MODULE_KEY_PROPERTY = "sonar.moduleKey"; | private static final String MODULE_KEY_PROPERTY = "sonar.moduleKey"; | ||||
protected static final String PROPERTY_PROJECT_BASEDIR = "sonar.projectBaseDir"; | protected static final String PROPERTY_PROJECT_BASEDIR = "sonar.projectBaseDir"; | ||||
/** | |||||
* @deprecated since 6.1 notion of buildDir is not well defined | |||||
*/ | |||||
@Deprecated | |||||
private static final String PROPERTY_PROJECT_BUILDDIR = "sonar.projectBuildDir"; | |||||
private static final String PROPERTY_MODULES = "sonar.modules"; | private static final String PROPERTY_MODULES = "sonar.modules"; | ||||
/** | /** | ||||
return ProjectDefinition.create().setProperties(moduleProperties) | return ProjectDefinition.create().setProperties(moduleProperties) | ||||
.setBaseDir(baseDir) | .setBaseDir(baseDir) | ||||
.setWorkDir(workDir) | |||||
.setBuildDir(initModuleBuildDir(baseDir, moduleProperties)); | |||||
.setWorkDir(workDir); | |||||
} | } | ||||
private void checkUnsupportedIssueExclusions(Map<String, String> moduleProperties, Map<String, String> parentProps) { | private void checkUnsupportedIssueExclusions(Map<String, String> moduleProperties, Map<String, String> parentProps) { | ||||
return new File(moduleBaseDir, customWorkDir.getPath()); | return new File(moduleBaseDir, customWorkDir.getPath()); | ||||
} | } | ||||
@CheckForNull | |||||
private static File initModuleBuildDir(File moduleBaseDir, Map<String, String> moduleProperties) { | |||||
String buildDir = moduleProperties.get(PROPERTY_PROJECT_BUILDDIR); | |||||
if (StringUtils.isBlank(buildDir)) { | |||||
return null; | |||||
} | |||||
File customBuildDir = new File(buildDir); | |||||
if (customBuildDir.isAbsolute()) { | |||||
return customBuildDir; | |||||
} | |||||
return new File(moduleBaseDir, customBuildDir.getPath()); | |||||
} | |||||
private void defineChildren(ProjectDefinition parentProject, Map<String, Map<String, String>> propertiesByModuleIdPath, String parentModuleIdPath) { | private void defineChildren(ProjectDefinition parentProject, Map<String, Map<String, String>> propertiesByModuleIdPath, String parentModuleIdPath) { | ||||
Map<String, String> parentProps = parentProject.properties(); | Map<String, String> parentProps = parentProject.properties(); | ||||
if (parentProps.containsKey(PROPERTY_MODULES)) { | if (parentProps.containsKey(PROPERTY_MODULES)) { |
import org.sonar.api.config.Encryption; | import org.sonar.api.config.Encryption; | ||||
import org.sonar.api.config.PropertyDefinitions; | import org.sonar.api.config.PropertyDefinitions; | ||||
import org.sonar.api.utils.log.LogTester; | import org.sonar.api.utils.log.LogTester; | ||||
import org.sonar.api.utils.log.LoggerLevel; | |||||
import org.sonar.scanner.config.DefaultConfiguration; | import org.sonar.scanner.config.DefaultConfiguration; | ||||
import org.sonar.scanner.scan.ProjectConfiguration; | import org.sonar.scanner.scan.ProjectConfiguration; | ||||
public LogTester logTester = new LogTester(); | public LogTester logTester = new LogTester(); | ||||
@Test | @Test | ||||
public void migrateOldProperties() { | |||||
public void loadAllReportPaths() { | |||||
Map<String, String> settings = new HashMap<>(); | Map<String, String> settings = new HashMap<>(); | ||||
settings.put(GenericCoverageSensor.OLD_REPORT_PATH_PROPERTY_KEY, "old.xml"); | |||||
settings.put(GenericCoverageSensor.OLD_COVERAGE_REPORT_PATHS_PROPERTY_KEY, "old1.xml,old2.xml"); | |||||
settings.put(GenericCoverageSensor.OLD_IT_COVERAGE_REPORT_PATHS_PROPERTY_KEY, "old3.xml,old4.xml,old.xml"); | |||||
settings.put(GenericCoverageSensor.OLD_OVERALL_COVERAGE_REPORT_PATHS_PROPERTY_KEY, "old5.xml,old6.xml"); | |||||
settings.put(GenericCoverageSensor.REPORT_PATHS_PROPERTY_KEY, "report.xml,report2.xml"); | |||||
PropertyDefinitions defs = new PropertyDefinitions(GenericCoverageSensor.properties()); | PropertyDefinitions defs = new PropertyDefinitions(GenericCoverageSensor.properties()); | ||||
DefaultConfiguration config = new ProjectConfiguration(defs, new Encryption(null), settings); | DefaultConfiguration config = new ProjectConfiguration(defs, new Encryption(null), settings); | ||||
Set<String> reportPaths = new GenericCoverageSensor(config).loadReportPaths(); | Set<String> reportPaths = new GenericCoverageSensor(config).loadReportPaths(); | ||||
assertThat(logTester.logs(LoggerLevel.WARN)).contains( | |||||
"Property 'sonar.genericcoverage.reportPath' is deprecated. Please use 'sonar.coverageReportPaths' instead.", | |||||
"Property 'sonar.genericcoverage.reportPaths' is deprecated. Please use 'sonar.coverageReportPaths' instead.", | |||||
"Property 'sonar.genericcoverage.itReportPaths' is deprecated. Please use 'sonar.coverageReportPaths' instead.", | |||||
"Property 'sonar.genericcoverage.overallReportPaths' is deprecated. Please use 'sonar.coverageReportPaths' instead."); | |||||
assertThat(reportPaths).containsOnly( | |||||
"old.xml", "old1.xml", "old2.xml", "old3.xml", "old4.xml", "old5.xml", "old6.xml"); | |||||
assertThat(reportPaths).containsOnly("report.xml", "report2.xml"); | |||||
} | } | ||||
} | } |
assertThat(logs).noneMatch(l -> l.contains("Please use 'sonar.coverageReportPaths'")); | assertThat(logs).noneMatch(l -> l.contains("Please use 'sonar.coverageReportPaths'")); | ||||
} | } | ||||
@Test | |||||
public void warnAboutDeprecatedProperty() { | |||||
File projectDir = new File("test-resources/mediumtest/xoo/sample-generic-coverage"); | |||||
tester | |||||
.setLogOutput((msg, level) -> logs.add(msg)) | |||||
.newAnalysis(new File(projectDir, "sonar-project.properties")) | |||||
.property("sonar.genericcoverage.reportPath", "coverage.xml") | |||||
.execute(); | |||||
assertThat(logs).anyMatch(l -> l.contains("Please use 'sonar.coverageReportPaths'")); | |||||
} | |||||
@Test | @Test | ||||
public void twoReports() throws IOException { | public void twoReports() throws IOException { |
assertThat(ProjectReactorBuilder.getListFromProperty(props, "prop")).containsOnly("foo", "bar", "toto", "tutu"); | assertThat(ProjectReactorBuilder.getListFromProperty(props, "prop")).containsOnly("foo", "bar", "toto", "tutu"); | ||||
} | } | ||||
@Test | |||||
public void shouldDefineProjectWithBuildDir() { | |||||
ProjectDefinition rootProject = loadProjectDefinition("simple-project-with-build-dir"); | |||||
File buildDir = rootProject.getBuildDir(); | |||||
assertThat(buildDir).isDirectory().exists(); | |||||
assertThat(new File(buildDir, "report.txt")).isFile().exists(); | |||||
assertThat(buildDir.getName()).isEqualTo("build"); | |||||
} | |||||
@Test | @Test | ||||
public void doNotMixPropertiesWhenModuleKeyIsPrefixOfAnother() throws IOException { | public void doNotMixPropertiesWhenModuleKeyIsPrefixOfAnother() throws IOException { | ||||
ProjectDefinition rootProject = loadProjectDefinition("multi-module-definitions-same-prefix"); | ProjectDefinition rootProject = loadProjectDefinition("multi-module-definitions-same-prefix"); |