Skip to content

Commit

Permalink
Fix #57. Implement Worker API support.
Browse files Browse the repository at this point in the history
 - Remove dead code
 - Fix javadoc warning

Signed-off-by: Kyle Moore <[email protected]>
  • Loading branch information
DPUkyle authored and KengoTODA committed Oct 10, 2018
1 parent 6089caf commit a0ceea6
Show file tree
Hide file tree
Showing 10 changed files with 193 additions and 143 deletions.
1 change: 1 addition & 0 deletions src/main/java/com/github/spotbugs/SpotBugsExtension.java
Original file line number Diff line number Diff line change
Expand Up @@ -305,6 +305,7 @@ public boolean isShowProgress() {
/**
* Indicates whether analysis progress should be rendered on standard output.
*
* @param showProgress Whether progress should be rendered on standard output.
*/
public void setShowProgress(boolean showProgress) {
this.showProgress = showProgress;
Expand Down
2 changes: 0 additions & 2 deletions src/main/java/com/github/spotbugs/SpotBugsPlugin.java
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,9 @@
import java.util.concurrent.Callable;
import java.util.stream.StreamSupport;

import org.gradle.api.InvalidUserDataException;
import org.gradle.api.Project;
import org.gradle.api.artifacts.Configuration;
import org.gradle.api.artifacts.DependencySet;
import org.gradle.api.file.ConfigurableFileTree;
import org.gradle.api.file.FileCollection;
import org.gradle.api.internal.ConventionMapping;
import org.gradle.api.plugins.quality.CodeQualityExtension;
Expand Down
108 changes: 42 additions & 66 deletions src/main/java/com/github/spotbugs/SpotBugsTask.java
Original file line number Diff line number Diff line change
@@ -1,23 +1,18 @@
package com.github.spotbugs;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.stream.Collectors;

import javax.inject.Inject;

import com.github.spotbugs.internal.SpotBugsReportsImpl;
import com.github.spotbugs.internal.SpotBugsReportsInternal;
import com.github.spotbugs.internal.spotbugs.SpotBugsClasspathValidator;
import com.github.spotbugs.internal.spotbugs.SpotBugsRunner;
import com.github.spotbugs.internal.spotbugs.SpotBugsSpec;
import com.github.spotbugs.internal.spotbugs.SpotBugsSpecBuilder;
import groovy.lang.Closure;
import org.gradle.api.Action;
import org.gradle.api.GradleException;
import org.gradle.api.Incubating;
import org.gradle.api.JavaVersion;
import org.gradle.api.file.FileCollection;
import org.gradle.api.file.FileTree;
import org.gradle.api.logging.LogLevel;
import org.gradle.api.reporting.Reporting;
import org.gradle.api.reporting.SingleFileReport;
import org.gradle.api.resources.TextResource;
import org.gradle.api.tasks.CacheableTask;
import org.gradle.api.tasks.Classpath;
Expand All @@ -32,20 +27,19 @@
import org.gradle.api.tasks.SourceTask;
import org.gradle.api.tasks.TaskAction;
import org.gradle.api.tasks.VerificationTask;
import org.gradle.internal.logging.ConsoleRenderer;
import org.gradle.internal.reflect.Instantiator;
import org.gradle.process.internal.worker.WorkerProcessFactory;
import org.gradle.util.ConfigureUtil;
import org.gradle.util.GradleVersion;
import org.gradle.workers.ForkMode;
import org.gradle.workers.IsolationMode;
import org.gradle.workers.WorkerExecutor;

import com.github.spotbugs.internal.SpotBugsReportsImpl;
import com.github.spotbugs.internal.SpotBugsReportsInternal;
import com.github.spotbugs.internal.spotbugs.SpotBugsClasspathValidator;
import com.github.spotbugs.internal.spotbugs.SpotBugsResult;
import com.github.spotbugs.internal.spotbugs.SpotBugsSpec;
import com.github.spotbugs.internal.spotbugs.SpotBugsSpecBuilder;
import com.github.spotbugs.internal.spotbugs.SpotBugsWorkerManager;
import javax.inject.Inject;
import java.io.File;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.stream.Collectors;

import groovy.lang.Closure;

/**
* Analyzes code with <a href="https://spotbugs.github.io/">SpotBugs</a>. See the
Expand Down Expand Up @@ -89,18 +83,22 @@ public class SpotBugsTask extends SourceTask implements VerificationTask, Report
@Nested
private final SpotBugsReportsInternal reports;

public SpotBugsTask() {
reports = getInstantiator().newInstance(SpotBugsReportsImpl.class, this);
}

@Inject
public Instantiator getInstantiator() {
throw new UnsupportedOperationException();
public SpotBugsTask(WorkerExecutor workerExecutor) {
super();
this.workerExecutor = workerExecutor;
if(GradleVersion.current().compareTo(GRADLE_42()) < 0) {
reports = new SpotBugsReportsImpl(this);
} else {
//ObjectFactory#newInstance was introduced in Gradle 4.2
reports = getProject().getObjects().newInstance(SpotBugsReportsImpl.class, this);
}
}

@Inject
public WorkerProcessFactory getWorkerProcessBuilderFactory() {
throw new UnsupportedOperationException();
private final WorkerExecutor workerExecutor;

private GradleVersion GRADLE_42() {
return GradleVersion.version("4.2");
}

/**
Expand Down Expand Up @@ -225,17 +223,22 @@ public void setExcludeBugsFilter(File filter) {
}

@TaskAction
public void run() throws IOException, InterruptedException {
public void run() {
new SpotBugsClasspathValidator(JavaVersion.current()).validateClasspath(
getSpotbugsClasspath().getFiles().stream().map(File::getName).collect(Collectors.toSet()));
SpotBugsSpec spec = generateSpec();
SpotBugsWorkerManager manager = new SpotBugsWorkerManager();

getLogging().captureStandardOutput(LogLevel.DEBUG);
getLogging().captureStandardError(LogLevel.DEBUG);

SpotBugsResult result = manager.runWorker(getProject().getProjectDir(), getWorkerProcessBuilderFactory(), getSpotbugsClasspath(), spec);
evaluateResult(result);
workerExecutor.submit(SpotBugsRunner.class, config -> {
config.params(spec, getIgnoreFailures(), reports.getFirstEnabled().getDestination());
config.setClasspath(getSpotbugsClasspath());
config.setForkMode(ForkMode.ALWAYS);
config.forkOptions( options -> {
options.setDebug(spec.isDebugEnabled());
options.setJvmArgs(spec.getJvmArgs());
options.setMaxHeapSize(spec.getMaxHeapSize());
});
config.setIsolationMode(IsolationMode.PROCESS);
});
}

SpotBugsSpec generateSpec() {
Expand All @@ -260,33 +263,6 @@ SpotBugsSpec generateSpec() {
return specBuilder.build();
}

void evaluateResult(SpotBugsResult result) {
if (result.getException() != null) {
throw new GradleException("SpotBugs encountered an error. Run with --debug to get more information.", result.getException());
}

if (result.getErrorCount() > 0) {
throw new GradleException("SpotBugs encountered an error. Run with --debug to get more information.");
}

if (result.getBugCount() > 0) {
String message = "SpotBugs rule violations were found.";
SingleFileReport report = reports.getFirstEnabled();
if (report != null) {
String reportUrl = new ConsoleRenderer().asClickableFileUrl(report.getDestination());
message += " See the report at: " + reportUrl;
}

if (getIgnoreFailures()) {
getLogger().warn(message);
} else {
throw new GradleException(message);
}

}

}

public SpotBugsTask extraArgs(Iterable<String> arguments) {
for (String argument : arguments) {
extraArgs.add(argument);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.github.spotbugs.internal;

import javax.inject.Inject;
import org.gradle.api.Task;
import org.gradle.api.reporting.SingleFileReport;
import org.gradle.api.reporting.internal.CustomizableHtmlReportImpl;
Expand All @@ -11,6 +12,7 @@

public class SpotBugsReportsImpl extends TaskReportContainer<SingleFileReport> implements SpotBugsReportsInternal {

@Inject
public SpotBugsReportsImpl(Task task) {
super(SingleFileReport.class, task);

Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
package com.github.spotbugs.internal.spotbugs;

import edu.umd.cs.findbugs.FindBugs;
import edu.umd.cs.findbugs.FindBugs2;
import edu.umd.cs.findbugs.IFindBugsEngine;
import edu.umd.cs.findbugs.TextUICommandLine;
import java.io.File;
import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.List;
import javax.inject.Inject;
import org.gradle.api.GradleException;


public class SpotBugsRunner implements Runnable {
private final SpotBugsSpec spec;
private final boolean ignoreFailures;
private final File report;

@Inject
SpotBugsRunner(SpotBugsSpec spec, boolean ignoreFailures, File report) {
this.spec = spec;
this.ignoreFailures = ignoreFailures;
this.report = report;
}

@Override
public void run() {
final ClassLoader contextClassLoader = Thread.currentThread().getContextClassLoader();
try {
final List<String> args = spec.getArguments();
String[] strArray = args.toArray(new String[0]);

Thread.currentThread().setContextClassLoader(FindBugs2.class.getClassLoader());
FindBugs2 findBugs2 = new FindBugs2();
TextUICommandLine commandLine = new TextUICommandLine();

FindBugs.processCommandLine(commandLine, strArray, findBugs2);
findBugs2.execute();

SpotBugsResult result = createSpotbugsResult(findBugs2);
evaluateResult(result);
} catch (IOException | InterruptedException e) {
throw new GradleException("Error initializing SpotBugsRunner", e);
} finally {
Thread.currentThread().setContextClassLoader(contextClassLoader);
}
}

SpotBugsResult createSpotbugsResult(IFindBugsEngine findBugs) {
int bugCount = findBugs.getBugCount();
int missingClassCount = findBugs.getMissingClassCount();
int errorCount = findBugs.getErrorCount();
return new SpotBugsResult(bugCount, missingClassCount, errorCount);
}

void evaluateResult(SpotBugsResult result) {
if (result.getException() != null) {
throw new GradleException("SpotBugs encountered an error. Run with --debug to get more information.", result.getException());
}

if (result.getErrorCount() > 0) {
throw new GradleException("SpotBugs encountered an error. Run with --debug to get more information.");
}

if (result.getBugCount() > 0) {
String message = "SpotBugs rule violations were found.";

if (report != null) {
String reportUrl = asClickableFileUrl(report);
message += " See the report at: " + reportUrl;
}

if (ignoreFailures) {
System.out.println(message);
} else {
throw new GradleException(message);
}

}
}

private String asClickableFileUrl(File file) {
try {
return new URI("file", "", file.toURI().getPath(), null, null).toString();
} catch (URISyntaxException e) {
throw new GradleException("Unable to parse path to destination file", e);
}
}

}

This file was deleted.

This file was deleted.

Loading

0 comments on commit a0ceea6

Please sign in to comment.