-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Prepared resourcemanager to be distributed as gradle plugin.
- Loading branch information
Showing
14 changed files
with
831 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
/build |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
plugins { | ||
`kotlin-dsl` | ||
java | ||
id("com.gradle.plugin-publish") version "1.3.0" | ||
} | ||
|
||
dependencies { | ||
implementation(gradleApi()) | ||
implementation(localGroovy()) | ||
} | ||
|
||
group = "dev.randos" | ||
version = "0.0.1" | ||
|
||
gradlePlugin { | ||
website.set("https://github.com/vsnappy1/ResourceManager") | ||
vcsUrl.set("https://github.com/vsnappy1/ResourceManager") | ||
plugins { | ||
create("resourcemanager") { | ||
id = "dev.randos.resourcemanager" | ||
implementationClass = "ResourceManagerPlugin" | ||
displayName = "Resource Manager" | ||
description = "ResourceManager is an Android plugin that simplifies accessing Android resources (strings, colors, drawables, etc.) in both Android and non-Android components (e.g., ViewModel) using generated code." | ||
tags.set(listOf("android", "androidResources", "codeGeneration")) | ||
} | ||
} | ||
} | ||
|
||
java { | ||
sourceCompatibility = JavaVersion.VERSION_1_8 | ||
targetCompatibility = JavaVersion.VERSION_1_8 | ||
} | ||
|
||
kotlin { | ||
jvmToolchain(8) | ||
} | ||
|
||
publishing { | ||
repositories { | ||
mavenLocal() | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
import dev.randos.resourcemanager.ResourceManagerGenerator | ||
import org.gradle.api.Plugin | ||
import org.gradle.api.Project | ||
import java.io.File | ||
|
||
class ResourceManagerPlugin : Plugin<Project> { | ||
override fun apply(project: Project) { | ||
val generatedFile = File(project.projectDir, "build/generated/resourcemanager/main/ResourceManager.kt") | ||
val resourceManager = ResourceManagerGenerator(project.projectDir, generatedFile) | ||
|
||
val generateResourceManagerTask = project.tasks.register("generateResourceManager") { | ||
inputs.files(resourceManager.getFilesUnderObservation()) | ||
outputs.files(generatedFile) | ||
doLast { | ||
resourceManager.generate() | ||
} | ||
} | ||
|
||
project.tasks.matching { it.name.startsWith("compile") } | ||
.configureEach { | ||
dependsOn(generateResourceManagerTask) | ||
} | ||
} | ||
} |
125 changes: 125 additions & 0 deletions
125
resourcemanager/src/main/kotlin/dev/randos/resourcemanager/ResourceManagerGenerator.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,125 @@ | ||
package dev.randos.resourcemanager | ||
|
||
import java.io.File | ||
|
||
import dev.randos.resourcemanager.model.Resource | ||
import dev.randos.resourcemanager.model.ResourceType | ||
import dev.randos.resourcemanager.model.ModuleDetails | ||
import dev.randos.resourcemanager.manager.ModuleManager | ||
import dev.randos.resourcemanager.file.generation.ClassFileGenerator | ||
|
||
internal class ResourceManagerGenerator( | ||
private val moduleFile: File, | ||
private val generatedFile: File | ||
) { | ||
|
||
fun generate() { | ||
|
||
val moduleManager = ModuleManager(moduleFile) | ||
val resources = getResources(moduleFile, moduleManager.getModuleDependencies()) | ||
|
||
try { | ||
// Create the new file with a dependency on all source files | ||
generatedFile.parentFile.mkdirs() | ||
|
||
// Write the generated class content to the file | ||
generatedFile.bufferedWriter().use { out -> | ||
|
||
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 | ||
) | ||
|
||
out.write(classFile) | ||
out.close() | ||
} | ||
} catch (e: Exception) { | ||
println("Error: ${e.localizedMessage}") | ||
e.printStackTrace() | ||
} | ||
} | ||
|
||
fun getFilesUnderObservation(): List<File> { | ||
val moduleManager = ModuleManager(moduleFile) | ||
val resources = getResources(moduleFile, moduleManager.getModuleDependencies()) | ||
return resources.getFilesUnderObservation() + listOf(moduleManager.getBuildGradleFile()) // Also observe the module build.gradle file. | ||
} | ||
|
||
/** | ||
* Scans the directory structure starting from the given file path to locate default resource file | ||
* within an Android project's res/values directories. | ||
* | ||
* @return A list of [Resource]. | ||
*/ | ||
private fun getResources( | ||
moduleFile: File, | ||
moduleDependencies: List<String> | ||
): List<Resource> { | ||
val list = mutableListOf<Resource>() | ||
|
||
var resFile = File(moduleFile, "src/main/res") | ||
|
||
// Locate the "values" directory within the "res" directory. | ||
list.add( | ||
Resource( | ||
type = ResourceType.VALUES, | ||
moduleDetails = ModuleDetails(resDirectory = File(resFile, "values")) | ||
) | ||
) | ||
|
||
// Locate the "drawable" directory within the "res" directory. | ||
list.add( | ||
Resource( | ||
type = ResourceType.DRAWABLES, | ||
moduleDetails = ModuleDetails(resDirectory = File(resFile, "drawable")) | ||
) | ||
) | ||
|
||
/* | ||
Also add resources for project dependencies. (i.e. implementation(project(":my_library"))) | ||
*/ | ||
val projectFile = moduleFile.parentFile | ||
moduleDependencies.forEach { module -> | ||
val dependencyModuleFile = File(projectFile, module) | ||
resFile = File(dependencyModuleFile, "src/main/res") | ||
|
||
ModuleManager(dependencyModuleFile).getNamespace()?.let { namespace -> | ||
// Locate the "values" directory within the "res" directory. | ||
list.add( | ||
Resource( | ||
type = ResourceType.VALUES, | ||
moduleDetails = ModuleDetails(module, namespace, File(resFile, "values")) | ||
) | ||
) | ||
|
||
// Locate the "drawable" directory within the "res" directory. | ||
list.add( | ||
Resource( | ||
type = ResourceType.DRAWABLES, | ||
moduleDetails = ModuleDetails(module, namespace, File(resFile, "drawable")) | ||
) | ||
) | ||
} | ||
} | ||
return list | ||
} | ||
|
||
/** | ||
* Generates a list of all files within the directories specified by each `Resource` object. | ||
* | ||
* @receiver List of `Resource` objects, each containing a directory path. | ||
* @return A list of all files under each directory in the `Resource` list. | ||
*/ | ||
private fun List<Resource>.getFilesUnderObservation(): List<File> { | ||
val files = mutableListOf<File>() | ||
this.map { it.moduleDetails.resDirectory }.forEach { directory -> | ||
directory.walkTopDown().forEach { file -> | ||
if (file.isFile) { | ||
files.add(file) | ||
} | ||
} | ||
} | ||
return files | ||
} | ||
} |
Oops, something went wrong.