Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
support hierarchial configurations
  • Loading branch information
ryaneberly committed Jan 8, 2017
1 parent e45d61c commit d152736
Show file tree
Hide file tree
Showing 84 changed files with 1,946 additions and 2,191 deletions.
31 changes: 26 additions & 5 deletions src/main/java/com/cflint/CFLint.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.StringReader;
import java.util.ArrayList;
Expand All @@ -12,6 +14,8 @@
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import javax.xml.bind.JAXBException;

import org.antlr.runtime.BitSet;
import org.antlr.runtime.IntStream;
import org.antlr.runtime.RecognitionException;
Expand All @@ -23,6 +27,7 @@

import com.cflint.BugInfo.BugInfoBuilder;
import com.cflint.config.CFLintConfig;
import com.cflint.config.CFLintConfiguration;
import com.cflint.config.CFLintPluginInfo;
import com.cflint.config.CFLintPluginInfo.PluginInfoRule;
import com.cflint.config.CFLintPluginInfo.PluginInfoRule.PluginMessage;
Expand Down Expand Up @@ -97,13 +102,14 @@ public class CFLint implements IErrorReporter {
final List<ScanProgressListener> scanProgressListeners = new ArrayList<ScanProgressListener>();
final List<CFLintExceptionListener> exceptionListeners = new ArrayList<CFLintExceptionListener>();

ConfigRuntime configuration;
CFLintConfiguration configuration;

public CFLint(final CFLintConfig configFile) throws IOException {
public CFLint(final CFLintConfiguration configFile) throws IOException {
final CFLintPluginInfo pluginInfo = ConfigUtils.loadDefaultPluginInfo();
configuration = new ConfigRuntime(configFile, pluginInfo);
//configuration = new ConfigRuntime(configFile, pluginInfo);
configuration =configFile==null?new CFLintConfig():configFile;
for (final PluginInfoRule ruleInfo : configuration.getRules()) {
addScanner(ConfigUtils.loadPlugin(ruleInfo));
addScanner(ConfigUtils.loadPlugin(ruleInfo));//TODO load them all
}
final CFLintFilter filter = CFLintFilter.createFilter(verbose);
bugs = new BugList(filter);
Expand All @@ -115,7 +121,7 @@ public CFLint(final CFLintConfig configFile) throws IOException {
}

@Deprecated
public CFLint(final ConfigRuntime configuration, final CFLintScanner... bugsScanners) {
public CFLint(final CFLintConfiguration configuration, final CFLintScanner... bugsScanners) {
super();
this.configuration = configuration;

Expand Down Expand Up @@ -155,9 +161,24 @@ public void scan(final File folderOrFile) {
return;
}
if (folderOrFile.isDirectory()) {
boolean newConfigFlag = false;
for (final File file : folderOrFile.listFiles()) {
if(file.getName().equalsIgnoreCase(".cflintrc.xml")){
try {
CFLintConfiguration newConfig = com.cflint.config.ConfigUtils.unmarshal(new FileInputStream(file), CFLintConfig.class);
System.out.println("read config " + file);
newConfigFlag =true;
} catch (Exception e) {
System.err.println("Could not read config file " + file);
}
}
}
for (final File file : folderOrFile.listFiles()) {
scan(file);
}
if(newConfigFlag){
//TODO unwrap
}
} else if (!folderOrFile.isHidden() && FileUtil.checkExtension(folderOrFile, allowedExtensions)) {
final String src = FileUtil.loadFile(folderOrFile);
try {
Expand Down
33 changes: 19 additions & 14 deletions src/main/java/com/cflint/ant/CFLintTask.java
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,9 @@
import com.cflint.TextOutput;
import com.cflint.XMLOutput;
import com.cflint.config.CFLintConfig;
import com.cflint.config.CFLintConfiguration;
import com.cflint.config.ConfigUtils;
import com.cflint.config.CFLintPluginInfo.PluginInfoRule.PluginMessage;
import com.cflint.tools.CFLintFilter;
import com.cflint.xml.stax.DefaultCFlintResultMarshaller;

Expand All @@ -51,15 +53,29 @@ public class CFLintTask extends Task {
public void execute() {
FileInputStream fis = null;
try {
CFLintConfig config = null;
CFLintConfiguration config = null;
if (configFile != null) {
if (configFile.getName().toLowerCase().endsWith(".xml")) {
config = ConfigUtils.unmarshal(new FileInputStream(configFile), CFLintConfig.class);
} else {
config = ConfigUtils.unmarshalJson(new FileInputStream(configFile), CFLintConfig.class);
}
}

CFLintConfiguration cmdLineConfig = null;
if ((excludeRule != null && excludeRule.trim().length() > 0) || (includeRule != null && includeRule.trim().length() > 0)) {
cmdLineConfig=new CFLintConfig();
if (includeRule != null && includeRule.trim().length() > 0) {
for(final String code: includeRule.trim().split(",")){
cmdLineConfig.addInclude(new PluginMessage(code));
}
}
if (excludeRule != null && excludeRule.trim().length() > 0) {
for(final String code: excludeRule.trim().split(",")){
cmdLineConfig.addExclude(new PluginMessage(code));
}
}
}
//TODO combine configs
final CFLint cflint = new CFLint(config);
cflint.setVerbose(verbose);
cflint.setQuiet(quiet);
Expand All @@ -76,18 +92,7 @@ public void execute() {
filter = CFLintFilter.createFilter(new String(b), verbose);
}
}
if (excludeRule != null && excludeRule.trim().length() > 0) {
final String[] excludeCodes = excludeRule.split(",");
if (excludeCodes != null && excludeCodes.length > 0) {
filter.excludeCode(excludeCodes);
}
}
if (includeRule != null && includeRule.trim().length() > 0) {
final String[] includeCodes = includeRule.split(",");
if (includeCodes != null && includeCodes.length > 0) {
filter.excludeCode(includeCodes);
}
}

cflint.getBugs().setFilter(filter);
if (xmlFile == null && htmlFile == null && textFile == null) {
xmlFile = new File("cflint-result.xml");
Expand Down
80 changes: 69 additions & 11 deletions src/main/java/com/cflint/config/CFLintChainedConfig.java
Original file line number Diff line number Diff line change
@@ -1,39 +1,97 @@
package com.cflint.config;

import java.util.Collection;
import java.util.HashSet;

import com.cflint.config.CFLintPluginInfo.PluginInfoRule;
import com.cflint.config.CFLintPluginInfo.PluginInfoRule.PluginMessage;
import com.cflint.plugins.CFLintScanner;

public class CFLintChainedConfig {
public class CFLintChainedConfig implements CFLintConfiguration{

final CFLintConfig config;
final CFLintChainedConfig parent;

public CFLintChainedConfig(CFLintConfig config) {
public CFLintChainedConfig(CFLintConfiguration config) {
super();
this.config = config;
this.config = (CFLintConfig)config;
parent = null;
}
public CFLintChainedConfig(CFLintConfig config,CFLintChainedConfig parent) {
public CFLintChainedConfig(CFLintConfiguration config,CFLintChainedConfig parent) {
super();
this.config = config;
this.config = (CFLintConfig)config;
this.parent = parent;
}

public CFLintChainedConfig createNestedConfig(CFLintConfig config){
return new CFLintChainedConfig(config,this);
/**
* Create a nested configuration.
* @param config
* @return
*/
public CFLintChainedConfig createNestedConfig(CFLintConfiguration config){
return config==null?this:new CFLintChainedConfig(config,this);
}

public boolean includes(PluginMessage pluginMessage) {
return config.includes(pluginMessage) ||
(config.isInheritParent() && parent!=null && parent.includes(pluginMessage));
}

public Object excludes(PluginMessage pluginMessage) {
return config.includes(pluginMessage) ||
(config.isInheritParent() && parent!=null && parent.includes(pluginMessage));
public boolean excludes(PluginMessage pluginMessage) {
return config.excludes(pluginMessage) ||
(config.isInheritParent() && parent!=null && parent.excludes(pluginMessage));
}

public CFLintChainedConfig getParent() {
return parent;
}

@Override
public PluginInfoRule getRuleByClass(Class<?> clazz) {
PluginInfoRule retval = config.getRuleByClass(clazz);
if(retval !=null || parent == null){
return retval;
}
return parent.getRuleByClass(clazz);
}
@Override
public PluginInfoRule getRuleForPlugin(CFLintScanner plugin) {
PluginInfoRule retval = config.getRuleForPlugin(plugin);
if(retval !=null || parent == null){
return retval;
}
return parent.getRuleForPlugin(plugin);
}
@Override
public void addInclude(PluginMessage pluginMessage) {
config.addInclude(pluginMessage);
}

@Override
public void addExclude(PluginMessage pluginMessage) {
config.addExclude(pluginMessage);
}
@Override
public Collection<PluginInfoRule> getRules() {
final HashSet<PluginInfoRule> activeRules = new HashSet<PluginInfoRule>();
for(PluginInfoRule rule:getAllRules()){
for(PluginMessage pluginMessage:rule.getMessages()){
if(includes(pluginMessage) && !excludes(pluginMessage)){
activeRules.add(rule);
break;
}
}
}
return activeRules;
}

public Collection<PluginInfoRule> getAllRules() {
if(parent==null || !config.isInheritPlugins()){
return config.getRules();
}
final HashSet<PluginInfoRule> retval = new HashSet<PluginInfoRule>(parent.getAllRules());
//Override any rules from the parent configuration
retval.addAll(config.getRules());
return retval;

}
}
77 changes: 76 additions & 1 deletion src/main/java/com/cflint/config/CFLintConfig.java
Original file line number Diff line number Diff line change
Expand Up @@ -12,15 +12,21 @@
import com.cflint.plugins.CFLintScanner;

@XmlRootElement(name = "config")
public class CFLintConfig {
public class CFLintConfig implements CFLintConfiguration {



List<ConfigOutput> output = new ArrayList<CFLintConfig.ConfigOutput>();
List<CFLintPluginInfo.PluginInfoRule> rules = new ArrayList<CFLintPluginInfo.PluginInfoRule>();
List<PluginMessage> excludes = new ArrayList<PluginMessage>();
List<PluginMessage> includes = new ArrayList<PluginMessage>();

private boolean inheritParent = true;
private boolean inheritPlugins = true;

/* (non-Javadoc)
* @see com.cflint.config.CFLintConfiguration#getOutput()
*/
public List<ConfigOutput> getOutput() {
return output;
}
Expand All @@ -30,6 +36,9 @@ public void setOutput(final List<ConfigOutput> output) {
this.output = output;
}

/* (non-Javadoc)
* @see com.cflint.config.CFLintConfiguration#getRules()
*/
public List<CFLintPluginInfo.PluginInfoRule> getRules() {
return rules;
}
Expand All @@ -39,6 +48,9 @@ public void setRules(final List<CFLintPluginInfo.PluginInfoRule> rules) {
this.rules = rules;
}

/* (non-Javadoc)
* @see com.cflint.config.CFLintConfiguration#getExcludes()
*/
public List<PluginMessage> getExcludes() {
return excludes;
}
Expand All @@ -48,6 +60,9 @@ public void setExcludes(final List<PluginMessage> excludes) {
this.excludes = excludes;
}

/* (non-Javadoc)
* @see com.cflint.config.CFLintConfiguration#getIncludes()
*/
public List<PluginMessage> getIncludes() {
return includes;
}
Expand All @@ -66,6 +81,15 @@ public void setInheritParent(boolean inheritParent) {
this.inheritParent = inheritParent;
}

public boolean isInheritPlugins() {
return inheritPlugins;
}

@XmlAttribute(name = "inheritPlugins")
public void setInheritPlugins(boolean inheritPlugins) {
this.inheritPlugins = inheritPlugins;
}

public static class ConfigOutput {

String name;
Expand Down Expand Up @@ -146,14 +170,26 @@ public void setStyle(final String style) {
}
}

/* (non-Javadoc)
* @see com.cflint.config.CFLintConfiguration#includes(com.cflint.config.CFLintPluginInfo.PluginInfoRule.PluginMessage)
*/
@Override
public boolean includes(PluginMessage pluginMessage) {
return (getIncludes().isEmpty() || getIncludes().contains(pluginMessage));
}

/* (non-Javadoc)
* @see com.cflint.config.CFLintConfiguration#excludes(com.cflint.config.CFLintPluginInfo.PluginInfoRule.PluginMessage)
*/
@Override
public boolean excludes(PluginMessage pluginMessage) {
return (!getExcludes().isEmpty() && getExcludes().contains(pluginMessage));
}

/* (non-Javadoc)
* @see com.cflint.config.CFLintConfiguration#getRuleByClass(java.lang.Class)
*/
@Override
public PluginInfoRule getRuleByClass(final Class<?> clazz) {
final String className = clazz.getSimpleName();
for (final PluginInfoRule rule : getRules()) {
Expand All @@ -164,6 +200,10 @@ public PluginInfoRule getRuleByClass(final Class<?> clazz) {
return null;
}

/* (non-Javadoc)
* @see com.cflint.config.CFLintConfiguration#getRuleForPlugin(com.cflint.plugins.CFLintScanner)
*/
@Override
public PluginInfoRule getRuleForPlugin(final CFLintScanner plugin) {
for (final PluginInfoRule rule : getRules()) {
if (rule.getPluginInstance() == plugin) {
Expand All @@ -172,4 +212,39 @@ public PluginInfoRule getRuleForPlugin(final CFLintScanner plugin) {
}
return getRuleByClass(plugin.getClass());
}

@Override
public void addInclude(PluginMessage pluginMessage) {
includes.add(pluginMessage);
}

@Override
public void addExclude(PluginMessage pluginMessage) {
excludes.add(pluginMessage);
}

public static CFLintConfiguration createDefault(){
final CFLintPluginInfo pluginInfo = ConfigUtils.loadDefaultPluginInfo();
CFLintConfig defaultConfig = new CFLintConfig();
defaultConfig.setRules(pluginInfo.getRules());
return defaultConfig;
}

/**
* Limit the rule set, primarily for unit test support
* @param rulename
*/
public static CFLintConfiguration createDefaultLimited(String ... rulenames){
final CFLintPluginInfo pluginInfo = ConfigUtils.loadDefaultPluginInfo();
CFLintConfig defaultConfig = new CFLintConfig();
for(CFLintPluginInfo.PluginInfoRule rule:pluginInfo.getRules()){
for(String rulename:rulenames){
if(rule.getName().equalsIgnoreCase(rulename)){
defaultConfig.getRules().add(rule);
}
}
}
return defaultConfig;
}

}
Loading

0 comments on commit d152736

Please sign in to comment.