Skip to content

Commit

Permalink
Configured plugin to add generated ResourceManager class to sourceSets.
Browse files Browse the repository at this point in the history
  • Loading branch information
vsnappy1 committed Nov 12, 2024
1 parent 3bb1b95 commit a5485eb
Show file tree
Hide file tree
Showing 8 changed files with 49 additions and 18 deletions.
5 changes: 1 addition & 4 deletions app/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down Expand Up @@ -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)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
package com.randos.resourceprovider

import android.app.Application
import dev.randos.resourcemanager.InstallResourceManager

@InstallResourceManager
class ResourceProviderApp: Application(){

override fun onCreate() {
Expand Down
2 changes: 2 additions & 0 deletions build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -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())
}
11 changes: 7 additions & 4 deletions resourcemanager/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -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"
Expand All @@ -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 {
Expand Down
29 changes: 28 additions & 1 deletion resourcemanager/src/main/kotlin/ResourceManagerPlugin.kt
Original file line number Diff line number Diff line change
@@ -1,24 +1,51 @@
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<Project> {
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 {
resourceManager.generate()
}
}

// 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)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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)
Expand All @@ -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<File> {
val moduleManager = ModuleManager(moduleFile)
val resources = getResources(moduleFile, moduleManager.getModuleDependencies())
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
}

Expand Down Expand Up @@ -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
}

Expand All @@ -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
}

Expand All @@ -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
}
}
1 change: 1 addition & 0 deletions settings.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ pluginManagement {
includeGroupByRegex("androidx.*")
}
}
mavenLocal()
mavenCentral()
gradlePluginPortal()
}
Expand Down

0 comments on commit a5485eb

Please sign in to comment.