import java.nio.file.Files;
import java.nio.file.StandardOpenOption;
import java.util.Map;
+import java.util.Properties;
+import java.util.TreeSet;
import org.sonar.api.batch.AnalysisMode;
import org.sonar.api.batch.BatchSide;
import org.sonar.api.batch.bootstrap.ProjectDefinition;
import org.sonar.api.config.Settings;
import org.sonar.api.utils.System2;
+import org.sonar.api.utils.log.Logger;
+import org.sonar.api.utils.log.Loggers;
import org.sonar.batch.bootstrap.BatchPluginRepository;
import org.sonar.batch.protocol.output.BatchReportWriter;
import org.sonar.core.platform.PluginInfo;
@BatchSide
public class AnalysisContextReportPublisher {
+ private static final Logger LOG = Loggers.get(AnalysisContextReportPublisher.class);
+
private static final String ENV_PROP_PREFIX = "env.";
private static final String SONAR_PROP_PREFIX = "sonar.";
private final BatchPluginRepository pluginRepo;
this.writer = writer;
File analysisLog = writer.getFileStructure().analysisLog();
try (BufferedWriter fileWriter = Files.newBufferedWriter(analysisLog.toPath(), StandardCharsets.UTF_8)) {
- writeEnvVariables(fileWriter);
- writeSystemProps(fileWriter);
+ if (LOG.isDebugEnabled()) {
+ writeEnvVariables(fileWriter);
+ writeSystemProps(fileWriter);
+ }
writePlugins(fileWriter);
} catch (IOException e) {
throw new IllegalStateException("Unable to write analysis log", e);
private void writeSystemProps(BufferedWriter fileWriter) throws IOException {
fileWriter.write("System properties:\n");
- for (Map.Entry<Object, Object> env : system.properties().entrySet()) {
- if (env.getKey().toString().startsWith(SONAR_PROP_PREFIX)) {
+ Properties sysProps = system.properties();
+ for (String prop : new TreeSet<String>(sysProps.stringPropertyNames())) {
+ if (prop.startsWith(SONAR_PROP_PREFIX)) {
continue;
}
- fileWriter.append(String.format(" - %s=%s", env.getKey(), env.getValue())).append('\n');
+ fileWriter.append(String.format(" - %s=%s", prop, sysProps.getProperty(prop))).append('\n');
}
}
private void writeEnvVariables(BufferedWriter fileWriter) throws IOException {
fileWriter.append("Environment variables:\n");
- for (Map.Entry<String, String> env : system.envVariables().entrySet()) {
- fileWriter.append(String.format(" - %s=%s", env.getKey(), env.getValue())).append('\n');
+ Map<String, String> envVariables = system.envVariables();
+ for (String env : new TreeSet<String>(envVariables.keySet())) {
+ fileWriter.append(String.format(" - %s=%s", env, envVariables.get(env))).append('\n');
}
}
File analysisLog = writer.getFileStructure().analysisLog();
try (BufferedWriter fileWriter = Files.newBufferedWriter(analysisLog.toPath(), StandardCharsets.UTF_8, StandardOpenOption.WRITE, StandardOpenOption.APPEND)) {
fileWriter.append(String.format("Settings for module: %s", moduleDefinition.getKey())).append('\n');
- for (Map.Entry<String, String> prop : settings.getProperties().entrySet()) {
- if (alreadyLoggedAsSystemProp(prop) || alreadyLoggedAsEnv(prop)) {
+ Map<String, String> moduleSettings = settings.getProperties();
+ for (String prop : new TreeSet<String>(moduleSettings.keySet())) {
+ if (isSystemProp(prop) || isEnvVariable(prop) || !isSqProp(prop)) {
continue;
}
- fileWriter.append(String.format(" - %s=%s", prop.getKey(), sensitive(prop.getKey()) ? "******" : prop.getValue())).append('\n');
+ fileWriter.append(String.format(" - %s=%s", prop, sensitive(prop) ? "******" : moduleSettings.get(prop))).append('\n');
}
} catch (IOException e) {
throw new IllegalStateException("Unable to write analysis log", e);
}
}
- private boolean alreadyLoggedAsSystemProp(Map.Entry<String, String> prop) {
- return system.properties().containsKey(prop.getKey()) && !prop.getKey().startsWith(SONAR_PROP_PREFIX);
+ private static boolean isSqProp(String propKey) {
+ return propKey.startsWith(SONAR_PROP_PREFIX);
+ }
+
+ private boolean isSystemProp(String propKey) {
+ return system.properties().containsKey(propKey) && !propKey.startsWith(SONAR_PROP_PREFIX);
}
- private boolean alreadyLoggedAsEnv(Map.Entry<String, String> prop) {
- return prop.getKey().startsWith(ENV_PROP_PREFIX) && system.envVariables().containsKey(prop.getKey().substring(ENV_PROP_PREFIX.length()));
+ private boolean isEnvVariable(String propKey) {
+ return propKey.startsWith(ENV_PROP_PREFIX) && system.envVariables().containsKey(propKey.substring(ENV_PROP_PREFIX.length()));
}
private static boolean sensitive(String key) {
import org.sonar.api.batch.bootstrap.ProjectDefinition;
import org.sonar.api.config.Settings;
import org.sonar.api.utils.System2;
+import org.sonar.api.utils.log.LogTester;
+import org.sonar.api.utils.log.LoggerLevel;
import org.sonar.batch.bootstrap.BatchPluginRepository;
import org.sonar.batch.protocol.output.BatchReportWriter;
import org.sonar.core.platform.PluginInfo;
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verifyZeroInteractions;
import static org.mockito.Mockito.when;
public class AnalysisContextReportPublisherTest {
private static final String SONAR_SKIP = "sonar.skip";
private static final String COM_FOO = "com.foo";
+ @Rule
+ public LogTester logTester = new LogTester();
+
@Rule
public TemporaryFolder temp = new TemporaryFolder();
@Before
public void prepare() throws Exception {
+ logTester.setLevel(LoggerLevel.INFO);
system2 = mock(System2.class);
when(system2.properties()).thenReturn(new Properties());
publisher = new AnalysisContextReportPublisher(analysisMode, pluginRepo, system2);
}
@Test
- public void shouldDumpPlugins() throws Exception {
+ public void shouldOnlyDumpPluginsByDefault() throws Exception {
when(pluginRepo.getPluginInfos()).thenReturn(Arrays.asList(new PluginInfo("xoo").setName("Xoo").setVersion(Version.create("1.0"))));
BatchReportWriter writer = new BatchReportWriter(temp.newFolder());
assertThat(writer.getFileStructure().analysisLog()).exists();
assertThat(FileUtils.readFileToString(writer.getFileStructure().analysisLog())).contains("Xoo 1.0 (xoo)");
+
+ verifyZeroInteractions(system2);
}
@Test
@Test
public void shouldNotDumpSQPropsInSystemProps() throws Exception {
+ logTester.setLevel(LoggerLevel.DEBUG);
BatchReportWriter writer = new BatchReportWriter(temp.newFolder());
Properties props = new Properties();
props.setProperty(COM_FOO, "bar");
@Test
public void shouldNotDumpEnvTwice() throws Exception {
+ logTester.setLevel(LoggerLevel.DEBUG);
BatchReportWriter writer = new BatchReportWriter(temp.newFolder());
Map<String, String> env = new HashMap<>();
String content = FileUtils.readFileToString(writer.getFileStructure().analysisLog());
assertThat(content).containsOnlyOnce(FOO);
assertThat(content).containsOnlyOnce(BIZ);
+ assertThat(content).containsSequence(BIZ, FOO);
Settings settings = new Settings();
settings.setProperty("env." + FOO, "BAR");
- settings.setProperty("env.another", "world");
publisher.dumpSettings(ProjectDefinition.create().setProperty("sonar.projectKey", "foo"), settings);
content = FileUtils.readFileToString(writer.getFileStructure().analysisLog());
- assertThat(content).containsOnlyOnce("env.another");
assertThat(content).containsOnlyOnce(FOO);
assertThat(content).containsOnlyOnce(BIZ);
assertThat(content).doesNotContain("env." + FOO);
settings.setProperty("sonar.cpp.license.secured", "AZERTY");
publisher.dumpSettings(ProjectDefinition.create().setProperty("sonar.projectKey", "foo"), settings);
- assertThat(FileUtils.readFileToString(writer.getFileStructure().analysisLog())).contains("sonar.projectKey=foo", "sonar.password=******", "sonar.cpp.license.secured=******");
+ assertThat(FileUtils.readFileToString(writer.getFileStructure().analysisLog())).containsSequence(
+ "sonar.cpp.license.secured=******",
+ "sonar.password=******",
+ "sonar.projectKey=foo");
}
}