package org.infernus.idea.checkstyle.build;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.Properties;
import java.util.Set;
import java.util.TreeSet;
import groovy.lang.Closure;
import org.apache.commons.io.FileUtils;
import org.gradle.api.DefaultTask;
import org.gradle.api.GradleException;
import org.gradle.api.Project;
import org.gradle.api.artifacts.Configuration;
import org.gradle.api.artifacts.Dependency;
import org.gradle.api.plugins.JavaPlugin;
import org.gradle.api.tasks.SourceSet;
import org.gradle.api.tasks.SourceSetContainer;
import org.gradle.language.base.plugins.LifecycleBasePlugin;
/**
* Download all supported versions of Checkstyle along with their transitive dependencies, for bundling with the
* plugin.
*/
public class GatherCheckstyleArtifactsTask extends DefaultTask {
public static final String NAME = "gatherCheckstyleArtifacts";
private final File bundledJarsDir;
private final File classPathsInfoFile;
public GatherCheckstyleArtifactsTask() {
super();
setGroup(LifecycleBasePlugin.BUILD_GROUP);
setDescription("Gathers Checkstyle libraries and their dependencies for bundling");
final Project project = getProject();
// Task Inputs: the property file with the list of supported Checkstyle versions
final CheckstyleVersions csVersions = new CheckstyleVersions(project);
getInputs().file(csVersions.getPropertyFile());
// Task Outputs: the directory full of JARs, and the classpath info file
bundledJarsDir = getTemporaryDir();
classPathsInfoFile = new File(project.getBuildDir(), "resources-generated/checkstyle-classpaths.properties");
getOutputs().dir(bundledJarsDir);
getOutputs().file(classPathsInfoFile);
// Add generated classpath info file to resources
SourceSetContainer sourceSets = (SourceSetContainer) project.getProperties().get("sourceSets");
SourceSet mainSourceSet = sourceSets.getByName(SourceSet.MAIN_SOURCE_SET_NAME);
mainSourceSet.getResources().srcDir(classPathsInfoFile.getParentFile());
// 'processResources' now depends on this task
project.afterEvaluate(new Closure<Void>(this) {
@Override
public Void call(final Object... args) {
project.getTasks().getByName(JavaPlugin.PROCESS_RESOURCES_TASK_NAME).dependsOn(getOwner());
return null;
}
});
doLast(new Closure<Void>(this) {
@Override
public Void call() {
final Set<File> bundledFiles = new TreeSet<>();
final Properties classPaths = new SortedProperties();
for (final String csVersion : csVersions.getVersions()) {
final Set<File> files = resolveDependencies(project, csVersion);
classPaths.setProperty(csVersion, convertToClassPath(files));
bundledFiles.addAll(files);
}
copyFiles(bundledFiles);
createClassPathsFile(classPaths);
return null;
}
});
}
private Set<File> resolveDependencies(final Project project, final String checkstyleVersion) {
final Dependency csDep = CheckstyleVersions.createCheckstyleDependency(project, checkstyleVersion);
final Configuration csConf = project.getConfigurations().detachedConfiguration(csDep);
return csConf.resolve();
}
private String convertToClassPath(final Set<File> resolvedDependecy) {
final StringBuilder sb = new StringBuilder();
for (final File f : resolvedDependecy) {
sb.append(CopyCheckstyleArtifactsToSandboxTask.TARGET_SUBFOLDER);
sb.append('/');
sb.append(f.getName());
sb.append(';');
}
sb.deleteCharAt(sb.length() - 1);
return sb.toString();
}
private void copyFiles(final Set<File> bundledJars) {
for (final File bundledJar : bundledJars) {
try {
FileUtils.copyFileToDirectory(bundledJar, bundledJarsDir, true);
}
catch (IOException e) {
throw new GradleException("Unable to copy file: " + bundledJar.getAbsolutePath(), e);
}
}
}
private void createClassPathsFile(final Properties classPaths) {
//noinspection ResultOfMethodCallIgnored
classPathsInfoFile.getParentFile().mkdir();
try (OutputStream os = new FileOutputStream(classPathsInfoFile)) {
classPaths.store(os, " Class path information for Checkstyle artifacts bundled with Checkstyle_IDEA");
}
catch (IOException e) {
throw new GradleException("Unable to write classpath info file: " + classPathsInfoFile.getAbsolutePath(),
e);
}
}
public File getBundledJarsDir() {
return bundledJarsDir;
}
}