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.SourceDirectorySet
import org.gradle.api.internal.plugins.DslObject
import org.gradle.api.model.ObjectFactory
import org.gradle.api.plugins.JavaPlugin
import org.gradle.api.plugins.JavaPluginExtension
import org.gradle.api.tasks.SourceSet
import org.gradle.api.tasks.TaskProvider
import org.gradle.api.provider.ListProperty
import org.gradle.api.provider.Provider
import org.gradle.api.tasks.*
import org.gradle.api.tasks.compile.JavaCompile
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.LIBRARY_ELEMENTS_ATTRIBUTE
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
void apply(Project project) {
project.pluginManager.apply(JavaPlugin)
MultiReleaseJarPluginExtension mrjpe = new MultiReleaseJarPluginExtension(project.objects)
project.extensions.add('multiReleaseJar', mrjpe)
JavaPluginExtension javaPluginExtension = project.extensions.findByType(JavaPluginExtension.class)
JavaVersion binaryVersion = javaPluginExtension.targetCompatibility ?: javaPluginExtension.toolchain?.with {
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 ->
javaCompileTask.options.release.set(javaVersion.majorVersion.toInteger())
javaCompileTask.classpath = compileClasspathConfiguration + compileOutputs.stream().reduce { fc1, fc2 -> fc1 + fc2 }.get()
javaCompileTask.doFirst {
if(project.hasProperty("jpms.module.name")) {
javaCompileTask.options.compilerArgs << "--patch-module" <<
"${project.property("jpms.module.name")}=${mainSourceSet.output.asPath}"
} else {
throw new GradleException("Missing property 'jpms.module.name'")
}
}
javaCompileTask.options.compilerArgumentProviders.add(
new CompilerArgumentProvider(
project,
project.objects,
project.provider {
project.hasProperty("jpms.module.name") ?
project.property("jpms.module.name") : null
},
mrjpe.patchModules,
mainSourceSet.output
)
)
javaCompileTask.source = sourceDirectorySet
javaCompileTask.destinationDirectory.set(sourceDirectorySet.destinationDirectory)
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;
}
}