Skip to content

Commit

Permalink
Issue checkstyle#3530: allowed ant to override and swap checker
Browse files Browse the repository at this point in the history
  • Loading branch information
rnveach committed Jan 28, 2017
1 parent 4cff2eb commit 0bac0af
Show file tree
Hide file tree
Showing 4 changed files with 67 additions and 37 deletions.
Expand Up @@ -46,13 +46,15 @@
import com.google.common.io.Closeables;
import com.puppycrawl.tools.checkstyle.Checker;
import com.puppycrawl.tools.checkstyle.ConfigurationLoader;
import com.puppycrawl.tools.checkstyle.DefaultContext;
import com.puppycrawl.tools.checkstyle.DefaultLogger;
import com.puppycrawl.tools.checkstyle.ModuleFactory;
import com.puppycrawl.tools.checkstyle.PackageObjectFactory;
import com.puppycrawl.tools.checkstyle.PropertiesExpander;
import com.puppycrawl.tools.checkstyle.XMLLogger;
import com.puppycrawl.tools.checkstyle.api.AuditListener;
import com.puppycrawl.tools.checkstyle.api.CheckstyleException;
import com.puppycrawl.tools.checkstyle.api.Configuration;
import com.puppycrawl.tools.checkstyle.api.RootModule;
import com.puppycrawl.tools.checkstyle.api.SeverityLevel;
import com.puppycrawl.tools.checkstyle.api.SeverityLevelCounter;

Expand Down Expand Up @@ -262,7 +264,7 @@ public void setOmitIgnoredModules(boolean omit) {
}

////////////////////////////////////////////////////////////////////////////
// Setters for Checker configuration attributes
// Setters for Root Module's configuration attributes
////////////////////////////////////////////////////////////////////////////

/**
Expand Down Expand Up @@ -316,45 +318,45 @@ public void execute() {
* @param checkstyleVersion Checkstyle compile version.
*/
private void realExecute(String checkstyleVersion) {
// Create the checker
Checker checker = null;
// Create the root module
RootModule rootModule = null;
try {
checker = createChecker();
rootModule = createRootModule();

// setup the listeners
final AuditListener[] listeners = getListeners();
for (AuditListener element : listeners) {
checker.addListener(element);
rootModule.addListener(element);
}
final SeverityLevelCounter warningCounter =
new SeverityLevelCounter(SeverityLevel.WARNING);
checker.addListener(warningCounter);
rootModule.addListener(warningCounter);

processFiles(checker, warningCounter, checkstyleVersion);
processFiles(rootModule, warningCounter, checkstyleVersion);
}
finally {
destroyChecker(checker);
destroyRootModule(rootModule);
}
}

/**
* Destroy Checker. This method exists only due to bug in cobertura library
* Destroy root module. This method exists only due to bug in cobertura library
* https://github.com/cobertura/cobertura/issues/170
* @param checker Checker that was used to process files
* @param rootModule Root module that was used to process files
*/
private static void destroyChecker(Checker checker) {
if (checker != null) {
checker.destroy();
private static void destroyRootModule(RootModule rootModule) {
if (rootModule != null) {
rootModule.destroy();
}
}

/**
* Scans and processes files by means given checker.
* @param checker Checker to process files
* @param warningCounter Checker's counter of warnings
* Scans and processes files by means given root module.
* @param rootModule Root module to process files
* @param warningCounter Root Module's counter of warnings
* @param checkstyleVersion Checkstyle compile version
*/
private void processFiles(Checker checker, final SeverityLevelCounter warningCounter,
private void processFiles(RootModule rootModule, final SeverityLevelCounter warningCounter,
final String checkstyleVersion) {
final long startTime = System.currentTimeMillis();
final List<File> files = scanFileSets();
Expand All @@ -370,7 +372,7 @@ private void processFiles(Checker checker, final SeverityLevelCounter warningCou

try {
final long processingStartTime = System.currentTimeMillis();
numErrs = checker.process(files);
numErrs = rootModule.process(files);
final long processingEndTime = System.currentTimeMillis();
log("To process the files took " + (processingEndTime - processingStartTime)
+ TIME_SUFFIX, Project.MSG_VERBOSE);
Expand All @@ -397,11 +399,11 @@ private void processFiles(Checker checker, final SeverityLevelCounter warningCou
}

/**
* Creates new instance of {@code Checker}.
* @return new instance of {@code Checker}
* Creates new instance of the root module.
* @return new instance of the root module
*/
private Checker createChecker() {
final Checker checker;
private RootModule createRootModule() {
final RootModule rootModule;
try {
final Properties props = createOverridingProperties();
final Configuration config =
Expand All @@ -410,24 +412,29 @@ private Checker createChecker() {
new PropertiesExpander(props),
omitIgnoredModules);

final DefaultContext context = new DefaultContext();
final ClassLoader loader = new AntClassLoader(getProject(),
classpath);
context.add("classloader", loader);

final ClassLoader moduleClassLoader =
Checker.class.getClassLoader();
context.add("moduleClassLoader", moduleClassLoader);

checker = new Checker();
checker.contextualize(context);
checker.configure(config);
final ModuleFactory factory = new PackageObjectFactory(
Checker.class.getPackage().getName() + ".", moduleClassLoader);

rootModule = (RootModule) factory.createModule(config.getName());
rootModule.setModuleClassLoader(moduleClassLoader);

if (rootModule instanceof Checker) {
final ClassLoader loader = new AntClassLoader(getProject(),
classpath);

((Checker) rootModule).setClassLoader(loader);
}

rootModule.configure(config);
}
catch (final CheckstyleException ex) {
throw new BuildException(String.format(Locale.ROOT, "Unable to create a Checker: "
throw new BuildException(String.format(Locale.ROOT, "Unable to create Root Module: "
+ "configLocation {%s}, classpath {%s}.", configLocation, classpath), ex);
}
return checker;
return rootModule;
}

/**
Expand Down
2 changes: 2 additions & 0 deletions src/test/java/com/puppycrawl/tools/checkstyle/MainTest.java
Expand Up @@ -802,6 +802,8 @@ public void testExcludeDirectoryNotMatch() throws Exception {

@Test
public void testCustomRootModule() throws Exception {
TestRootModuleChecker.reset();

exit.checkAssertionAfterwards(() -> {
assertEquals("", systemOut.getLog());
assertEquals("", systemErr.getLog());
Expand Down
Expand Up @@ -59,4 +59,8 @@ public void setModuleClassLoader(ClassLoader moduleClassLoader) {
public static boolean isProcessed() {
return processed;
}

public static void reset() {
processed = false;
}
}
Expand Up @@ -42,19 +42,25 @@

import com.puppycrawl.tools.checkstyle.BaseCheckTestSupport;
import com.puppycrawl.tools.checkstyle.DefaultLogger;
import com.puppycrawl.tools.checkstyle.TestRootModuleChecker;
import com.puppycrawl.tools.checkstyle.XMLLogger;

public class CheckstyleAntTaskTest extends BaseCheckTestSupport {

private static final String FLAWLESS_INPUT = "ant/InputCheckstyleAntTaskFlawless.java";
private static final String VIOLATED_INPUT = "ant/InputCheckstyleAntTaskError.java";
private static final String CONFIG_FILE = "ant/ant_task_test_checks.xml";
private static final String CUSTOM_ROOT_CONFIG_FILE = "config-custom-root-module.xml";
private static final String NOT_EXISTING_FILE = "target/not_existing.xml";
private static final String FAILURE_PROPERTY_VALUE = "myValue";

private CheckstyleAntTask getCheckstyleAntTask() throws IOException {
return getCheckstyleAntTask(CONFIG_FILE);
}

private CheckstyleAntTask getCheckstyleAntTask(String configFile) throws IOException {
final CheckstyleAntTask antTask = new CheckstyleAntTask();
antTask.setConfig(new File(getPath(CONFIG_FILE)));
antTask.setConfig(new File(getPath(configFile)));
antTask.setProject(new Project());
return antTask;
}
Expand All @@ -66,6 +72,17 @@ public final void testDefaultFlawless() throws IOException {
antTask.execute();
}

@Test
public final void testCustomRootModule() throws IOException {
TestRootModuleChecker.reset();

final CheckstyleAntTask antTask = getCheckstyleAntTask(CUSTOM_ROOT_CONFIG_FILE);
antTask.setFile(new File(getPath(FLAWLESS_INPUT)));
antTask.execute();

assertTrue(TestRootModuleChecker.isProcessed());
}

@Test
public final void testFileSet() throws IOException {
final CheckstyleAntTask antTask = getCheckstyleAntTask();
Expand Down Expand Up @@ -100,7 +117,7 @@ public final void testNonExistingConfig() throws IOException {
fail("Exception is expected");
}
catch (BuildException ex) {
assertTrue(ex.getMessage().startsWith("Unable to create a Checker: configLocation"));
assertTrue(ex.getMessage().startsWith("Unable to create Root Module: configLocation"));
}
}

Expand All @@ -115,7 +132,7 @@ public final void testEmptyConfigFile() throws IOException {
fail("Exception is expected");
}
catch (BuildException ex) {
assertTrue(ex.getMessage().startsWith("Unable to create a Checker: configLocation"));
assertTrue(ex.getMessage().startsWith("Unable to create Root Module: configLocation"));
}
}

Expand Down

0 comments on commit 0bac0af

Please sign in to comment.