Skip to content
Permalink
Browse files

[JENKINS-42268] CyclomaticComplexity lint defect initial approach

  • Loading branch information
v1v committed Feb 27, 2017
1 parent 266f27b commit 1c66f0c0d3329cf80591d3bbe1a81b4ba03b0950
@@ -0,0 +1,107 @@
package org.jenkins.ci.plugins.jenkinslint.check;

import hudson.matrix.MatrixProject;
import hudson.maven.MavenModuleSet;
import hudson.model.Item;
import hudson.model.Project;
import hudson.tasks.Builder;
import jenkins.model.Jenkins;
import org.jenkins.ci.plugins.jenkinslint.model.AbstractCheck;

import java.util.List;
import java.util.logging.Level;

/**
* @author Victor Martinez
*/
public class CyclomaticComplexityChecker extends AbstractCheck {

private final int THRESHOLD = 4;

public CyclomaticComplexityChecker() {
super();
this.setDescription(Messages.CyclometicComplexityCheckerDesc());
this.setSeverity(Messages.CyclometicComplexityCheckerSeverity());
}

public boolean executeCheck(Item item) {
boolean found = false;
if (Jenkins.getInstance().pluginManager.getPlugin("conditional-buildstep") != null) {

int cyclomatic = 0;
if (Jenkins.getInstance().pluginManager.getPlugin("maven-plugin") != null) {
if (item instanceof MavenModuleSet) {
cyclomatic = totalCyclomatic(((MavenModuleSet) item).getPrebuilders());
found = cyclomatic > THRESHOLD;
}
}
if (item instanceof Project) {
cyclomatic = totalCyclomatic(((Project) item).getBuilders());
found = cyclomatic > THRESHOLD;
}
if (item instanceof MatrixProject) {
cyclomatic = totalCyclomatic(((MatrixProject) item).getBuilders());
found = cyclomatic > THRESHOLD;
}

LOG.log(Level.INFO, "Cyclomatic complexity of " + item.getName() + " is " + cyclomatic);

} else {
LOG.log(Level.INFO, "Conditional BuildStep plugin is not installed");
}
return found;
}

private int totalCyclomatic(List<Builder> builders) {
int cyclomatic = 0;
if (builders != null && builders.size() > 0 ) {
for (Builder builder : builders) {
if (builder.getClass().getName().endsWith("ConditionalBuilder")) {
cyclomatic += cyclomatic(builder, 0);
}
}
}
return cyclomatic;
}

private int conditionalCyclomatic(Object builder) {
int cyclomatic = 0;
try {
Object getConditionalbuilders = builder.getClass().getMethod("getConditionalbuilders", null).invoke(builder);
if (getConditionalbuilders instanceof List) {
for (Object conditional : ((List) getConditionalbuilders)) {
cyclomatic += cyclomatic(conditional, 0);
}
}
} catch (Exception e) {
LOG.log(Level.WARNING, "Exception " + e.getMessage(), e.getCause());
cyclomatic = 0;
}
return cyclomatic;
}

private int cyclomatic(Object builder, int cyclomatic) {
try {
Object runCondition = builder.getClass().getMethod("getRunCondition", null).invoke(builder);
switch (runCondition.getClass().getSimpleName()) {
case "And":
cyclomatic += conditionalCyclomatic(builder);
break;
case "Or":
cyclomatic += conditionalCyclomatic(builder);
break;
case "Not":
cyclomatic += conditionalCyclomatic(builder);
break;
default:
cyclomatic++;
break;
}
} catch (Exception e) {
LOG.log(Level.WARNING, "Exception " + e.getMessage(), e.getCause());
}
return cyclomatic;
}


}
@@ -12,6 +12,12 @@ BFACheckerDesc=\

BFACheckerSeverity=Low

CyclometicComplexityCheckerDesc=\
Cyclomatic Complexity in Jenkins job over 5 indicates a higher complexity. \
<br/>It's recommended to simplify those jenkins jobs by splitting them for instance..\
CyclometicComplexityCheckerSeverity=High
CleanupWorkspaceCheckerDesc=\
There are some builds which demand a lot of disc space. Some builds \
might run out of space during the build itself and cause build errors. \

0 comments on commit 1c66f0c

Please sign in to comment.
You can’t perform that action at this time.