Unplugging it and plugging it back in

- Convert existing binary plugins to kotlin
- Move each plugin to a different package
This commit is contained in:
Jozufozu 2024-04-29 15:49:30 -07:00
parent 2072bea11b
commit fb798112d7
19 changed files with 395 additions and 449 deletions

View file

@ -26,15 +26,15 @@ gradlePlugin {
} }
create("jarSetPlugin") { create("jarSetPlugin") {
id = "flywheel.jar-sets" id = "flywheel.jar-sets"
implementationClass = "com.jozufozu.gradle.JarSetPlugin" implementationClass = "com.jozufozu.gradle.jarset.JarSetPlugin"
} }
create("packageInfosPlugin") { create("packageInfosPlugin") {
id = "flywheel.package-infos" id = "flywheel.package-infos"
implementationClass = "com.jozufozu.gradle.PackageInfosPlugin" implementationClass = "com.jozufozu.gradle.nullability.PackageInfosPlugin"
} }
create("transitiveSourceSetsPlugin") { create("transitiveSourceSetsPlugin") {
id = "flywheel.transitive-source-sets" id = "flywheel.transitive-source-sets"
implementationClass = "com.jozufozu.gradle.TransitiveSourceSetsPlugin" implementationClass = "com.jozufozu.gradle.transitive.TransitiveSourceSetsPlugin"
} }
} }
} }

View file

@ -1,53 +0,0 @@
package com.jozufozu.gradle
import org.gradle.api.DefaultTask
import org.gradle.api.file.DirectoryProperty
import org.gradle.api.tasks.InputDirectory
import org.gradle.api.tasks.OutputDirectory
import org.gradle.api.tasks.SkipWhenEmpty
import org.gradle.api.tasks.TaskAction
import java.nio.file.Files
// Adapted from https://github.com/FabricMC/fabric/blob/31787236d242247e0b6c4ae806b1cfaa7042a62c/gradle/package-info.gradle, which is licensed under Apache 2.0.
class GeneratePackageInfosTask extends DefaultTask {
@SkipWhenEmpty
@InputDirectory
final DirectoryProperty sourceRoot = project.objects.directoryProperty()
@OutputDirectory
final DirectoryProperty outputDir = project.objects.directoryProperty()
@TaskAction
def run() {
def output = outputDir.get().asFile.toPath()
output.deleteDir()
def root = sourceRoot.get().asFile.toPath()
root.eachDirRecurse {
def containsJava = Files.list(it).any {
Files.isRegularFile(it) && it.fileName.toString().endsWith('.java')
}
if (containsJava && Files.notExists(it.resolve('package-info.java'))) {
def relativePath = root.relativize(it)
def target = output.resolve(relativePath)
Files.createDirectories(target)
target.resolve('package-info.java').withWriter {
def packageName = relativePath.toString().replace(File.separator, '.')
it.write("""@ParametersAreNonnullByDefault
|@FieldsAreNonnullByDefault
|@MethodsReturnNonnullByDefault
|package $packageName;
|
|import javax.annotation.ParametersAreNonnullByDefault;
|
|import net.minecraft.FieldsAreNonnullByDefault;
|import net.minecraft.MethodsReturnNonnullByDefault;
|""".stripMargin())
}
}
}
}
}

View file

@ -1,23 +0,0 @@
package com.jozufozu.gradle
import groovy.transform.CompileStatic
import org.gradle.api.Project
import org.gradle.api.tasks.SourceSet
import org.gradle.api.tasks.SourceSetContainer
@CompileStatic
class JarSetExtension {
private final Project project
JarSetExtension(Project project) {
this.project = project
}
JarTaskSet createJars(String name) {
return createJars(name, project.getExtensions().getByType(SourceSetContainer).named(name).get())
}
JarTaskSet createJars(String name, SourceSet... sourceSetSet) {
return JarTaskSet.create(project, name, sourceSetSet)
}
}

View file

@ -1,15 +0,0 @@
package com.jozufozu.gradle
import groovy.transform.CompileStatic
import org.gradle.api.Plugin
import org.gradle.api.Project
@CompileStatic
class JarSetPlugin implements Plugin<Project> {
@Override
void apply(Project project) {
project.extensions.create('jarSets', JarSetExtension, project)
}
}

View file

@ -1,126 +0,0 @@
package com.jozufozu.gradle
import groovy.transform.CompileStatic
import net.fabricmc.loom.task.RemapJarTask
import net.fabricmc.loom.task.RemapSourcesJarTask
import org.gradle.api.Action
import org.gradle.api.Project
import org.gradle.api.tasks.SourceSet
import org.gradle.api.tasks.TaskProvider
import org.gradle.api.tasks.bundling.Jar
import org.gradle.api.tasks.javadoc.Javadoc
@CompileStatic
class JarTaskSet {
public static final String BUILD_GROUP = 'build'
public static final String LOOM_GROUP = 'loom'
public static final String JAVADOC_CLASSIFIER = "javadoc"
public static final String SOURCES_CLASSIFIER = "sources"
Project project
String name
TaskProvider<Jar> jar
TaskProvider<RemapJarTask> remapJar
TaskProvider<Jar> sources
TaskProvider<RemapSourcesJarTask> remapSources
TaskProvider<Jar> javadocJar
JarTaskSet(Project project, String name, TaskProvider<Jar> jar, TaskProvider<RemapJarTask> remapJar, TaskProvider<Jar> sources, TaskProvider<RemapSourcesJarTask> remapSources, TaskProvider<Jar> javadocJar) {
this.project = project
this.name = name
this.jar = jar
this.remapJar = remapJar
this.sources = sources
this.remapSources = remapSources
this.javadocJar = javadocJar
}
void createOutgoingConfiguration(String prefix) {
def config = project.configurations.register("${prefix}${name.capitalize()}") {
it.canBeConsumed = true
it.canBeResolved = false
}
project.artifacts.add(config.name, jar)
}
void configure(Action<JarTaskSet> action) {
action.execute(this)
}
void configureEach(Action<? extends Jar> action) {
jar.configure(action)
sources.configure(action)
javadocJar.configure(action)
remapJar.configure(action as Action<? super RemapJarTask>)
remapSources.configure(action as Action<? super RemapSourcesJarTask>)
}
static JarTaskSet create(Project project, String name, SourceSet... sourceSetSet) {
def buildDirectory = project.layout.buildDirectory
def devlibs = buildDirectory.dir("devlibs/${name}")
def libs = buildDirectory.dir("libs/${name}")
def jarTask = project.tasks.register("${name}Jar", Jar) {
it.group = BUILD_GROUP
it.destinationDirectory.set(devlibs)
for (SourceSet set in sourceSetSet) {
it.from set.output
}
JarTaskUtils.excludeDuplicatePackageInfos(it)
}
def remapJarTask = project.tasks.register("${name}RemapJar", RemapJarTask) {
it.dependsOn(jarTask)
it.group = LOOM_GROUP
it.destinationDirectory.set(libs)
it.inputFile.set(jarTask.flatMap { it.archiveFile })
}
def sourcesTask = project.tasks.register("${name}SourcesJar", Jar) {
it.group = BUILD_GROUP
it.destinationDirectory.set(devlibs)
it.archiveClassifier.set(SOURCES_CLASSIFIER)
for (SourceSet set in sourceSetSet) {
it.from set.allSource
}
JarTaskUtils.excludeDuplicatePackageInfos(it)
}
def remapSourcesTask = project.tasks.register("${name}RemapSourcesJar", RemapSourcesJarTask) {
it.dependsOn(sourcesTask)
it.group = LOOM_GROUP
it.destinationDirectory.set(libs)
it.archiveClassifier.set(SOURCES_CLASSIFIER)
it.inputFile.set(sourcesTask.flatMap { it.archiveFile })
}
def javadocTask = project.tasks.register("${name}Javadoc", Javadoc) {
it.group = BUILD_GROUP
it.destinationDir = buildDirectory.dir("docs/${name}-javadoc").get().asFile
it.options.encoding = 'UTF-8'
it.options.optionFiles(project.rootProject.file('javadoc-options.txt'))
for (SourceSet set in sourceSetSet) {
it.source set.allJava
it.classpath += set.compileClasspath
}
JarTaskUtils.excludeDuplicatePackageInfos(it)
}
def javadocJarTask = project.tasks.register("${name}JavadocJar", Jar) {
it.dependsOn(javadocTask)
it.group = BUILD_GROUP
it.destinationDirectory.set(libs)
it.archiveClassifier.set(JAVADOC_CLASSIFIER)
it.from(javadocTask.map { it.outputs })
}
project.tasks.named('assemble').configure {
it.dependsOn(remapJarTask, remapSourcesTask, javadocJarTask)
}
return new JarTaskSet(project, name, jarTask, remapJarTask, sourcesTask, remapSourcesTask, javadocJarTask)
}
}

View file

@ -1,28 +0,0 @@
package com.jozufozu.gradle
import groovy.transform.CompileStatic
import org.gradle.api.file.DuplicatesStrategy
import org.gradle.api.file.FileCopyDetails
import org.gradle.api.tasks.AbstractCopyTask
import org.gradle.api.tasks.SourceTask
@CompileStatic
class JarTaskUtils {
/**
* We have duplicate packages between the common and platform dependent subprojects.
* In theory the package-info.java files should be identical, so just take the first one we find.
*/
static void excludeDuplicatePackageInfos(AbstractCopyTask copyTask) {
copyTask.filesMatching('**/package-info.java') { FileCopyDetails details ->
details.duplicatesStrategy = DuplicatesStrategy.EXCLUDE
}
}
/**
* The compile/javadoc tasks have a different base type that isn't so smart about exclusion handling.
*/
static void excludeDuplicatePackageInfos(SourceTask sourceTask) {
sourceTask.exclude('**/package-info.java')
}
}

View file

@ -1,50 +0,0 @@
package com.jozufozu.gradle
import groovy.transform.CompileStatic
import org.gradle.api.Project
import org.gradle.api.tasks.Delete
import org.gradle.api.tasks.SourceSet
@CompileStatic
class PackageInfosExtension {
final Project project
PackageInfosExtension(Project project) {
this.project = project
}
void forSourceSets(SourceSet... sourceSets) {
for (SourceSet sourceSet : sourceSets) {
_forSourceSet(sourceSet)
}
}
private void _forSourceSet(SourceSet sourceSet) {
// We have to capture the source set name for the lazy string literals,
// otherwise it'll just be whatever the last source set is in the list.
def sourceSetName = sourceSet.name
def taskName = sourceSet.getTaskName('generate', 'PackageInfos')
def task = project.tasks.register(taskName, GeneratePackageInfosTask) {
it.group = 'flywheel'
it.description = "Generates package-info files for $sourceSetName packages."
// Only apply to default source directory since we also add the generated
// sources to the source set.
it.sourceRoot.set(project.file("src/$sourceSetName/java"))
it.outputDir.set(project.file("src/$sourceSetName/generatedPackageInfos"))
}
sourceSet.java.srcDir(task)
project.tasks.named('ideaSyncTask').configure {
it.finalizedBy(task)
}
def cleanTask = project.tasks.register(sourceSet.getTaskName('clean', 'PackageInfos'), Delete) {
it.group = 'flywheel'
it.delete(project.file("src/$sourceSetName/generatedPackageInfos"))
}
project.tasks.named('clean').configure {
it.dependsOn(cleanTask)
}
}
}

View file

@ -1,14 +0,0 @@
package com.jozufozu.gradle
import groovy.transform.CompileStatic
import org.gradle.api.Plugin
import org.gradle.api.Project
@CompileStatic
class PackageInfosPlugin implements Plugin<Project> {
@Override
void apply(Project target) {
target.extensions.create('defaultPackageInfos', PackageInfosExtension, target)
}
}

View file

@ -1,134 +0,0 @@
package com.jozufozu.gradle
import groovy.transform.CompileStatic
import net.fabricmc.loom.api.LoomGradleExtensionAPI
import net.fabricmc.loom.task.RemapJarTask
import net.fabricmc.loom.task.RemapSourcesJarTask
import org.gradle.api.NamedDomainObjectProvider
import org.gradle.api.Plugin
import org.gradle.api.Project
import org.gradle.api.artifacts.Configuration
import org.gradle.api.file.FileCollection
import org.gradle.api.publish.PublishingExtension
import org.gradle.api.publish.maven.MavenPublication
import org.gradle.api.tasks.SourceSet
import org.gradle.api.tasks.SourceSetContainer
import org.gradle.api.tasks.bundling.Jar
import org.gradle.api.tasks.compile.JavaCompile
import org.gradle.api.tasks.javadoc.Javadoc
import org.gradle.language.jvm.tasks.ProcessResources
// Couldn't get imports for loom to work in the simple .gradle file, so upgraded this to a real plugin.
@CompileStatic
class PlatformPlugin implements Plugin<Project> {
@Override
void apply(Project project) {
def commonProject = project.project(':common')
def commonSourceSets = commonProject.getExtensions().getByType(SourceSetContainer)
def sourceSets = project.getExtensions().getByType(SourceSetContainer)
def loom = project.getExtensions().getByType(LoomGradleExtensionAPI)
def publishing = project.getExtensions().getByType(PublishingExtension)
SourceSet platformImpl = sourceSets.named('main').get()
SourceSet platformApi = sourceSets.create('api')
SourceSet platformLib = sourceSets.create('lib')
SourceSet platformBackend = sourceSets.create('backend')
// This is needed for both platforms.
def mainMod = loom.mods.maybeCreate('main')
mainMod.sourceSet(platformApi)
mainMod.sourceSet(platformLib)
mainMod.sourceSet(platformBackend)
mainMod.sourceSet(platformImpl)
SourceSet commonApi = commonSourceSets.named('api').get()
SourceSet commonLib = commonSourceSets.named('lib').get()
SourceSet commonBackend = commonSourceSets.named('backend').get()
SourceSet commonImpl = commonSourceSets.named('main').get()
def commonSources = [commonApi, commonLib, commonBackend, commonImpl]
// Directly compile the platform sources with the common sources
includeFromCommon(project, platformApi, commonApi)
includeFromCommon(project, platformLib, commonLib)
includeFromCommon(project, platformBackend, commonBackend)
includeFromCommon(project, platformImpl, commonImpl)
def tasks = project.tasks
tasks.withType(JavaCompile).configureEach { JavaCompile compileJava ->
JarTaskUtils.excludeDuplicatePackageInfos(compileJava)
}
tasks.named('jar', Jar).configure { Jar jar ->
jar.from platformApi.output, platformLib.output, platformBackend.output
JarTaskUtils.excludeDuplicatePackageInfos(jar)
}
tasks.named('javadoc', Javadoc).configure { Javadoc javadoc ->
commonSources.forEach { javadoc.source it.allJava }
javadoc.source platformApi.allJava, platformLib.allJava, platformBackend.allJava
JarTaskUtils.excludeDuplicatePackageInfos(javadoc)
}
tasks.named('sourcesJar', Jar).configure { Jar jar ->
commonSources.forEach { jar.from it.allJava }
jar.from platformApi.allJava, platformLib.allJava, platformBackend.allJava
JarTaskUtils.excludeDuplicatePackageInfos(jar)
}
def remapJar = tasks.named('remapJar', RemapJarTask)
def remapSourcesJar = tasks.named('remapSourcesJar', RemapSourcesJarTask)
def javadocJar = tasks.named('javadocJar', Jar)
JarTaskSet apiSet = JarTaskSet.create(project, 'api', platformApi, platformLib)
def mcVersion = project.property('artifact_minecraft_version')
publishing.publications {
// we should be using remapped on both Fabric and Forge because Forge needs to put things in srg
it.register('mavenApi', MavenPublication) { MavenPublication pub ->
pub.artifact(apiSet.remapJar)
pub.artifact(apiSet.remapSources)
pub.artifact(apiSet.javadocJar)
pub.artifactId = "flywheel-${project.name}-api-${mcVersion}"
}
it.register('mavenImpl', MavenPublication) { MavenPublication pub ->
pub.artifact(remapJar)
pub.artifact(remapSourcesJar)
pub.artifact(javadocJar)
pub.artifactId = "flywheel-${project.name}-${mcVersion}"
}
}
}
static NamedDomainObjectProvider<Configuration> newConfiguration(Project project, String name) {
return project.configurations.register(name) { Configuration it ->
it.canBeConsumed = true
it.canBeResolved = false
}
}
static void extendsFrom(Project project, String name, Configuration... configurations) {
project.configurations.named(name).configure {
it.extendsFrom(configurations)
}
}
static void includeFromCommon(Project project, SourceSet sourceSet, SourceSet commonSourceSet) {
project.tasks.named(sourceSet.compileJavaTaskName, JavaCompile).configure { JavaCompile compileJava ->
compileJava.source commonSourceSet.allJava
}
project.tasks.named(sourceSet.processResourcesTaskName, ProcessResources).configure { ProcessResources processResources ->
processResources.from commonSourceSet.resources
}
}
}

View file

@ -0,0 +1,115 @@
package com.jozufozu.gradle
import com.jozufozu.gradle.jarset.JarTaskSet
import net.fabricmc.loom.api.LoomGradleExtensionAPI
import net.fabricmc.loom.task.RemapJarTask
import net.fabricmc.loom.task.RemapSourcesJarTask
import org.gradle.api.Plugin
import org.gradle.api.Project
import org.gradle.api.publish.PublishingExtension
import org.gradle.api.publish.maven.MavenPublication
import org.gradle.api.tasks.SourceSet
import org.gradle.api.tasks.SourceSetContainer
import org.gradle.api.tasks.compile.JavaCompile
import org.gradle.api.tasks.javadoc.Javadoc
import org.gradle.jvm.tasks.Jar
import org.gradle.kotlin.dsl.the
import org.gradle.language.jvm.tasks.ProcessResources
class PlatformPlugin: Plugin<Project> {
override fun apply(project: Project) {
val commonProject = project.project(":common")
val commonSourceSets = commonProject.the<SourceSetContainer>()
val sourceSets = project.the<SourceSetContainer>()
val loom = project.the<LoomGradleExtensionAPI>()
val publishing = project.the<PublishingExtension>()
val platformImpl = sourceSets.named("main").get()
val platformApi = sourceSets.create("api")
val platformLib = sourceSets.create("lib")
val platformBackend = sourceSets.create("backend")
// This is needed for both platforms.
val mainMod = loom.mods.maybeCreate("main")
mainMod.sourceSet(platformApi)
mainMod.sourceSet(platformLib)
mainMod.sourceSet(platformBackend)
mainMod.sourceSet(platformImpl)
val commonApi = commonSourceSets.named("api").get()
val commonLib = commonSourceSets.named("lib").get()
val commonBackend = commonSourceSets.named("backend").get()
val commonImpl = commonSourceSets.named("main").get()
val commonSources = listOf(commonApi, commonLib, commonBackend, commonImpl)
// Directly compile the platform sources with the common sources
includeFromCommon(project, platformApi, commonApi)
includeFromCommon(project, platformLib, commonLib)
includeFromCommon(project, platformBackend, commonBackend)
includeFromCommon(project, platformImpl, commonImpl)
val tasks = project.tasks
tasks.withType(JavaCompile::class.java).configureEach {
JarTaskSet.excludeDuplicatePackageInfos(this)
}
tasks.named("jar", Jar::class.java).configure {
from(platformApi.output, platformLib.output, platformBackend.output)
JarTaskSet.excludeDuplicatePackageInfos(this)
}
tasks.named("javadoc", Javadoc::class.java).configure {
commonSources.forEach { source(it.allJava) }
source(platformApi.allJava, platformLib.allJava, platformBackend.allJava)
JarTaskSet.excludeDuplicatePackageInfos(this)
}
tasks.named("sourcesJar", Jar::class.java).configure {
commonSources.forEach { from(it.allJava) }
from(platformApi.allJava, platformLib.allJava, platformBackend.allJava)
JarTaskSet.excludeDuplicatePackageInfos(this)
}
val remapJar = tasks.named("remapJar", RemapJarTask::class.java)
val remapSourcesJar = tasks.named("remapSourcesJar", RemapSourcesJarTask::class.java)
val javadocJar = tasks.named("javadocJar", Jar::class.java)
val apiSet = JarTaskSet.create(project, "api", platformApi, platformLib)
val mcVersion = project.property("artifact_minecraft_version")
publishing.publications {
// we should be using remapped on both Fabric and Forge because Forge needs to put things in srg
register("mavenApi", MavenPublication::class.java) {
artifact(apiSet.remapJar)
artifact(apiSet.remapSources)
artifact(apiSet.javadocJar)
artifactId = "flywheel-${project.name}-api-${mcVersion}"
}
register("mavenImpl", MavenPublication::class.java) {
artifact(remapJar)
artifact(remapSourcesJar)
artifact(javadocJar)
artifactId = "flywheel-${project.name}-${mcVersion}"
}
}
}
private fun includeFromCommon(project: Project, sourceSet: SourceSet, commonSourceSet: SourceSet) {
project.tasks.named(sourceSet.compileJavaTaskName, JavaCompile::class.java).configure {
source(commonSourceSet.allJava)
}
project.tasks.named(sourceSet.processResourcesTaskName, ProcessResources::class.java).configure {
from(commonSourceSet.resources)
}
}
}

View file

@ -0,0 +1,16 @@
package com.jozufozu.gradle.jarset
import org.gradle.api.Project
import org.gradle.api.tasks.SourceSet
import org.gradle.api.tasks.SourceSetContainer
import org.gradle.kotlin.dsl.the
open class JarSetExtension(val project: Project) {
fun createJars(name: String): JarTaskSet {
return createJars(name, project.the<SourceSetContainer>().named(name).get())
}
fun createJars(name: String, vararg sourceSetSet: SourceSet): JarTaskSet {
return JarTaskSet.create(project, name, *sourceSetSet)
}
}

View file

@ -0,0 +1,10 @@
package com.jozufozu.gradle.jarset
import org.gradle.api.Plugin
import org.gradle.api.Project
class JarSetPlugin: Plugin<Project> {
override fun apply(target: Project) {
target.extensions.create("jarSets", JarSetExtension::class.java, target)
}
}

View file

@ -0,0 +1,138 @@
package com.jozufozu.gradle.jarset
import net.fabricmc.loom.task.RemapJarTask
import net.fabricmc.loom.task.RemapSourcesJarTask
import org.gradle.api.Action
import org.gradle.api.Project
import org.gradle.api.file.DuplicatesStrategy
import org.gradle.api.tasks.AbstractCopyTask
import org.gradle.api.tasks.SourceSet
import org.gradle.api.tasks.SourceTask
import org.gradle.api.tasks.TaskProvider
import org.gradle.api.tasks.javadoc.Javadoc
import org.gradle.jvm.tasks.Jar
class JarTaskSet(
val project: Project,
val name: String,
val jar: TaskProvider<Jar>,
val remapJar: TaskProvider<RemapJarTask>,
val sources: TaskProvider<Jar>,
val remapSources: TaskProvider<RemapSourcesJarTask>,
val javadocJar: TaskProvider<Jar>
) {
fun createOutgoingConfiguration(prefix: String) {
val config = project.configurations.register("${prefix}${name.capitalize()}") {
isCanBeConsumed = true
isCanBeResolved = false
}
project.artifacts.add(config.name, jar)
}
fun configure(action: Action<JarTaskSet>) {
action.execute(this)
}
fun configureEach(action: Action<Jar>) {
jar.configure(action)
sources.configure(action)
javadocJar.configure(action)
remapJar.configure(action)
remapSources.configure(action)
}
companion object {
private const val PACKAGE_INFOS_JAVA_PATTERN = "**/package-info.java"
private const val BUILD_GROUP: String = "build"
private const val LOOM_GROUP: String = "loom"
private const val JAVADOC_CLASSIFIER: String = "javadoc"
private const val SOURCES_CLASSIFIER: String = "sources"
/**
* We have duplicate packages between the common and platform dependent subprojects.
* In theory the package-info.java files should be identical, so just take the first one we find.
*/
fun excludeDuplicatePackageInfos(copyTask: AbstractCopyTask) {
copyTask.filesMatching(PACKAGE_INFOS_JAVA_PATTERN) {
duplicatesStrategy = DuplicatesStrategy.EXCLUDE
}
}
/**
* The compile/javadoc tasks have a different base type that isn't so smart about exclusion handling.
*/
fun excludeDuplicatePackageInfos(sourceTask: SourceTask) {
sourceTask.exclude(PACKAGE_INFOS_JAVA_PATTERN)
}
fun create(project: Project, name: String, vararg sourceSetSet: SourceSet): JarTaskSet {
val buildDirectory = project.layout.buildDirectory
val devlibs = buildDirectory.dir("devlibs/${name}")
val libs = buildDirectory.dir("libs/${name}")
val jarTask = project.tasks.register("${name}Jar", Jar::class.java) {
group = BUILD_GROUP
destinationDirectory.set(devlibs)
for (set in sourceSetSet) {
from(set.output)
}
excludeDuplicatePackageInfos(this)
}
val remapJarTask = project.tasks.register("${name}RemapJar", RemapJarTask::class.java) {
dependsOn(jarTask)
group = LOOM_GROUP
destinationDirectory.set(libs)
inputFile.set(jarTask.flatMap { it.archiveFile })
}
val sourcesTask = project.tasks.register("${name}SourcesJar", Jar::class.java) {
group = BUILD_GROUP
destinationDirectory.set(devlibs)
archiveClassifier.set(SOURCES_CLASSIFIER)
for (set in sourceSetSet) {
from(set.allSource)
}
excludeDuplicatePackageInfos(this)
}
val remapSourcesTask = project.tasks.register("${name}RemapSourcesJar", RemapSourcesJarTask::class.java) {
dependsOn(sourcesTask)
group = LOOM_GROUP
destinationDirectory.set(libs)
archiveClassifier.set(SOURCES_CLASSIFIER)
inputFile.set(sourcesTask.flatMap { it.archiveFile })
}
val javadocTask = project.tasks.register("${name}Javadoc", Javadoc::class.java) {
group = BUILD_GROUP
setDestinationDir(buildDirectory.dir("docs/${name}-javadoc").get().asFile)
options.encoding = "UTF-8"
options.optionFiles(project.rootProject.file("javadoc-options.txt"))
for (set in sourceSetSet) {
source(set.allJava)
classpath += set.compileClasspath
}
excludeDuplicatePackageInfos(this)
}
val javadocJarTask = project.tasks.register("${name}JavadocJar", Jar::class.java) {
dependsOn(javadocTask)
group = BUILD_GROUP
destinationDirectory.set(libs)
archiveClassifier.set(JAVADOC_CLASSIFIER)
from(javadocTask.map { it.outputs })
}
project.tasks.named("assemble").configure {
dependsOn(remapJarTask, remapSourcesTask, javadocJarTask)
}
return JarTaskSet(project, name, jarTask, remapJarTask, sourcesTask, remapSourcesTask, javadocJarTask)
}
}
}

View file

@ -0,0 +1,58 @@
package com.jozufozu.gradle.nullability
import org.apache.groovy.nio.extensions.NioExtensions
import org.codehaus.groovy.runtime.StringGroovyMethods
import org.gradle.api.DefaultTask
import org.gradle.api.file.DirectoryProperty
import org.gradle.api.tasks.InputDirectory
import org.gradle.api.tasks.OutputDirectory
import org.gradle.api.tasks.SkipWhenEmpty
import org.gradle.api.tasks.TaskAction
import org.gradle.kotlin.dsl.closureOf
import java.io.BufferedWriter
import java.io.File
import java.nio.file.Files
import java.nio.file.Path
// Adapted from https://github.com/FabricMC/fabric/blob/31787236d242247e0b6c4ae806b1cfaa7042a62c/gradle/package-info.gradle, which is licensed under Apache 2.0.
open class GeneratePackageInfosTask: DefaultTask() {
@SkipWhenEmpty
@InputDirectory
val sourceRoot: DirectoryProperty = project.objects.directoryProperty()
@OutputDirectory
val outputDir: DirectoryProperty = project.objects.directoryProperty()
@TaskAction
fun run() {
val output = outputDir.get().asFile.toPath()
NioExtensions.deleteDir(output)
val root = sourceRoot.get().asFile.toPath()
NioExtensions.eachDirRecurse(root, closureOf<Path> {
val containsJava = Files.list(this).anyMatch {
Files.isRegularFile(it) && it.fileName.toString().endsWith(".java")
}
if (containsJava && Files.notExists(resolve("package-info.java"))) {
val relativePath = root.relativize(this)
val target = output.resolve(relativePath)
Files.createDirectories(target)
NioExtensions.withWriter(target.resolve("package-info.java"), closureOf<BufferedWriter> {
val packageName = relativePath.toString().replace(File.separator, ".")
write(StringGroovyMethods.stripMargin("""@ParametersAreNonnullByDefault
|@FieldsAreNonnullByDefault
|@MethodsReturnNonnullByDefault
|package $packageName;
|
|import javax.annotation.ParametersAreNonnullByDefault;
|
|import net.minecraft.FieldsAreNonnullByDefault;
|import net.minecraft.MethodsReturnNonnullByDefault;
|"""))
})
}
})
}
}

View file

@ -0,0 +1,42 @@
package com.jozufozu.gradle.nullability
import org.gradle.api.Project
import org.gradle.api.tasks.Delete
import org.gradle.api.tasks.SourceSet
open class PackageInfosExtension(private val project: Project) {
fun forSourceSets(vararg sourceSets: SourceSet) {
for (sourceSet in sourceSets) {
forSourceSet(sourceSet)
}
}
private fun forSourceSet(sourceSet: SourceSet) {
// We have to capture the source set name for the lazy string literals,
// otherwise it'll just be whatever the last source set is in the list.
val sourceSetName = sourceSet.name
val taskName = sourceSet.getTaskName("generate", "PackageInfos")
val task = project.tasks.register(taskName, GeneratePackageInfosTask::class.java) {
group = "flywheel"
description = "Generates package-info files for $sourceSetName packages."
// Only apply to default source directory since we also add the generated
// sources to the source set.
sourceRoot.set(project.file("src/$sourceSetName/java"))
outputDir.set(project.file("src/$sourceSetName/generatedPackageInfos"))
}
sourceSet.java.srcDir(task)
project.tasks.named("ideaSyncTask").configure {
finalizedBy(task)
}
val cleanTask = project.tasks.register(sourceSet.getTaskName("clean", "PackageInfos"), Delete::class.java) {
group = "flywheel"
delete(project.file("src/$sourceSetName/generatedPackageInfos"))
}
project.tasks.named("clean").configure {
dependsOn(cleanTask)
}
}
}

View file

@ -0,0 +1,10 @@
package com.jozufozu.gradle.nullability
import org.gradle.api.Plugin
import org.gradle.api.Project
class PackageInfosPlugin: Plugin<Project> {
override fun apply(target: Project) {
target.extensions.create("defaultPackageInfos", PackageInfosExtension::class.java, target)
}
}

View file

@ -1,4 +1,4 @@
package com.jozufozu.gradle package com.jozufozu.gradle.transitive
import org.gradle.api.tasks.SourceSet import org.gradle.api.tasks.SourceSet

View file

@ -1,4 +1,4 @@
package com.jozufozu.gradle package com.jozufozu.gradle.transitive
import org.gradle.api.Action import org.gradle.api.Action
import org.gradle.api.Project import org.gradle.api.Project

View file

@ -1,4 +1,4 @@
package com.jozufozu.gradle package com.jozufozu.gradle.transitive
import org.gradle.api.Plugin import org.gradle.api.Plugin
import org.gradle.api.Project import org.gradle.api.Project