added module patching customization

This commit is contained in:
2022-07-01 03:30:59 +08:00
parent e860638c29
commit f12bb69dbd
2 changed files with 138 additions and 10 deletions

View File

@@ -10,20 +10,111 @@ import org.gradle.api.attributes.java.TargetJvmVersion
import org.gradle.api.file.FileCollection import org.gradle.api.file.FileCollection
import org.gradle.api.file.SourceDirectorySet import org.gradle.api.file.SourceDirectorySet
import org.gradle.api.internal.plugins.DslObject import org.gradle.api.internal.plugins.DslObject
import org.gradle.api.model.ObjectFactory
import org.gradle.api.plugins.JavaPlugin import org.gradle.api.plugins.JavaPlugin
import org.gradle.api.plugins.JavaPluginExtension import org.gradle.api.plugins.JavaPluginExtension
import org.gradle.api.tasks.SourceSet import org.gradle.api.provider.ListProperty
import org.gradle.api.tasks.TaskProvider import org.gradle.api.provider.Provider
import org.gradle.api.tasks.*
import org.gradle.api.tasks.compile.JavaCompile import org.gradle.api.tasks.compile.JavaCompile
import org.gradle.jvm.tasks.Jar import org.gradle.jvm.tasks.Jar
import org.gradle.process.CommandLineArgumentProvider
import java.lang.module.ModuleDescriptor
import java.util.jar.JarFile
import java.util.stream.Collectors
import java.util.zip.ZipFile
import static org.gradle.api.attributes.LibraryElements.JAR import static org.gradle.api.attributes.LibraryElements.JAR
import static org.gradle.api.attributes.LibraryElements.LIBRARY_ELEMENTS_ATTRIBUTE import static org.gradle.api.attributes.LibraryElements.LIBRARY_ELEMENTS_ATTRIBUTE
class MultiReleaseJarPlugin implements Plugin<Project> { class MultiReleaseJarPlugin implements Plugin<Project> {
private static void jpmsModuleName(File file) {
JarFile jarFile = new JarFile(file).with {
if (it.isMultiRelease()) {
new JarFile(
file,
false,
ZipFile.OPEN_READ,
Runtime.version()
)
} else {
it
}
}
String automaticModuleName = jarFile.manifest?.with {it.mainAttributes.getValue("Automatic-Module-Name") }
def moduleInfoEntry = jarFile.getJarEntry("module-info.class")
moduleInfoEntry
?.with(jarFile.&getInputStream)
?.withCloseable(ModuleDescriptor.&read) ?: automaticModuleName
ModuleDescriptor.read()
}
// @Canonical
static class CompilerArgumentProvider implements CommandLineArgumentProvider {
private final Project project
private final ObjectFactory objects
@Input
final Provider<String> jpmsModuleName
private final Map<String, ListProperty<String>> patchModules
@InputFiles
@CompileClasspath
final FileCollection sourceSetOutput
// @InputFiles
// FileCollection getPatchModules() {
// return project.files(patchModules.entrySet().stream().flatMap {
// it.getValue().get().stream()
// }.toArray(String::new))
// }
CompilerArgumentProvider(
Project project,
ObjectFactory objects,
Provider<String> jpmsModuleName,
Map<String, ListProperty<String>> patchModules,
FileCollection sourceSetOutput) {
this.project = project
this.objects = objects
this.jpmsModuleName = jpmsModuleName
this.patchModules = patchModules
this.sourceSetOutput = sourceSetOutput
}
@Override
Iterable<String> asArguments() {
Map<String, ListProperty<String>> patchModules = new HashMap<>(patchModules)
String name = jpmsModuleName.get()
if(name) {
patchModules.computeIfAbsent(name) {
objects.listProperty(String.class).convention(new ArrayList<String>())
}.addAll(sourceSetOutput.collect { it.toString() })
} else {
throw new GradleException("Missing property 'jpms.module.name'")
}
String sep = System.getProperty('path.separator')
List<String> result = new ArrayList<>()
for(Map.Entry<String, ListProperty<String>> entry : patchModules.entrySet()) {
String arg = entry.getValue().get().stream().collect(Collectors.joining(sep))
result += '--patch-module'
result += "${entry.getKey()}=${arg}"
}
result
}
}
@Override @Override
void apply(Project project) { void apply(Project project) {
project.pluginManager.apply(JavaPlugin) project.pluginManager.apply(JavaPlugin)
MultiReleaseJarPluginExtension mrjpe = new MultiReleaseJarPluginExtension(project.objects)
project.extensions.add('multiReleaseJar', mrjpe)
JavaPluginExtension javaPluginExtension = project.extensions.findByType(JavaPluginExtension.class) JavaPluginExtension javaPluginExtension = project.extensions.findByType(JavaPluginExtension.class)
JavaVersion binaryVersion = javaPluginExtension.targetCompatibility ?: javaPluginExtension.toolchain?.with { JavaVersion binaryVersion = javaPluginExtension.targetCompatibility ?: javaPluginExtension.toolchain?.with {
it.languageVersion.get() it.languageVersion.get()
@@ -64,14 +155,18 @@ class MultiReleaseJarPlugin implements Plugin<Project> {
TaskProvider<JavaCompile> compileTask = project.tasks.register(JavaPlugin.COMPILE_JAVA_TASK_NAME + javaVersion.majorVersion, JavaCompile, { javaCompileTask -> TaskProvider<JavaCompile> compileTask = project.tasks.register(JavaPlugin.COMPILE_JAVA_TASK_NAME + javaVersion.majorVersion, JavaCompile, { javaCompileTask ->
javaCompileTask.options.release.set(javaVersion.majorVersion.toInteger()) javaCompileTask.options.release.set(javaVersion.majorVersion.toInteger())
javaCompileTask.classpath = compileClasspathConfiguration + compileOutputs.stream().reduce { fc1, fc2 -> fc1 + fc2 }.get() javaCompileTask.classpath = compileClasspathConfiguration + compileOutputs.stream().reduce { fc1, fc2 -> fc1 + fc2 }.get()
javaCompileTask.doFirst { javaCompileTask.options.compilerArgumentProviders.add(
if(project.hasProperty("jpms.module.name")) { new CompilerArgumentProvider(
javaCompileTask.options.compilerArgs << "--patch-module" << project,
"${project.property("jpms.module.name")}=${mainSourceSet.output.asPath}" project.objects,
} else { project.provider {
throw new GradleException("Missing property 'jpms.module.name'") project.hasProperty("jpms.module.name") ?
} project.property("jpms.module.name") : null
} },
mrjpe.patchModules,
mainSourceSet.output
)
)
javaCompileTask.source = sourceDirectorySet javaCompileTask.source = sourceDirectorySet
javaCompileTask.destinationDirectory.set(sourceDirectorySet.destinationDirectory) javaCompileTask.destinationDirectory.set(sourceDirectorySet.destinationDirectory)
javaCompileTask.options.annotationProcessorPath = mainSourceSet.annotationProcessorPath javaCompileTask.options.annotationProcessorPath = mainSourceSet.annotationProcessorPath

View File

@@ -0,0 +1,33 @@
package net.woggioni.gradle.multi.release.jar;
import org.gradle.api.model.ObjectFactory;
import org.gradle.api.provider.ListProperty;
import org.gradle.api.provider.Provider;
import javax.inject.Inject;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
public class MultiReleaseJarPluginExtension {
private final ObjectFactory objects;
private final Map<String, ListProperty<String>> patchModules;
@Inject
public MultiReleaseJarPluginExtension(ObjectFactory objects) {
this.objects = objects;
patchModules = new HashMap<>();
}
public void patchModule(String moduleName, Provider<String> path) {
this.patchModules
.computeIfAbsent(moduleName, key -> objects.listProperty(String.class)
.convention(new ArrayList<>()))
.add(path);
}
public Map<String, ListProperty<String>> getPatchModules() {
return patchModules;
}
}