From 3dc0457d8c14ab5cc629a6ef35f5ed7f82998e0f Mon Sep 17 00:00:00 2001 From: Revxrsal Date: Sun, 15 Dec 2024 00:05:32 +0300 Subject: [PATCH] organize the gradle plugin code and document it --- .../zapper/RuntimeLibPluginConfiguration.java | 2 +- .../java/revxrsal/zapper/gradle/Relocation.kt | 6 ++ .../revxrsal/zapper/gradle/ZapperExtension.kt | 72 ++++++++++++++++--- .../revxrsal/zapper/gradle/ZapperPlugin.kt | 47 ++++++++---- .../java/revxrsal/zapper/gradle/extensions.kt | 8 ++- .../java/revxrsal/zapper/gradle/repository.kt | 45 +++++++++--- 6 files changed, 144 insertions(+), 36 deletions(-) create mode 100644 gradle-plugin/src/main/java/revxrsal/zapper/gradle/Relocation.kt diff --git a/api/src/main/java/revxrsal/zapper/RuntimeLibPluginConfiguration.java b/api/src/main/java/revxrsal/zapper/RuntimeLibPluginConfiguration.java index 3bae46c..cedabe4 100644 --- a/api/src/main/java/revxrsal/zapper/RuntimeLibPluginConfiguration.java +++ b/api/src/main/java/revxrsal/zapper/RuntimeLibPluginConfiguration.java @@ -80,7 +80,7 @@ public final class RuntimeLibPluginConfiguration { private static @NotNull Properties parseProperties() { Properties properties = new Properties(); - try (InputStream stream = ClassLoaderReader.getResource("zapper/config.properties")) { + try (InputStream stream = ClassLoaderReader.getResource("zapper/zapper.properties")) { properties.load(stream); } catch (IOException e) { throw sneakyThrow(e); diff --git a/gradle-plugin/src/main/java/revxrsal/zapper/gradle/Relocation.kt b/gradle-plugin/src/main/java/revxrsal/zapper/gradle/Relocation.kt new file mode 100644 index 0000000..be37c7a --- /dev/null +++ b/gradle-plugin/src/main/java/revxrsal/zapper/gradle/Relocation.kt @@ -0,0 +1,6 @@ +package revxrsal.zapper.gradle + +/** + * Represents a basic relocation rule + */ +data class Relocation(val pattern: String, val newPattern: String) diff --git a/gradle-plugin/src/main/java/revxrsal/zapper/gradle/ZapperExtension.kt b/gradle-plugin/src/main/java/revxrsal/zapper/gradle/ZapperExtension.kt index 9496038..789065a 100644 --- a/gradle-plugin/src/main/java/revxrsal/zapper/gradle/ZapperExtension.kt +++ b/gradle-plugin/src/main/java/revxrsal/zapper/gradle/ZapperExtension.kt @@ -1,29 +1,83 @@ package revxrsal.zapper.gradle +import org.gradle.api.Action + +/** + * The maven central repository, which is added by default. + */ +private const val MAVEN_CENTRAL = "https://repo.maven.apache.org/maven2/" + +/** + * Configure Zapper properties + */ open class ZapperExtension { + /** + * The subfolder in the plugin directory where libraries + * should be installed + */ var libsFolder: String = "libs" + + /** + * The relocation prefix of all libraries + */ var relocationPrefix: String = "zapperlib" - private var _repositories = mutableListOf() + + /** + * The repositories URLs + */ + private var _repositories = mutableListOf(MAVEN_CENTRAL) + + /** + * The relocation rules + */ private var _relocations = mutableListOf() + /** + * The currently added repositories + */ val repositries: List get() = _repositories + + /** + * The current relocation rules + */ val relocations: List get() = _relocations - internal var useProjectRepositories = false + /** + * Should project repositories be remembered for downloading + * repositories at runtime? + */ + internal var includeProjectRepositories = false - fun repositories(configure: RepositoryDsl.() -> Unit) { + /** + * Configures the repositories that are used for downloading dependencies. + * + * See [RepositoryDsl] + */ + fun repositories(configure: Action) { val dsl = BasicRepositoryDsl() - dsl.mavenCentral() - dsl.configure() + configure.execute(dsl) _repositories = dsl.repositories - useProjectRepositories = dsl.projectRepositories + includeProjectRepositories = dsl.includeProjectRepositories + } + + /** + * Adds a relocation rule + */ + fun relocate(pattern: String, newPattern: String) { + _relocations.add(Relocation(pattern, newPattern)) } + /** + * A fancy toString implementation + */ override fun toString(): String { - return "RuntimeLibsExtension(libsFolder='$libsFolder', useProjectRepositories=$useProjectRepositories, repositries=$repositries)" + return "RuntimeLibsExtension(libsFolder='$libsFolder', includeProjectRepositories=$includeProjectRepositories, repositries=$repositries)" } + /** + * Generates the content of the properties file of this extension + */ internal fun toPropertiesFile(): String { //language=Properties return """ @@ -31,8 +85,4 @@ open class ZapperExtension { relocation-prefix=${relocationPrefix} """.trimIndent() } - - fun relocate(pattern: String, newPattern: String) { - _relocations.add(Relocation(pattern, newPattern)) - } } diff --git a/gradle-plugin/src/main/java/revxrsal/zapper/gradle/ZapperPlugin.kt b/gradle-plugin/src/main/java/revxrsal/zapper/gradle/ZapperPlugin.kt index 3aaeb12..a092f56 100644 --- a/gradle-plugin/src/main/java/revxrsal/zapper/gradle/ZapperPlugin.kt +++ b/gradle-plugin/src/main/java/revxrsal/zapper/gradle/ZapperPlugin.kt @@ -11,25 +11,37 @@ import org.gradle.kotlin.dsl.hasPlugin import org.gradle.kotlin.dsl.withType import java.io.File -const val PLUGIN_VERSION: String = "0.0.1" - +/** + * The plugin version + */ +private const val PLUGIN_VERSION: String = "0.0.1" + +/** + * The Zapper Gradle plugin collects information about the zapped dependencies + * and merges them into raw text files that are read by the Zapper API. + */ class ZapperPlugin : Plugin { override fun apply(project: Project) { + if (!project.plugins.hasPlugin(ShadowPlugin::class)) { + error("ShadowJar is required by the Zapper Gradle plugin. Please add ShadowJar v8.11.0") + } + project.extensions.create("zapper", ZapperExtension::class.java) - val runtimeLib = project.configurations.create("zap") { + // creates the 'zap' configuration + val zap = project.configurations.create("zap") { isCanBeResolved = true isCanBeConsumed = false description = "Marks a dependency for downloading at runtime" } + // include zapped dependencies as compileOnly project.afterEvaluate { - configurations.getByName("compileOnly").extendsFrom(runtimeLib) + configurations.getByName("compileOnly").extendsFrom(zap) } val outputDir = project.layout.buildDirectory.asFile.get().resolve("zapper") - val configFile = outputDir.resolve("config.properties") project.tasks.register("generateZapperFiles") { group = "build" description = "Generates information about dependencies to install and relocate at runtime" @@ -40,15 +52,12 @@ class ZapperPlugin : Plugin { project.createRepositoriesFile(outputDir, extension) if (extension.relocations.isNotEmpty()) { - if (project.plugins.hasPlugin(ShadowPlugin::class)) { - project.createRelocationsFile(outputDir, extension) - } else { - error("Relocations require the ShadowJar plugin") - } + project.createRelocationsFile(outputDir, extension) } - createZappersFile(outputDir, runtimeLib) + createZappersFile(outputDir, zap) + val configFile = outputDir.resolve("zapper.properties") configFile.writeText(extension.toPropertiesFile()) } } @@ -62,13 +71,16 @@ class ZapperPlugin : Plugin { include("dependencies.txt") include("relocations.txt") include("repositories.txt") - include("config.properties") + include("zapper.properties") into("zapper") } } } } +/** + * Generates the relocations.txt file + */ private fun Project.createRelocationsFile(outputDir: File, extension: ZapperExtension) { val relocationsFile = outputDir.resolve("relocations.txt") project.plugins.withId("com.github.johnrengelman.shadow") { @@ -84,6 +96,9 @@ private fun Project.createRelocationsFile(outputDir: File, extension: ZapperExte } } +/** + * Generates the dependencies.txt file + */ private fun createZappersFile(outputDir: File, runtimeLib: Configuration) { val runtimeLibsFile = outputDir.resolve("dependencies.txt") val runtimeLibDependencies = runtimeLib.resolvedConfiguration @@ -93,10 +108,13 @@ private fun createZappersFile(outputDir: File, runtimeLib: Configuration) { runtimeLibsFile.writeText(runtimeLibDependencies) } +/** + * Generates the repositories.txt file + */ private fun Project.createRepositoriesFile(outputDir: File, extension: ZapperExtension) { val repositoriesFile = outputDir.resolve("repositories.txt") val repositories = extension.repositries.toMutableSet() - if (extension.useProjectRepositories) { + if (extension.includeProjectRepositories) { project.repositories.forEach { if (it is MavenArtifactRepository) { repositories.add(it.url.toString()) @@ -106,6 +124,9 @@ private fun Project.createRepositoriesFile(outputDir: File, extension: ZapperExt repositoriesFile.writeText(repositories.joinToString("\n")) } +/** + * Adds the Zapper API library + */ private fun Project.addZapperDependencies() { dependencies.add("implementation", "io.github.revxrsal:zapper.api:${PLUGIN_VERSION}") } diff --git a/gradle-plugin/src/main/java/revxrsal/zapper/gradle/extensions.kt b/gradle-plugin/src/main/java/revxrsal/zapper/gradle/extensions.kt index cac4d01..b25cb3c 100644 --- a/gradle-plugin/src/main/java/revxrsal/zapper/gradle/extensions.kt +++ b/gradle-plugin/src/main/java/revxrsal/zapper/gradle/extensions.kt @@ -3,8 +3,14 @@ package revxrsal.zapper.gradle import org.gradle.api.Action import org.gradle.api.Project -val Project.zapper: ZapperExtension get() = extensions.getByName("zapper") as ZapperExtension +/** + * Returns the zapper extension configuration + */ +val Project.zapper get() = extensions.getByName("zapper") as ZapperExtension +/** + * Configures the Zapper plugin + */ fun Project.zapper(configure: Action) { project.extensions.configure("zapper", configure) } diff --git a/gradle-plugin/src/main/java/revxrsal/zapper/gradle/repository.kt b/gradle-plugin/src/main/java/revxrsal/zapper/gradle/repository.kt index fd7e4a0..9520dda 100644 --- a/gradle-plugin/src/main/java/revxrsal/zapper/gradle/repository.kt +++ b/gradle-plugin/src/main/java/revxrsal/zapper/gradle/repository.kt @@ -1,26 +1,51 @@ package revxrsal.zapper.gradle +/** + * A basic interface DSL for specifying repositories to be used + * for dependencies + */ interface RepositoryDsl { - fun mavenCentral() = maven("https://repo.maven.apache.org/maven2/") - fun jitpack() = maven("https://jitpack.io/") + + /** + * Adds the given repository to the repositories list + */ fun maven(url: String) - fun useProjectRepositories() + + /** + * Tells Zapper to include the project repositories for + * resolving dependencies + */ + fun includeProjectRepositories() } +/** + * A basic implementation of [RepositoryDsl] + */ internal class BasicRepositoryDsl : RepositoryDsl { + + /** + * The repositories list + */ val repositories = mutableListOf() - var projectRepositories = false + /** + * Should project repositories be included? + */ + var includeProjectRepositories = false + + /** + * Adds the given repository to the repositories list + */ override fun maven(url: String) { repositories.add(url) } - override fun useProjectRepositories() { - projectRepositories = true + /** + * Tells Zapper to include the project repositories for + * resolving dependencies + */ + override fun includeProjectRepositories() { + includeProjectRepositories = true } } -data class Relocation( - val pattern: String, - val newPattern: String -)