diff --git a/app/build.gradle.kts b/app/build.gradle.kts index 6e4127b..67e46b9 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -3,7 +3,7 @@ import java.util.Properties plugins { alias(libs.plugins.android.application) alias(libs.plugins.jetbrains.kotlin.android) - alias(libs.plugins.google.devtools.ksp) + id("dev.randos.resourcemanager") } android { @@ -74,9 +74,6 @@ dependencies { implementation(libs.androidx.material3) implementation ("androidx.compose.runtime:runtime-livedata:1.7.4") - implementation(project(":resourcemanager-runtime")) - ksp(project(":resourcemanager-compiler")) - testImplementation(libs.junit) androidTestImplementation(libs.androidx.junit) diff --git a/app/src/main/java/com/randos/resourceprovider/ResourceProviderApp.kt b/app/src/main/java/com/randos/resourceprovider/ResourceProviderApp.kt index 5579162..e78e61a 100644 --- a/app/src/main/java/com/randos/resourceprovider/ResourceProviderApp.kt +++ b/app/src/main/java/com/randos/resourceprovider/ResourceProviderApp.kt @@ -1,9 +1,7 @@ package com.randos.resourceprovider import android.app.Application -import dev.randos.resourcemanager.InstallResourceManager -@InstallResourceManager class ResourceProviderApp: Application(){ override fun onCreate() { diff --git a/build.gradle.kts b/build.gradle.kts index acfe973..a0ab49a 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -5,8 +5,10 @@ plugins { alias(libs.plugins.android.library) apply false alias(libs.plugins.jetbrains.kotlin.jvm) apply false alias(libs.plugins.google.devtools.ksp) apply false + id("dev.randos.resourcemanager") version "0.0.1" apply false } ext { set("kspVersion", libs.versions.kspVersion.get()) + set("agp", libs.versions.agp.get()) } \ No newline at end of file diff --git a/resourcemanager/build.gradle.kts b/resourcemanager/build.gradle.kts index d7a0551..ade5cb1 100644 --- a/resourcemanager/build.gradle.kts +++ b/resourcemanager/build.gradle.kts @@ -1,12 +1,15 @@ plugins { `kotlin-dsl` - java + kotlin("jvm") + id("java-gradle-plugin") id("com.gradle.plugin-publish") version "1.3.0" } +val agp: String by project dependencies { implementation(gradleApi()) implementation(localGroovy()) + compileOnly("com.android.tools.build:gradle:$agp") } group = "dev.randos" @@ -27,12 +30,12 @@ gradlePlugin { } java { - sourceCompatibility = JavaVersion.VERSION_1_8 - targetCompatibility = JavaVersion.VERSION_1_8 + sourceCompatibility = JavaVersion.VERSION_11 + targetCompatibility = JavaVersion.VERSION_11 } kotlin { - jvmToolchain(8) + jvmToolchain(11) } publishing { diff --git a/resourcemanager/src/main/kotlin/ResourceManagerPlugin.kt b/resourcemanager/src/main/kotlin/ResourceManagerPlugin.kt index ba96e24..1124065 100644 --- a/resourcemanager/src/main/kotlin/ResourceManagerPlugin.kt +++ b/resourcemanager/src/main/kotlin/ResourceManagerPlugin.kt @@ -1,14 +1,33 @@ +import com.android.build.gradle.BaseExtension import dev.randos.resourcemanager.ResourceManagerGenerator +import dev.randos.resourcemanager.manager.ModuleManager import org.gradle.api.Plugin import org.gradle.api.Project import java.io.File +/** + * A Gradle plugin that simplifies accessing Android resources (e.g., strings, colors, drawables) + * in both Android and non-Android components (e.g., ViewModel) using generated code. + * This plugin generates a Kotlin file containing resource access code and configures the build + * process to ensure the generated code is included in the project's source sets. + */ class ResourceManagerPlugin : Plugin { override fun apply(project: Project) { - val generatedFile = File(project.projectDir, "build/generated/resourcemanager/main/ResourceManager.kt") + + // Define the location of the generated Kotlin file containing resource management code. + val mainDirectory = File(project.projectDir, "build/generated/source/resourcemanager/main") + val namespacePath = ModuleManager(project.projectDir).getNamespace()?.replace(".","/") + val generatedFile = File(mainDirectory, "$namespacePath/ResourceManager.kt") + + // Initialize the ResourceManagerGenerator responsible for generating the Kotlin code. val resourceManager = ResourceManagerGenerator(project.projectDir, generatedFile) + // Register a new Gradle task to generate the ResourceManager code. val generateResourceManagerTask = project.tasks.register("generateResourceManager") { + + // Define the input and output files for the task. This ensures that the task is only executed + // when there is a change in any of the input files or the output file, optimizing the build process + // by avoiding unnecessary task executions. inputs.files(resourceManager.getFilesUnderObservation()) outputs.files(generatedFile) doLast { @@ -16,9 +35,17 @@ class ResourceManagerPlugin : Plugin { } } + // Ensure that the "generateResourceManager" task runs before any compile task. project.tasks.matching { it.name.startsWith("compile") } .configureEach { dependsOn(generateResourceManagerTask) } + + // Add the generated file to the Kotlin source sets so that it can be used as part of the build. + project.extensions.getByType(BaseExtension::class.java) + .sourceSets + .getByName("main") + .kotlin + .srcDir(mainDirectory) } } \ No newline at end of file diff --git a/resourcemanager/src/main/kotlin/dev/randos/resourcemanager/ResourceManagerGenerator.kt b/resourcemanager/src/main/kotlin/dev/randos/resourcemanager/ResourceManagerGenerator.kt index 48aedac..726314d 100644 --- a/resourcemanager/src/main/kotlin/dev/randos/resourcemanager/ResourceManagerGenerator.kt +++ b/resourcemanager/src/main/kotlin/dev/randos/resourcemanager/ResourceManagerGenerator.kt @@ -16,10 +16,9 @@ internal class ResourceManagerGenerator( fun generate() { val moduleManager = ModuleManager(moduleFile) - val resources = getResources(moduleFile, moduleManager.getModuleDependencies()) try { - // Create the new file with a dependency on all source files + // Ensure directory exists before writing to the file. generatedFile.parentFile.mkdirs() // Write the generated class content to the file @@ -28,7 +27,7 @@ internal class ResourceManagerGenerator( val classFile = ClassFileGenerator.generateClassFile( namespace = moduleManager.getNamespace() ?: throw IllegalStateException("Namespace could not be found in either build.gradle, build.gradle.kts or AndroidManifest.xml. Please ensure the module is properly configured."), - files = resources + files = getResources(moduleFile, moduleManager.getModuleDependencies()) ) out.write(classFile) @@ -40,6 +39,10 @@ internal class ResourceManagerGenerator( } } + /** + * Returns resource files under observation such as strings.xml, dimens.xml, ic_gift.png etc, + * which are taken as input to generate ResourceManager (a generated class). + */ fun getFilesUnderObservation(): List { val moduleManager = ModuleManager(moduleFile) val resources = getResources(moduleFile, moduleManager.getModuleDependencies()) diff --git a/resourcemanager/src/main/kotlin/dev/randos/resourcemanager/manager/ModuleManager.kt b/resourcemanager/src/main/kotlin/dev/randos/resourcemanager/manager/ModuleManager.kt index 89b15dd..7839a11 100644 --- a/resourcemanager/src/main/kotlin/dev/randos/resourcemanager/manager/ModuleManager.kt +++ b/resourcemanager/src/main/kotlin/dev/randos/resourcemanager/manager/ModuleManager.kt @@ -98,7 +98,7 @@ class ModuleManager(private val moduleFile: File) { gradleFile = File(moduleFile, "build.gradle.kts") } if (!gradleFile.exists()) { - println("Error: Failed to find build.gradle/build.gradle.kts at path: ${gradleFile.absolutePath}") + println("Could not find build.gradle(.kts) at path: ${gradleFile.absolutePath}") return null } @@ -131,7 +131,7 @@ class ModuleManager(private val moduleFile: File) { } } - println("Error: Failed to find namespace in gradle file at path: ${gradleFile.absolutePath}") + println("Could not find namespace in gradle file at path: ${gradleFile.absolutePath}") return null } @@ -143,7 +143,7 @@ class ModuleManager(private val moduleFile: File) { private fun getNamespaceFromManifest(): String? { val manifestFile = File(moduleFile, "src/main/AndroidManifest.xml") if (!manifestFile.exists()) { - println("Error: Failed to find AndroidManifest.xml at path: ${manifestFile.absolutePath}") + println("Could not find AndroidManifest.xml at path: ${manifestFile.absolutePath}") return null } @@ -161,7 +161,7 @@ class ModuleManager(private val moduleFile: File) { e.printStackTrace() } - println("Error: Failed to find attribute `package` in AndroidManifest.xml at path: ${manifestFile.absolutePath}") + println("Could not find attribute `package` in AndroidManifest.xml at path: ${manifestFile.absolutePath}") return null } } \ No newline at end of file diff --git a/settings.gradle.kts b/settings.gradle.kts index 7b8d5d4..b496637 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -7,6 +7,7 @@ pluginManagement { includeGroupByRegex("androidx.*") } } + mavenLocal() mavenCentral() gradlePluginPortal() }