@@ -28,10 +28,8 @@ import org.sonar.scanner.config.DefaultConfiguration; | |||
@Immutable | |||
public class GlobalConfiguration extends DefaultConfiguration { | |||
public GlobalConfiguration(PropertyDefinitions propertyDefinitions, Encryption encryption, GlobalAnalysisMode mode, | |||
Map<String, String> settings) { | |||
super(propertyDefinitions, encryption, mode, settings); | |||
public GlobalConfiguration(PropertyDefinitions propertyDefinitions, Encryption encryption, Map<String, String> settings) { | |||
super(propertyDefinitions, encryption, settings); | |||
} | |||
} |
@@ -28,13 +28,13 @@ public class GlobalConfigurationProvider extends ProviderAdapter { | |||
private GlobalConfiguration globalConfig; | |||
public GlobalConfiguration provide(GlobalServerSettings globalServerSettings, ScannerProperties scannerProps, PropertyDefinitions propertyDefinitions, GlobalAnalysisMode mode) { | |||
public GlobalConfiguration provide(GlobalServerSettings globalServerSettings, ScannerProperties scannerProps, PropertyDefinitions propertyDefinitions) { | |||
if (globalConfig == null) { | |||
Map<String, String> mergedSettings = new LinkedHashMap<>(); | |||
mergedSettings.putAll(globalServerSettings.properties()); | |||
mergedSettings.putAll(scannerProps.properties()); | |||
globalConfig = new GlobalConfiguration(propertyDefinitions, scannerProps.getEncryption(), mode, mergedSettings); | |||
globalConfig = new GlobalConfiguration(propertyDefinitions, scannerProps.getEncryption(), mergedSettings); | |||
} | |||
return globalConfig; | |||
} |
@@ -35,7 +35,7 @@ public class GlobalServerSettingsProvider extends ProviderAdapter { | |||
public GlobalServerSettings provide(SettingsLoader loader) { | |||
if (singleton == null) { | |||
Map<String, String> serverSideSettings = loader.load(null); | |||
Map<String, String> serverSideSettings = loader.loadGlobalSettings(); | |||
singleton = new GlobalServerSettings(serverSideSettings); | |||
Optional.ofNullable(serverSideSettings.get(CoreProperties.SERVER_ID)).ifPresent(v -> LOG.info("Server id: {}", v)); | |||
} |
@@ -29,10 +29,8 @@ import org.sonar.api.config.Configuration; | |||
import org.sonar.api.config.Encryption; | |||
import org.sonar.api.config.PropertyDefinition; | |||
import org.sonar.api.config.PropertyDefinitions; | |||
import org.sonar.api.utils.MessageException; | |||
import org.sonar.api.utils.log.Logger; | |||
import org.sonar.api.utils.log.Loggers; | |||
import org.sonar.scanner.bootstrap.GlobalAnalysisMode; | |||
import static java.util.Objects.requireNonNull; | |||
import static org.apache.commons.lang.StringUtils.trim; | |||
@@ -45,14 +43,12 @@ public abstract class DefaultConfiguration implements Configuration { | |||
private final PropertyDefinitions definitions; | |||
private final Encryption encryption; | |||
private final GlobalAnalysisMode mode; | |||
private final Map<String, String> properties; | |||
private final Map<String, String> originalProperties; | |||
public DefaultConfiguration(PropertyDefinitions propertyDefinitions, Encryption encryption, GlobalAnalysisMode mode, Map<String, String> props) { | |||
public DefaultConfiguration(PropertyDefinitions propertyDefinitions, Encryption encryption, Map<String, String> props) { | |||
this.definitions = requireNonNull(propertyDefinitions); | |||
this.encryption = encryption; | |||
this.mode = mode; | |||
this.properties = unmodifiableMapWithTrimmedValues(definitions, props); | |||
this.originalProperties = Collections.unmodifiableMap(props); | |||
} | |||
@@ -66,10 +62,6 @@ public abstract class DefaultConfiguration implements Configuration { | |||
return Collections.unmodifiableMap(map); | |||
} | |||
public GlobalAnalysisMode getMode() { | |||
return mode; | |||
} | |||
public Encryption getEncryption() { | |||
return encryption; | |||
} | |||
@@ -119,10 +111,6 @@ public abstract class DefaultConfiguration implements Configuration { | |||
} | |||
private Optional<String> getInternal(String key) { | |||
if (mode.isIssues() && key.endsWith(".secured") && !key.contains(".license")) { | |||
throw MessageException.of("Access to the secured property '" + key | |||
+ "' is not possible in issues mode. The SonarQube plugin which requires this property must be deactivated in issues mode."); | |||
} | |||
Optional<String> value = Optional.ofNullable(properties.get(key)); | |||
if (!value.isPresent()) { | |||
// default values cannot be encrypted, so return value as-is. |
@@ -34,6 +34,7 @@ import org.apache.commons.lang.StringEscapeUtils; | |||
import org.sonar.api.utils.log.Logger; | |||
import org.sonar.api.utils.log.Loggers; | |||
import org.sonar.api.utils.log.Profiler; | |||
import org.sonar.scanner.bootstrap.ScannerProperties; | |||
import org.sonar.scanner.bootstrap.ScannerWsClient; | |||
import org.sonar.scanner.util.ScannerUtils; | |||
import org.sonarqube.ws.Settings.FieldValues.Value; | |||
@@ -45,14 +46,25 @@ import org.sonarqube.ws.client.HttpException; | |||
public class DefaultSettingsLoader implements SettingsLoader { | |||
private ScannerWsClient wsClient; | |||
private final ScannerProperties scannerProperties; | |||
private static final Logger LOG = Loggers.get(DefaultSettingsLoader.class); | |||
public DefaultSettingsLoader(ScannerWsClient wsClient) { | |||
public DefaultSettingsLoader(ScannerWsClient wsClient, ScannerProperties scannerProperties) { | |||
this.wsClient = wsClient; | |||
this.scannerProperties = scannerProperties; | |||
} | |||
@Override | |||
public Map<String, String> load(@Nullable String componentKey) { | |||
public Map<String, String> loadGlobalSettings() { | |||
return load(null); | |||
} | |||
@Override | |||
public Map<String, String> loadProjectSettings() { | |||
return load(scannerProperties.getKeyWithBranch()); | |||
} | |||
private Map<String, String> load(@Nullable String componentKey) { | |||
String url = "api/settings/values.protobuf"; | |||
Profiler profiler = Profiler.create(LOG); | |||
if (componentKey != null) { |
@@ -20,9 +20,9 @@ | |||
package org.sonar.scanner.repository.settings; | |||
import java.util.Map; | |||
import javax.annotation.Nullable; | |||
@FunctionalInterface | |||
public interface SettingsLoader { | |||
Map<String, String> load(@Nullable String componentKey); | |||
Map<String, String> loadGlobalSettings(); | |||
Map<String, String> loadProjectSettings(); | |||
} |
@@ -22,13 +22,12 @@ package org.sonar.scanner.scan; | |||
import java.util.Map; | |||
import org.sonar.api.config.Encryption; | |||
import org.sonar.api.config.PropertyDefinitions; | |||
import org.sonar.scanner.bootstrap.GlobalAnalysisMode; | |||
import org.sonar.scanner.config.DefaultConfiguration; | |||
public class ModuleConfiguration extends DefaultConfiguration { | |||
public ModuleConfiguration(PropertyDefinitions propertyDefinitions, Encryption encryption, GlobalAnalysisMode mode, Map<String, String> props) { | |||
super(propertyDefinitions, encryption, mode, props); | |||
public ModuleConfiguration(PropertyDefinitions propertyDefinitions, Encryption encryption, Map<String, String> props) { | |||
super(propertyDefinitions, encryption, props); | |||
} | |||
} |
@@ -26,20 +26,19 @@ import java.util.Map; | |||
import org.picocontainer.injectors.ProviderAdapter; | |||
import org.sonar.api.batch.bootstrap.ProjectDefinition; | |||
import org.sonar.api.batch.fs.internal.DefaultInputModule; | |||
import org.sonar.scanner.bootstrap.GlobalAnalysisMode; | |||
import org.sonar.scanner.bootstrap.GlobalConfiguration; | |||
public class ModuleConfigurationProvider extends ProviderAdapter { | |||
private ModuleConfiguration moduleConfiguration; | |||
public ModuleConfiguration provide(GlobalConfiguration globalConfig, DefaultInputModule module, ProjectServerSettings projectServerSettings, GlobalAnalysisMode analysisMode) { | |||
public ModuleConfiguration provide(GlobalConfiguration globalConfig, DefaultInputModule module, ProjectServerSettings projectServerSettings) { | |||
if (moduleConfiguration == null) { | |||
Map<String, String> settings = new LinkedHashMap<>(projectServerSettings.properties()); | |||
addScannerSideProperties(settings, module.definition()); | |||
moduleConfiguration = new ModuleConfiguration(globalConfig.getDefinitions(), globalConfig.getEncryption(), analysisMode, settings); | |||
moduleConfiguration = new ModuleConfiguration(globalConfig.getDefinitions(), globalConfig.getEncryption(), settings); | |||
} | |||
return moduleConfiguration; | |||
} |
@@ -22,13 +22,12 @@ package org.sonar.scanner.scan; | |||
import java.util.Map; | |||
import org.sonar.api.config.Encryption; | |||
import org.sonar.api.config.PropertyDefinitions; | |||
import org.sonar.scanner.bootstrap.GlobalAnalysisMode; | |||
import org.sonar.scanner.config.DefaultConfiguration; | |||
public class ProjectConfiguration extends DefaultConfiguration { | |||
public ProjectConfiguration(PropertyDefinitions propertyDefinitions, Encryption encryption, GlobalAnalysisMode mode, Map<String, String> props) { | |||
super(propertyDefinitions, encryption, mode, props); | |||
public ProjectConfiguration(PropertyDefinitions propertyDefinitions, Encryption encryption, Map<String, String> props) { | |||
super(propertyDefinitions, encryption, props); | |||
} | |||
} |
@@ -23,7 +23,6 @@ import java.util.LinkedHashMap; | |||
import java.util.Map; | |||
import org.picocontainer.injectors.ProviderAdapter; | |||
import org.sonar.api.batch.fs.internal.DefaultInputProject; | |||
import org.sonar.scanner.bootstrap.GlobalAnalysisMode; | |||
import org.sonar.scanner.bootstrap.GlobalConfiguration; | |||
import org.sonar.scanner.bootstrap.GlobalServerSettings; | |||
@@ -32,7 +31,7 @@ public class ProjectConfigurationProvider extends ProviderAdapter { | |||
private ProjectConfiguration projectConfig; | |||
public ProjectConfiguration provide(DefaultInputProject project, GlobalConfiguration globalConfig, GlobalServerSettings globalServerSettings, | |||
ProjectServerSettings projectServerSettings, GlobalAnalysisMode mode, MutableProjectSettings projectSettings) { | |||
ProjectServerSettings projectServerSettings, MutableProjectSettings projectSettings) { | |||
if (projectConfig == null) { | |||
Map<String, String> settings = new LinkedHashMap<>(); | |||
@@ -40,7 +39,7 @@ public class ProjectConfigurationProvider extends ProviderAdapter { | |||
settings.putAll(projectServerSettings.properties()); | |||
settings.putAll(project.properties()); | |||
projectConfig = new ProjectConfiguration(globalConfig.getDefinitions(), globalConfig.getEncryption(), mode, settings); | |||
projectConfig = new ProjectConfiguration(globalConfig.getDefinitions(), globalConfig.getEncryption(), settings); | |||
projectSettings.complete(projectConfig); | |||
} | |||
return projectConfig; |
@@ -26,7 +26,6 @@ import org.sonar.api.CoreProperties; | |||
import org.sonar.api.notifications.AnalysisWarnings; | |||
import org.sonar.api.utils.log.Logger; | |||
import org.sonar.api.utils.log.Loggers; | |||
import org.sonar.scanner.bootstrap.ScannerProperties; | |||
import org.sonar.scanner.repository.settings.SettingsLoader; | |||
public class ProjectServerSettingsProvider extends ProviderAdapter { | |||
@@ -40,9 +39,9 @@ public class ProjectServerSettingsProvider extends ProviderAdapter { | |||
private ProjectServerSettings singleton = null; | |||
public ProjectServerSettings provide(SettingsLoader loader, ScannerProperties scannerProperties, AnalysisWarnings analysisWarnings) { | |||
public ProjectServerSettings provide(SettingsLoader loader, AnalysisWarnings analysisWarnings) { | |||
if (singleton == null) { | |||
Map<String, String> serverSideSettings = loader.load(scannerProperties.getKeyWithBranch()); | |||
Map<String, String> serverSideSettings = loader.loadProjectSettings(); | |||
if (StringUtils.isNotBlank(serverSideSettings.get(CoreProperties.MODULE_LEVEL_ARCHIVED_SETTINGS))) { | |||
LOG.warn(MODULE_LEVEL_ARCHIVED_SETTINGS_WARNING); | |||
analysisWarnings.addUnique(MODULE_LEVEL_ARCHIVED_SETTINGS_WARNING); |
@@ -110,7 +110,7 @@ public class FileIndexer { | |||
if (projectExclusionFilters.equals(moduleExclusionFilters)) { | |||
warnOnceDeprecatedExclusion( | |||
"Specifying module-relative paths at project level in the files exclusions/inclusions properties is deprecated. " + | |||
"To continue including/excluding files like '" + projectRelativePath + "' from the analysis, " + | |||
"To continue matching files like '" + projectRelativePath + "', " + | |||
"update these properties so that patterns refer to project-relative paths."); | |||
} | |||
excludedByPatternsCount.incrementAndGet(); | |||
@@ -163,7 +163,7 @@ public class FileIndexer { | |||
if (Arrays.equals(moduleCoverageExclusions.getCoverageExclusionConfig(), projectCoverageExclusions.getCoverageExclusionConfig())) { | |||
warnOnceDeprecatedCoverageExclusion( | |||
"Specifying module-relative paths at project level in the property '" + CoreProperties.PROJECT_COVERAGE_EXCLUSIONS_PROPERTY + "' is deprecated. " + | |||
"To continue excluding files like '" + inputFile + "' from coverage, update this property so that patterns refer to project-relative paths."); | |||
"To continue matching files like '" + inputFile + "', update this property so that patterns refer to project-relative paths."); | |||
} | |||
LOG.debug("File {} excluded for coverage", inputFile); | |||
} |
@@ -21,17 +21,12 @@ package org.sonar.scanner.scan.filesystem; | |||
import javax.annotation.concurrent.Immutable; | |||
import org.sonar.api.batch.fs.internal.DefaultInputFile; | |||
import org.sonar.api.batch.fs.internal.DefaultInputModule; | |||
import static org.sonar.api.config.internal.MultivalueProperty.parseAsCsv; | |||
import org.sonar.scanner.scan.ModuleConfiguration; | |||
@Immutable | |||
public class ModuleCoverageExclusions extends AbstractCoverageExclusions { | |||
public ModuleCoverageExclusions(DefaultInputModule module) { | |||
super(k -> { | |||
String value = module.properties().get(k); | |||
return value != null ? parseAsCsv(k, value) : new String[0]; | |||
}, DefaultInputFile::getModuleRelativePath); | |||
public ModuleCoverageExclusions(ModuleConfiguration moduleConfiguration) { | |||
super(moduleConfiguration::getStringArray, DefaultInputFile::getModuleRelativePath); | |||
} | |||
} |
@@ -19,17 +19,12 @@ | |||
*/ | |||
package org.sonar.scanner.scan.filesystem; | |||
import org.sonar.api.batch.fs.internal.DefaultInputModule; | |||
import static org.sonar.api.config.internal.MultivalueProperty.parseAsCsv; | |||
import org.sonar.scanner.scan.ModuleConfiguration; | |||
public class ModuleExclusionFilters extends AbstractExclusionFilters { | |||
public ModuleExclusionFilters(DefaultInputModule module) { | |||
super(k -> { | |||
String value = module.properties().get(k); | |||
return value != null ? parseAsCsv(k, value) : new String[0]; | |||
}); | |||
public ModuleExclusionFilters(ModuleConfiguration moduleConfiguration) { | |||
super(moduleConfiguration::getStringArray); | |||
} | |||
} |
@@ -41,6 +41,10 @@ import org.sonar.api.batch.fs.InputFile.Type; | |||
import org.sonar.api.batch.fs.internal.DefaultInputModule; | |||
import org.sonar.api.batch.fs.internal.InputModuleHierarchy; | |||
import org.sonar.api.scan.filesystem.PathResolver; | |||
import org.sonar.scanner.bootstrap.GlobalConfiguration; | |||
import org.sonar.scanner.scan.ModuleConfiguration; | |||
import org.sonar.scanner.scan.ModuleConfigurationProvider; | |||
import org.sonar.scanner.scan.ProjectServerSettings; | |||
import org.sonar.scanner.util.ProgressReport; | |||
/** | |||
@@ -52,15 +56,19 @@ public class ProjectFileIndexer { | |||
private final AbstractExclusionFilters projectExclusionFilters; | |||
private final InputComponentStore componentStore; | |||
private final InputModuleHierarchy inputModuleHierarchy; | |||
private final GlobalConfiguration globalConfig; | |||
private final ProjectServerSettings projectServerSettings; | |||
private final FileIndexer fileIndexer; | |||
private ProgressReport progressReport; | |||
public ProjectFileIndexer(InputComponentStore componentStore, AbstractExclusionFilters exclusionFilters, | |||
InputModuleHierarchy inputModuleHierarchy, | |||
InputModuleHierarchy inputModuleHierarchy, GlobalConfiguration globalConfig, ProjectServerSettings projectServerSettings, | |||
FileIndexer fileIndexer) { | |||
this.componentStore = componentStore; | |||
this.inputModuleHierarchy = inputModuleHierarchy; | |||
this.globalConfig = globalConfig; | |||
this.projectServerSettings = projectServerSettings; | |||
this.fileIndexer = fileIndexer; | |||
this.projectExclusionFilters = exclusionFilters; | |||
} | |||
@@ -94,8 +102,10 @@ public class ProjectFileIndexer { | |||
logPaths(" Source paths: ", module.getBaseDir(), module.getSourceDirsOrFiles()); | |||
logPaths(" Test paths: ", module.getBaseDir(), module.getTestDirsOrFiles()); | |||
} | |||
ModuleExclusionFilters moduleExclusionFilters = new ModuleExclusionFilters(module); | |||
ModuleCoverageExclusions moduleCoverageExclusions = new ModuleCoverageExclusions(module); | |||
// Emulate creation of module level settings | |||
ModuleConfiguration moduleConfig = new ModuleConfigurationProvider().provide(globalConfig, module, projectServerSettings); | |||
ModuleExclusionFilters moduleExclusionFilters = new ModuleExclusionFilters(moduleConfig); | |||
ModuleCoverageExclusions moduleCoverageExclusions = new ModuleCoverageExclusions(moduleConfig); | |||
indexFiles(module, moduleExclusionFilters, moduleCoverageExclusions, module.getSourceDirsOrFiles(), Type.MAIN, excludedByPatternsCount); | |||
indexFiles(module, moduleExclusionFilters, moduleCoverageExclusions, module.getTestDirsOrFiles(), Type.TEST, excludedByPatternsCount); | |||
} |
@@ -43,20 +43,18 @@ public class GlobalConfigurationProviderTest { | |||
GlobalServerSettings globalServerSettings; | |||
ScannerProperties scannerProps; | |||
private GlobalAnalysisMode mode; | |||
@Before | |||
public void prepare() { | |||
globalServerSettings = mock(GlobalServerSettings.class); | |||
scannerProps = new ScannerProperties(Collections.<String, String>emptyMap()); | |||
mode = mock(GlobalAnalysisMode.class); | |||
} | |||
@Test | |||
public void should_load_global_settings() { | |||
when(globalServerSettings.properties()).thenReturn(ImmutableMap.of("sonar.cpd.cross", "true")); | |||
GlobalConfiguration globalConfig = new GlobalConfigurationProvider().provide(globalServerSettings, scannerProps, new PropertyDefinitions(), mode); | |||
GlobalConfiguration globalConfig = new GlobalConfigurationProvider().provide(globalServerSettings, scannerProps, new PropertyDefinitions()); | |||
assertThat(globalConfig.get("sonar.cpd.cross")).hasValue("true"); | |||
} |
@@ -30,11 +30,9 @@ import org.sonar.api.config.PropertyDefinitions; | |||
import org.sonar.api.config.PropertyFieldDefinition; | |||
import org.sonar.api.utils.log.LogTester; | |||
import org.sonar.api.utils.log.LoggerLevel; | |||
import org.sonar.scanner.bootstrap.GlobalAnalysisMode; | |||
import static org.assertj.core.api.Assertions.assertThat; | |||
import static org.assertj.core.api.Assertions.fail; | |||
import static org.mockito.Mockito.mock; | |||
public class DefaultConfigurationTest { | |||
@@ -46,7 +44,6 @@ public class DefaultConfigurationTest { | |||
Configuration config = new DefaultConfiguration(new PropertyDefinitions(Arrays.asList( | |||
PropertyDefinition.builder("single").multiValues(false).build(), | |||
PropertyDefinition.builder("multiA").multiValues(true).build())), new Encryption(null), | |||
mock(GlobalAnalysisMode.class), | |||
ImmutableMap.of("single", "foo", "multiA", "a,b", "notDeclared", "c,d")) { | |||
}; | |||
@@ -74,7 +71,6 @@ public class DefaultConfigurationTest { | |||
Configuration config = new DefaultConfiguration(new PropertyDefinitions(Arrays.asList( | |||
PropertyDefinition.builder("props").fields(PropertyFieldDefinition.build("foo1").name("Foo1").build(), PropertyFieldDefinition.build("foo2").name("Foo2").build()).build())), | |||
new Encryption(null), | |||
mock(GlobalAnalysisMode.class), | |||
ImmutableMap.of("props", "1,2", "props.1.foo1", "a", "props.1.foo2", "b")) { | |||
}; | |||
@@ -94,7 +90,6 @@ public class DefaultConfigurationTest { | |||
Configuration config = new DefaultConfiguration(new PropertyDefinitions(Arrays.asList( | |||
PropertyDefinition.builder("single").multiValues(false).defaultValue("default").build(), | |||
PropertyDefinition.builder("multiA").multiValues(true).defaultValue("foo,bar").build())), new Encryption(null), | |||
mock(GlobalAnalysisMode.class), | |||
ImmutableMap.of()) { | |||
}; | |||
@@ -134,7 +129,6 @@ public class DefaultConfigurationTest { | |||
private String[] getStringArray(String value) { | |||
return new DefaultConfiguration(new PropertyDefinitions(Arrays.asList( | |||
PropertyDefinition.builder("multi").multiValues(true).build())), new Encryption(null), | |||
mock(GlobalAnalysisMode.class), | |||
ImmutableMap.of("multi", value)) { | |||
}.getStringArray("multi"); | |||
} |
@@ -28,12 +28,10 @@ import org.sonar.api.config.Encryption; | |||
import org.sonar.api.config.PropertyDefinitions; | |||
import org.sonar.api.utils.log.LogTester; | |||
import org.sonar.api.utils.log.LoggerLevel; | |||
import org.sonar.scanner.bootstrap.GlobalAnalysisMode; | |||
import org.sonar.scanner.config.DefaultConfiguration; | |||
import org.sonar.scanner.scan.ProjectConfiguration; | |||
import static org.assertj.core.api.Assertions.assertThat; | |||
import static org.mockito.Mockito.mock; | |||
public class GenericCoverageSensorTest { | |||
@@ -49,7 +47,7 @@ public class GenericCoverageSensorTest { | |||
settings.put(GenericCoverageSensor.OLD_OVERALL_COVERAGE_REPORT_PATHS_PROPERTY_KEY, "old5.xml,old6.xml"); | |||
PropertyDefinitions defs = new PropertyDefinitions(GenericCoverageSensor.properties()); | |||
DefaultConfiguration config = new ProjectConfiguration(defs, new Encryption(null), mock(GlobalAnalysisMode.class), settings); | |||
DefaultConfiguration config = new ProjectConfiguration(defs, new Encryption(null), settings); | |||
Set<String> reportPaths = new GenericCoverageSensor(config).loadReportPaths(); | |||
@@ -33,7 +33,6 @@ import org.sonar.api.config.Encryption; | |||
import org.sonar.api.config.PropertyDefinitions; | |||
import org.sonar.api.utils.log.LogTester; | |||
import org.sonar.api.utils.log.LoggerLevel; | |||
import org.sonar.scanner.bootstrap.GlobalAnalysisMode; | |||
import org.sonar.scanner.config.DefaultConfiguration; | |||
import org.sonar.scanner.deprecated.test.TestPlanBuilder; | |||
import org.sonar.scanner.scan.ProjectConfiguration; | |||
@@ -59,7 +58,7 @@ public class GenericTestExecutionSensorTest { | |||
Map<String, String> settings = new HashMap<>(); | |||
settings.put(GenericTestExecutionSensor.OLD_UNIT_TEST_REPORT_PATHS_PROPERTY_KEY, "report.xml"); | |||
PropertyDefinitions defs = new PropertyDefinitions(GenericTestExecutionSensor.properties()); | |||
DefaultConfiguration config = new ProjectConfiguration(defs, new Encryption(null), mock(GlobalAnalysisMode.class), settings); | |||
DefaultConfiguration config = new ProjectConfiguration(defs, new Encryption(null), settings); | |||
new GenericTestExecutionSensor(mock(TestPlanBuilder.class), config).execute(context); | |||
assertThat(logTester.logs(LoggerLevel.WARN)).contains( |
@@ -19,9 +19,7 @@ | |||
*/ | |||
package org.sonar.scanner.mediumtest; | |||
import com.google.common.collect.HashBasedTable; | |||
import com.google.common.collect.Maps; | |||
import com.google.common.collect.Table; | |||
import java.io.File; | |||
import java.io.FileInputStream; | |||
import java.io.IOException; | |||
@@ -91,6 +89,7 @@ public class ScannerMediumTester extends ExternalResource { | |||
private final FakeProjectRepositoriesLoader projectRefProvider = new FakeProjectRepositoriesLoader(); | |||
private final FakePluginInstaller pluginInstaller = new FakePluginInstaller(); | |||
private final FakeServerIssuesLoader serverIssues = new FakeServerIssuesLoader(); | |||
private final FakeSettingsLoader settingsLoader = new FakeSettingsLoader(); | |||
private final FakeServerLineHashesLoader serverLineHashes = new FakeServerLineHashesLoader(); | |||
private final FakeRulesLoader rulesLoader = new FakeRulesLoader(); | |||
private final FakeQualityProfileLoader qualityProfiles = new FakeQualityProfileLoader(); | |||
@@ -230,6 +229,16 @@ public class ScannerMediumTester extends ExternalResource { | |||
return this; | |||
} | |||
public ScannerMediumTester addGlobalServerSettings(String key, String value) { | |||
settingsLoader.getGlobalSettings().put(key, value); | |||
return this; | |||
} | |||
public ScannerMediumTester addProjectServerSettings(String key, String value) { | |||
settingsLoader.getProjectSettings().put(key, value); | |||
return this; | |||
} | |||
public ScannerMediumTester mockLineHashes(String fileKey, String[] lineHashes) { | |||
serverLineHashes.byKey.put(fileKey, lineHashes); | |||
return this; | |||
@@ -302,7 +311,7 @@ public class ScannerMediumTester extends ExternalResource { | |||
tester.projectRefProvider, | |||
tester.activeRules, | |||
tester.serverIssues, | |||
new FakeSettingsLoader(), | |||
tester.settingsLoader, | |||
result) | |||
.setLogOutput(tester.logOutput) | |||
.build().execute(); | |||
@@ -495,9 +504,25 @@ public class ScannerMediumTester extends ExternalResource { | |||
private static class FakeSettingsLoader implements SettingsLoader { | |||
private Map<String, String> globalSettings = new HashMap<>(); | |||
private Map<String, String> projectSettings = new HashMap<>(); | |||
public Map<String, String> getGlobalSettings() { | |||
return globalSettings; | |||
} | |||
public Map<String, String> getProjectSettings() { | |||
return projectSettings; | |||
} | |||
@Override | |||
public Map<String, String> loadGlobalSettings() { | |||
return Collections.unmodifiableMap(globalSettings); | |||
} | |||
@Override | |||
public Map<String, String> load(String componentKey) { | |||
return Collections.emptyMap(); | |||
public Map<String, String> loadProjectSettings() { | |||
return Collections.unmodifiableMap(projectSettings); | |||
} | |||
} | |||
@@ -159,7 +159,7 @@ public class CoverageMediumTest { | |||
} | |||
@Test | |||
public void warn_user_for_outdated_inherited_exclusions_for_multi_module_project() throws IOException { | |||
public void warn_user_for_outdated_inherited_scanner_side_exclusions_for_multi_module_project() throws IOException { | |||
File baseDir = temp.getRoot(); | |||
File baseDirModuleA = new File(baseDir, "moduleA"); | |||
@@ -197,7 +197,50 @@ public class CoverageMediumTest { | |||
assertThat(result.coverageFor(fileB, 2)).isNull(); | |||
assertThat(logTester.logs(LoggerLevel.WARN)).contains("Specifying module-relative paths at project level in the property 'sonar.coverage.exclusions' is deprecated. " + | |||
"To continue excluding files like 'moduleA/src/sample.xoo' from coverage, update this property so that patterns refer to project-relative paths."); | |||
"To continue matching files like 'moduleA/src/sample.xoo', update this property so that patterns refer to project-relative paths."); | |||
} | |||
@Test | |||
public void warn_user_for_outdated_server_side_exclusions_for_multi_module_project() throws IOException { | |||
File baseDir = temp.getRoot(); | |||
File baseDirModuleA = new File(baseDir, "moduleA"); | |||
File baseDirModuleB = new File(baseDir, "moduleB"); | |||
File srcDirA = new File(baseDirModuleA, "src"); | |||
srcDirA.mkdirs(); | |||
File srcDirB = new File(baseDirModuleB, "src"); | |||
srcDirB.mkdirs(); | |||
File xooFileA = new File(srcDirA, "sample.xoo"); | |||
File xooUtCoverageFileA = new File(srcDirA, "sample.xoo.coverage"); | |||
FileUtils.write(xooFileA, "function foo() {\n if (a && b) {\nalert('hello');\n}\n}", StandardCharsets.UTF_8); | |||
FileUtils.write(xooUtCoverageFileA, "2:2:2:1\n3:1", StandardCharsets.UTF_8); | |||
File xooFileB = new File(srcDirB, "sample.xoo"); | |||
File xooUtCoverageFileB = new File(srcDirB, "sample.xoo.coverage"); | |||
FileUtils.write(xooFileB, "function foo() {\n if (a && b) {\nalert('hello');\n}\n}", StandardCharsets.UTF_8); | |||
FileUtils.write(xooUtCoverageFileB, "2:2:2:1\n3:1", StandardCharsets.UTF_8); | |||
tester.addProjectServerSettings("sonar.coverage.exclusions", "src/sample.xoo"); | |||
AnalysisResult result = tester.newAnalysis() | |||
.properties(ImmutableMap.<String, String>builder() | |||
.put("sonar.task", "scan") | |||
.put("sonar.projectBaseDir", baseDir.getAbsolutePath()) | |||
.put("sonar.projectKey", "com.foo.project") | |||
.put("sonar.sources", "src") | |||
.put("sonar.modules", "moduleA,moduleB") | |||
.build()) | |||
.execute(); | |||
InputFile fileA = result.inputFile("moduleA/src/sample.xoo"); | |||
assertThat(result.coverageFor(fileA, 2)).isNull(); | |||
InputFile fileB = result.inputFile("moduleB/src/sample.xoo"); | |||
assertThat(result.coverageFor(fileB, 2)).isNull(); | |||
assertThat(logTester.logs(LoggerLevel.WARN)).contains("Specifying module-relative paths at project level in the property 'sonar.coverage.exclusions' is deprecated. " + | |||
"To continue matching files like 'moduleA/src/sample.xoo', update this property so that patterns refer to project-relative paths."); | |||
} | |||
@Test |
@@ -71,32 +71,16 @@ public class FileSystemMediumTest { | |||
private ImmutableMap.Builder<String, String> builder; | |||
@Before | |||
public void prepare() throws IOException { | |||
public void prepare() { | |||
baseDir = temp.getRoot(); | |||
builder = ImmutableMap.<String, String>builder() | |||
.put("sonar.task", "scan") | |||
.put("sonar.projectBaseDir", baseDir.getAbsolutePath()) | |||
.put("sonar.projectKey", "com.foo.project") | |||
.put("sonar.projectName", "Foo Project") | |||
.put("sonar.projectVersion", "1.0-SNAPSHOT") | |||
.put("sonar.projectDescription", "Description of Foo Project"); | |||
} | |||
private ImmutableMap.Builder<String, String> createBuilder() { | |||
return ImmutableMap.<String, String>builder() | |||
.put("sonar.task", "scan") | |||
.put("sonar.verbose", "true") | |||
.put("sonar.projectBaseDir", baseDir.getAbsolutePath()) | |||
.put("sonar.projectKey", "com.foo.project") | |||
.put("sonar.projectVersion", "1.0-SNAPSHOT") | |||
.put("sonar.projectDescription", "Description of Foo Project"); | |||
.put("sonar.projectKey", "com.foo.project"); | |||
} | |||
@Test | |||
public void scanProjectWithoutProjectName() throws IOException { | |||
builder = createBuilder(); | |||
File srcDir = new File(baseDir, "src"); | |||
srcDir.mkdir(); | |||
@@ -125,7 +109,6 @@ public class FileSystemMediumTest { | |||
@Test | |||
public void logProjectKeyAndOrganizationKey() throws IOException { | |||
builder = createBuilder(); | |||
builder.put("sonar.organization", "my org"); | |||
builder.put("sonar.branch", ""); | |||
File srcDir = new File(baseDir, "src"); | |||
@@ -147,7 +130,6 @@ public class FileSystemMediumTest { | |||
@Test | |||
public void logBranchKey() throws IOException { | |||
builder = createBuilder(); | |||
builder.put("sonar.branch", "my-branch"); | |||
File srcDir = new File(baseDir, "src"); | |||
assertThat(srcDir.mkdir()).isTrue(); | |||
@@ -163,20 +145,18 @@ public class FileSystemMediumTest { | |||
assertThat(logTester.logs()).contains("Project key: com.foo.project"); | |||
assertThat(logTester.logs()).contains("Branch key: my-branch"); | |||
assertThat(logTester.logs()).contains("The use of \"sonar.branch\" is deprecated and replaced by \"sonar.branch.name\". See https://redirect.sonarsource.com/doc/branches.html."); | |||
assertThat(logTester.logs()) | |||
.contains("The use of \"sonar.branch\" is deprecated and replaced by \"sonar.branch.name\". See https://redirect.sonarsource.com/doc/branches.html."); | |||
} | |||
@Test | |||
public void logBranchNameAndType() throws IOException { | |||
builder = createBuilder(); | |||
builder.put("sonar.branch.name", "my-branch"); | |||
File srcDir = new File(baseDir, "src"); | |||
assertThat(srcDir.mkdir()).isTrue(); | |||
// Using sonar.branch.name when the branch plugin is not installed is an error. | |||
// IllegalStateException is expected here, because this test is in a bit artificial, | |||
// the fail-fast mechanism in the scanner should have prevented reaching this point. | |||
thrown.expect(IllegalStateException.class); | |||
thrown.expect(MessageException.class); | |||
tester.newAnalysis() | |||
.properties(builder | |||
@@ -187,7 +167,6 @@ public class FileSystemMediumTest { | |||
@Test | |||
public void dontLogInvalidOrganization() throws IOException { | |||
builder = createBuilder(); | |||
File srcDir = new File(baseDir, "src"); | |||
srcDir.mkdir(); | |||
@@ -207,8 +186,6 @@ public class FileSystemMediumTest { | |||
@Test | |||
public void onlyGenerateMetadataIfNeeded() throws IOException { | |||
builder = createBuilder(); | |||
File srcDir = new File(baseDir, "src"); | |||
srcDir.mkdir(); | |||
@@ -234,8 +211,7 @@ public class FileSystemMediumTest { | |||
@Test | |||
public void preloadFileMetadata() throws IOException { | |||
builder = createBuilder() | |||
.put("sonar.preloadFileMetadata", "true"); | |||
builder.put("sonar.preloadFileMetadata", "true"); | |||
File srcDir = new File(baseDir, "src"); | |||
srcDir.mkdir(); | |||
@@ -261,8 +237,6 @@ public class FileSystemMediumTest { | |||
@Test | |||
public void dontPublishFilesWithoutDetectedLanguage() throws IOException { | |||
builder = createBuilder(); | |||
Path mainDir = baseDir.toPath().resolve("src").resolve("main"); | |||
Files.createDirectories(mainDir); | |||
@@ -305,8 +279,6 @@ public class FileSystemMediumTest { | |||
.addRules(new XooRulesDefinition()) | |||
.addActiveRule("xoo", "OneIssuePerUnknownFile", null, "OneIssuePerUnknownFile", "MAJOR", null, "xoo"); | |||
builder = createBuilder(); | |||
File srcDir = new File(baseDir, "src"); | |||
srcDir.mkdir(); | |||
@@ -334,7 +306,6 @@ public class FileSystemMediumTest { | |||
.addRules(new XooRulesDefinition()) | |||
.addActiveRule("xoo", "OneIssuePerFile", null, "OneIssuePerFile", "MAJOR", null, "xoo"); | |||
builder = createBuilder(); | |||
builder.put("sonar.issue.ignore.allfile", "1") | |||
.put("sonar.issue.ignore.allfile.1.fileRegexp", "pattern"); | |||
File srcDir = new File(baseDir, "src"); | |||
@@ -363,7 +334,6 @@ public class FileSystemMediumTest { | |||
@Test | |||
public void preloadIssueExclusions() throws IOException { | |||
builder = createBuilder(); | |||
builder.put("sonar.issue.ignore.allfile", "1") | |||
.put("sonar.issue.ignore.allfile.1.fileRegexp", "pattern") | |||
.put("sonar.preloadFileMetadata", "true"); | |||
@@ -394,8 +364,6 @@ public class FileSystemMediumTest { | |||
.addRules(new XooRulesDefinition()) | |||
.addActiveRule("xoo", "OneIssueOnDirPerFile", null, "OneIssueOnDirPerFile", "MAJOR", null, "xoo"); | |||
builder = createBuilder(); | |||
File srcDir = new File(baseDir, "src"); | |||
srcDir.mkdir(); | |||
@@ -541,8 +509,7 @@ public class FileSystemMediumTest { | |||
} | |||
@Test | |||
public void warn_user_for_outdated_inherited_exclusions_for_multi_module_project() throws IOException { | |||
public void warn_user_for_outdated_scanner_side_inherited_exclusions_for_multi_module_project() throws IOException { | |||
File baseDir = temp.getRoot(); | |||
File baseDirModuleA = new File(baseDir, "moduleA"); | |||
File baseDirModuleB = new File(baseDir, "moduleB"); | |||
@@ -576,7 +543,46 @@ public class FileSystemMediumTest { | |||
assertThat(logTester.logs(LoggerLevel.WARN)) | |||
.contains("Specifying module-relative paths at project level in the files exclusions/inclusions properties is deprecated. " + | |||
"To continue including/excluding files like 'moduleA/src/sample.xoo' from the analysis, update these properties so that patterns refer to project-relative paths."); | |||
"To continue matching files like 'moduleA/src/sample.xoo', update these properties so that patterns refer to project-relative paths."); | |||
} | |||
@Test | |||
public void warn_user_for_outdated_server_side_inherited_exclusions_for_multi_module_project() throws IOException { | |||
File baseDir = temp.getRoot(); | |||
File baseDirModuleA = new File(baseDir, "moduleA"); | |||
File baseDirModuleB = new File(baseDir, "moduleB"); | |||
File srcDirA = new File(baseDirModuleA, "src"); | |||
srcDirA.mkdirs(); | |||
File srcDirB = new File(baseDirModuleB, "src"); | |||
srcDirB.mkdirs(); | |||
File xooFileA = new File(srcDirA, "sample.xoo"); | |||
FileUtils.write(xooFileA, "Sample xoo\ncontent", StandardCharsets.UTF_8); | |||
File xooFileB = new File(srcDirB, "sample.xoo"); | |||
FileUtils.write(xooFileB, "Sample xoo\ncontent", StandardCharsets.UTF_8); | |||
tester.addProjectServerSettings("sonar.exclusions", "src/sample.xoo"); | |||
AnalysisResult result = tester.newAnalysis() | |||
.properties(ImmutableMap.<String, String>builder() | |||
.put("sonar.task", "scan") | |||
.put("sonar.projectBaseDir", baseDir.getAbsolutePath()) | |||
.put("sonar.projectKey", "com.foo.project") | |||
.put("sonar.sources", "src") | |||
.put("sonar.modules", "moduleA,moduleB") | |||
.build()) | |||
.execute(); | |||
InputFile fileA = result.inputFile("moduleA/src/sample.xoo"); | |||
assertThat(fileA).isNull(); | |||
InputFile fileB = result.inputFile("moduleB/src/sample.xoo"); | |||
assertThat(fileB).isNull(); | |||
assertThat(logTester.logs(LoggerLevel.WARN)) | |||
.contains("Specifying module-relative paths at project level in the files exclusions/inclusions properties is deprecated. " + | |||
"To continue matching files like 'moduleA/src/sample.xoo', update these properties so that patterns refer to project-relative paths."); | |||
} | |||
@Test |
@@ -102,7 +102,7 @@ public class ExceptionHandlingMediumTest { | |||
boolean withCause = false; | |||
@Override | |||
public Map<String, String> load(String componentKey) { | |||
public Map<String, String> loadGlobalSettings() { | |||
if (withCause) { | |||
IllegalStateException cause = new IllegalStateException("Code 401"); | |||
throw MessageException.of("Error loading settings", cause); | |||
@@ -110,5 +110,10 @@ public class ExceptionHandlingMediumTest { | |||
throw MessageException.of("Error loading settings"); | |||
} | |||
} | |||
@Override | |||
public Map<String, String> loadProjectSettings() { | |||
return null; | |||
} | |||
} | |||
} |
@@ -20,15 +20,11 @@ | |||
package org.sonar.scanner.phases; | |||
import java.io.File; | |||
import java.util.Arrays; | |||
import java.util.stream.Collectors; | |||
import org.junit.Before; | |||
import org.junit.Rule; | |||
import org.junit.Test; | |||
import org.junit.rules.TemporaryFolder; | |||
import org.sonar.api.batch.bootstrap.ProjectDefinition; | |||
import org.sonar.api.batch.fs.internal.DefaultInputFile; | |||
import org.sonar.api.batch.fs.internal.DefaultInputModule; | |||
import org.sonar.api.batch.fs.internal.TestInputFileBuilder; | |||
import org.sonar.scanner.scan.ModuleConfiguration; | |||
import org.sonar.scanner.scan.filesystem.ModuleCoverageExclusions; | |||
@@ -68,12 +64,9 @@ public class ModuleCoverageExclusionsTest { | |||
assertThat(coverageExclusions.isExcluded(file)).isFalse(); | |||
} | |||
private DefaultInputModule mockConfig(String... values) { | |||
private ModuleConfiguration mockConfig(String... values) { | |||
ModuleConfiguration config = mock(ModuleConfiguration.class); | |||
when(config.getStringArray("sonar.coverage.exclusions")).thenReturn(values); | |||
return new DefaultInputModule(ProjectDefinition.create() | |||
.setBaseDir(baseDir) | |||
.setWorkDir(baseDir) | |||
.setProperty("sonar.coverage.exclusions", Arrays.asList(values).stream().collect(Collectors.joining(",")))); | |||
return config; | |||
} | |||
} |