Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support environment variables and system properties in configuration files #716

Merged
merged 1 commit into from
Dec 30, 2015
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ public class UnnamedNamespaceInHeaderCheck extends SquidCheck<Grammar> {
public void init() {
subscribeTo(CxxGrammarImpl.unnamedNamespaceDefinition);
// ToDo use cxx.suffixes.headers ?? No API
// conf.getStringArray(CxxPlugin.INCLUDE_DIRECTORIES_KEY)
// settings.getStringArray(CxxPlugin.INCLUDE_DIRECTORIES_KEY)
}


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,8 @@
package org.sonar.plugins.cxx;

import org.apache.commons.lang.StringUtils;
import org.sonar.api.config.Settings;
import org.sonar.api.resources.AbstractLanguage;
import org.sonar.api.config.Settings;

/**
* {@inheritDoc}
Expand All @@ -32,17 +32,19 @@ public class CxxLanguage extends AbstractLanguage {
public static final String DEFAULT_C_FILES = "*.c,*.C";
public static final String KEY = "c++";

private CxxSettings settings;
private String[] sourceSuffixes;
private String[] headerSuffixes;
private String[] fileSuffixes;

/**
* {@inheritDoc}
*/
public CxxLanguage(Settings config) {
public CxxLanguage(Settings settings) {
super(KEY, "c++");
sourceSuffixes = createStringArray(config.getStringArray(CxxPlugin.SOURCE_FILE_SUFFIXES_KEY), DEFAULT_SOURCE_SUFFIXES);
headerSuffixes = createStringArray(config.getStringArray(CxxPlugin.HEADER_FILE_SUFFIXES_KEY), DEFAULT_HEADER_SUFFIXES);
this.settings = new CxxSettings(settings);
sourceSuffixes = createStringArray(this.settings.getStringArray(CxxPlugin.SOURCE_FILE_SUFFIXES_KEY), DEFAULT_SOURCE_SUFFIXES);
headerSuffixes = createStringArray(this.settings.getStringArray(CxxPlugin.HEADER_FILE_SUFFIXES_KEY), DEFAULT_HEADER_SUFFIXES);
fileSuffixes = mergeArrays(sourceSuffixes, headerSuffixes);
}

Expand Down
110 changes: 110 additions & 0 deletions sonar-cxx-plugin/src/main/java/org/sonar/plugins/cxx/CxxSettings.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
/*
* Sonar C++ Plugin (Community)
* Copyright (C) 2010 Neticoa SAS France
* [email protected]
*
* 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 02
*/
package org.sonar.plugins.cxx;

import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Properties;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.sonar.api.config.Settings;

/**
* CxxSettings supports variables in configuration files
*
* - CxxSettings clones Settings in ctor
* - format for placeholder is ${xxx} - supported are environment variables,
* Java system properties and SonarQube properties
* - backslashes in values from environment variables and Java system properties
* are replaced with slashes to support Windows paths
*/
public class CxxSettings extends Settings {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

wonder if the internals of Settings will be in proper state when it arrives to the plugin. i would assume core to create its own instance of Settings class, likely when CxxSettings gets into the plugin it comes without any information about the settings.

perhaps this class cannot be used like this, and might explain the issue in server side. Could this be done in a helper class that receives Settings and then returns the value as per you implementation below?


private final HashMap<String, String> vars = new HashMap<>();
private final Pattern regex = Pattern.compile("\\$\\{(.+?)\\}");

/**
* Clone settings.
*/
public CxxSettings(Settings other) {
super(other);

Map<String, String> envMap = System.getenv();
for (Entry<String, String> entry : envMap.entrySet()) {
String key = entry.getKey();
String value = entry.getValue();
value = value.replace("\\", "/");
vars.put(key, value);
}

Properties props = System.getProperties();
for (String key : props.stringPropertyNames()) {
String value = props.getProperty(key);
value = value.replace("\\", "/");
vars.put(key, value);
}

vars.putAll(other.getProperties());
}

@Override
protected String getClearString(String key) {
String value = super.getClearString(key);
if (value != null) {
value = expandProperties(value);
}
return value;
}

/**
* expand properties in string
*/
private String expandProperties(String text) {
Matcher m = regex.matcher(text);
String result = text;
while (m.find()) {
String key = m.group(1);
String value = vars.get(key);
if (value != null) {
result = result.replace(m.group(), value);
}
}
return result;
}

@Override
protected void doOnSetProperty(String key, String value) {
if (value != null) {
vars.put(key, value);
}
}

@Override
protected void doOnRemoveProperty(String key) {
vars.remove(key);
}

@Override
protected void doOnClearProperties() {
vars.clear();
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -56,8 +56,8 @@ public class CxxCompilerSensor extends CxxReportSensor {
/**
* {@inheritDoc}
*/
public CxxCompilerSensor(ResourcePerspectives perspectives, Settings conf, FileSystem fs, RulesProfile profile, ProjectReactor reactor) {
super(perspectives, conf, fs, reactor, CxxMetrics.COMPILER);
public CxxCompilerSensor(ResourcePerspectives perspectives, Settings settings, FileSystem fs, RulesProfile profile, ProjectReactor reactor) {
super(perspectives, settings, fs, reactor, CxxMetrics.COMPILER);
this.profile = profile;

addCompilerParser(new CxxCompilerVcParser());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -80,9 +80,9 @@ public CxxCoverageSensor(Settings settings, FileSystem fs, ProjectReactor reacto
public boolean shouldExecuteOnProject(Project project) {
return fs.hasFiles(fs.predicates().hasLanguage(CxxLanguage.KEY))
&& (isForceZeroCoverageActivated()
|| conf.hasKey(REPORT_PATH_KEY)
|| conf.hasKey(IT_REPORT_PATH_KEY)
|| conf.hasKey(OVERALL_REPORT_PATH_KEY));
|| settings.hasKey(REPORT_PATH_KEY)
|| settings.hasKey(IT_REPORT_PATH_KEY)
|| settings.hasKey(OVERALL_REPORT_PATH_KEY));
}

/**
Expand All @@ -95,29 +95,29 @@ public void analyse(Project project, SensorContext context) {
Map<String, CoverageMeasuresBuilder> itCoverageMeasures = null;
Map<String, CoverageMeasuresBuilder> overallCoverageMeasures = null;

if (conf.hasKey(REPORT_PATH_KEY)) {
if (settings.hasKey(REPORT_PATH_KEY)) {
CxxUtils.LOG.debug("Parsing coverage reports");
List<File> reports = getReports(conf,
List<File> reports = getReports(settings,
reactor.getRoot().getBaseDir().getAbsolutePath(),
fs.baseDir().getPath(),
REPORT_PATH_KEY);
coverageMeasures = processReports(project, context, reports);
saveMeasures(context, coverageMeasures, CoverageType.UT_COVERAGE);
}

if (conf.hasKey(IT_REPORT_PATH_KEY)) {
if (settings.hasKey(IT_REPORT_PATH_KEY)) {
CxxUtils.LOG.debug("Parsing integration test coverage reports");
List<File> itReports = getReports(conf,
List<File> itReports = getReports(settings,
reactor.getRoot().getBaseDir().getAbsolutePath(),
fs.baseDir().getPath(),
IT_REPORT_PATH_KEY);
itCoverageMeasures = processReports(project, context, itReports);
saveMeasures(context, itCoverageMeasures, CoverageType.IT_COVERAGE);
}

if (conf.hasKey(OVERALL_REPORT_PATH_KEY)) {
if (settings.hasKey(OVERALL_REPORT_PATH_KEY)) {
CxxUtils.LOG.debug("Parsing overall test coverage reports");
List<File> overallReports = getReports(conf,
List<File> overallReports = getReports(settings,
reactor.getRoot().getBaseDir().getAbsolutePath(),
fs.baseDir().getPath(),
OVERALL_REPORT_PATH_KEY);
Expand Down Expand Up @@ -198,19 +198,19 @@ private void zeroMeasuresWithoutReports(SensorContext context,
for (InputFile inputFile : inputFiles) {
String filePath = CxxUtils.normalizePath(inputFile.absolutePath());

if (conf.hasKey(REPORT_PATH_KEY)) {
if (settings.hasKey(REPORT_PATH_KEY)) {
if (coverageMeasures == null || coverageMeasures.get(filePath) == null) {
saveZeroValueForResource(inputFile, filePath, context, CoverageType.UT_COVERAGE);
}
}

if (conf.hasKey(IT_REPORT_PATH_KEY)) {
if (settings.hasKey(IT_REPORT_PATH_KEY)) {
if (itCoverageMeasures == null || itCoverageMeasures.get(filePath) == null) {
saveZeroValueForResource(inputFile, filePath, context, CoverageType.IT_COVERAGE);
}
}

if (conf.hasKey(OVERALL_REPORT_PATH_KEY)) {
if (settings.hasKey(OVERALL_REPORT_PATH_KEY)) {
if (overallCoverageMeasures == null || overallCoverageMeasures.get(filePath) == null) {
saveZeroValueForResource(inputFile, filePath, context, CoverageType.OVERALL_COVERAGE);
}
Expand Down Expand Up @@ -307,6 +307,6 @@ private Measure convertForOverall(Measure measure) {
}

private boolean isForceZeroCoverageActivated() {
return conf.getBoolean(FORCE_ZERO_COVERAGE_KEY);
return settings.getBoolean(FORCE_ZERO_COVERAGE_KEY);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -51,9 +51,9 @@ public class CxxCppCheckSensor extends CxxReportSensor {
/**
* {@inheritDoc}
*/
public CxxCppCheckSensor(ResourcePerspectives perspectives, Settings conf, FileSystem fs,
public CxxCppCheckSensor(ResourcePerspectives perspectives, Settings settings, FileSystem fs,
RulesProfile profile, ProjectReactor reactor) {
super(perspectives, conf, fs, reactor, CxxMetrics.CPPCHECK);
super(perspectives, settings, fs, reactor, CxxMetrics.CPPCHECK);
this.profile = profile;
parsers.add(new CppcheckParserV2(this));
parsers.add(new CppcheckParserV1(this));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
import org.sonar.plugins.cxx.utils.CxxUtils;
import org.sonar.squidbridge.rules.SqaleXmlLoader;
import org.sonar.plugins.cxx.utils.CxxSqaleXmlLoader;
import org.sonar.plugins.cxx.CxxSettings;

/**
* Loads the external rules configuration file.
Expand All @@ -38,13 +39,13 @@ public class CxxExternalRuleRepository implements RulesDefinition {
public static final String KEY = "other";
public static final String RULES_KEY = "sonar.cxx.other.rules";
public static final String SQALES_KEY = "sonar.cxx.other.sqales";
public final Settings settings;
public final CxxSettings settings;
private final RulesDefinitionXmlLoader xmlRuleLoader;
private static final String NAME = "Other";

public CxxExternalRuleRepository(RulesDefinitionXmlLoader xmlRuleLoader, Settings settings) {
this.xmlRuleLoader = xmlRuleLoader;
this.settings = settings;
this.settings = new CxxSettings(settings);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,8 +50,8 @@ public class CxxExternalRulesSensor extends CxxReportSensor {
/**
* {@inheritDoc}
*/
public CxxExternalRulesSensor(ResourcePerspectives perspectives, Settings conf, FileSystem fs, RulesProfile profile, ProjectReactor reactor) {
super(perspectives, conf, fs, reactor, CxxMetrics.EXTERNAL);
public CxxExternalRulesSensor(ResourcePerspectives perspectives, Settings settings, FileSystem fs, RulesProfile profile, ProjectReactor reactor) {
super(perspectives, settings, fs, reactor, CxxMetrics.EXTERNAL);
this.profile = profile;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,8 +57,8 @@ public class CxxPCLintSensor extends CxxReportSensor {
/**
* {@inheritDoc}
*/
public CxxPCLintSensor(ResourcePerspectives perspectives, Settings conf, FileSystem fs, RulesProfile profile, ProjectReactor reactor) {
super(perspectives, conf, fs, reactor, CxxMetrics.PCLINT);
public CxxPCLintSensor(ResourcePerspectives perspectives, Settings settings, FileSystem fs, RulesProfile profile, ProjectReactor reactor) {
super(perspectives, settings, fs, reactor, CxxMetrics.PCLINT);
this.profile = profile;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,8 +46,8 @@ public final class CxxRatsSensor extends CxxReportSensor {
/**
* {@inheritDoc}
*/
public CxxRatsSensor(ResourcePerspectives perspectives, Settings conf, FileSystem fs, RulesProfile profile, ProjectReactor reactor) {
super(perspectives, conf, fs, reactor, CxxMetrics.RATS);
public CxxRatsSensor(ResourcePerspectives perspectives, Settings settings, FileSystem fs, RulesProfile profile, ProjectReactor reactor) {
super(perspectives, settings, fs, reactor, CxxMetrics.RATS);
this.profile = profile;
}

Expand Down
Loading