Skip to content

Add AndroidApplicationStorytaleGradlePlugin #76

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 3 commits into
base: main
Choose a base branch
from
Draft

Conversation

congvc-dev
Copy link
Collaborator

@congvc-dev congvc-dev commented May 16, 2025

this PR fixes long awaited #38.
I tested with my local android app module but didn't commit because it isn't necessarily.

@congvc-dev congvc-dev requested a review from JSMonk May 16, 2025 15:53
@congvc-dev congvc-dev self-assigned this May 16, 2025
@congvc-dev congvc-dev linked an issue May 16, 2025 that may be closed by this pull request
@congvc-dev congvc-dev marked this pull request as ready for review May 16, 2025 15:57
@JSMonk
Copy link
Member

JSMonk commented May 18, 2025

By the way, @congvc-dev, I haven't found your contacts, so I will put them here.
We've added you to the core contributors (because you've made so many fantastic contributions to this project).
We have a call with all the core contributors once a month, so if you would like to join, please send me your contact information in the DM of our Kotlin community Slack.
Thank you a lot for all these magical contributions you introduced 🧙

@congvc-dev
Copy link
Collaborator Author

I think im at my limit of knowledge here. Somehow my android app module doesn't register stories sourceset as a build type. Here is my code setup. Someone please help out 🙏

@congvc-dev congvc-dev marked this pull request as draft May 18, 2025 15:41
@whitescent
Copy link
Collaborator

Hi @congvc-dev 👋, Thank you for your contribution to this issue! I also tried to do some research

for android projects, it seems that you can't directly add a custom sourceSet. Instead, you need to create a flavor to set the corresponding sourceSets (I'm not sure if this is the correct approach).

image

but i'm currently not sure how to configure the existing Gradle plugin task for the corresponding flavor.

applicationExtension.applicationVariants
.matching { it.name == StorytaleGradlePlugin.STORYTALE_EXEC_SUFFIX }
.configureEach {
val generatorTask = createAndroidStorytaleGenerateSourceTask(
target,
this,
storytaleBuildSourcesDir,
storytaleBuildResourcesDir,
)
extension.project.tasks
.matching { it.name == "process${StorytaleGradlePlugin.STORYTALE_EXEC_SUFFIX}MainManifest" }
.configureEach { dependsOn(generatorTask) }

Also, I think we might need to do some handling in AndroidMultiplatformTask.kt to configure different dependencies based on KMP or a standalone Android project.

target.compilations
.matching { it.name == StorytaleGradlePlugin.STORYTALE_EXEC_SUFFIX }
.configureEach {
associateWith(target.compilations.getByName("debug"))
compileTaskProvider.configure {
dependsOn(generatorTask)
dependsOn(":generateResourceAccessorsForCommonStories")

For example, the task :generateResourceAccessorsForCommonStories doesn't seem like it should be used in non-multiplatform projects.

@congvc-dev
Copy link
Collaborator Author

@whitescent, good approach! Thanks for untying the knot for me. I'll try look into it later this weekend

@congvc-dev
Copy link
Collaborator Author

@JSMonk, can you shoot me a DM? here is my profile in kotlinlang slack

@@ -14,12 +14,20 @@ import org.jetbrains.kotlin.gradle.targets.jvm.KotlinJvmTarget
class StorytaleGradlePlugin : KotlinCompilerPluginSupportPlugin {

override fun apply(project: Project) {
project.plugins.withId("org.jetbrains.kotlin.multiplatform") {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@eymar, Am I right that withId works lazily, so that the order of the plugins application doesn't matter if we use withId?

Copy link
Collaborator

@eymar eymar May 26, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

according to the documentation:

     * Executes or registers an action for a plugin with given id.
     * If the plugin was already applied, the action is executed.
     * If the plugin is applied sometime later the action will be executed after the plugin is applied.
     * If the plugin is never applied, the action is never executed.

so yes, the order of apply(plugin) calls doesn't matter when using withId.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the new implementation I see on the right side would require a strict order of plugins: Storytale would need to be registered after all other plugins - it's error prone. Ideally the order shouldn't matter.

Using nested withId is a solution which come to my mind. And btw I see it used to be here below.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So, yep, this is what I'm afraid of. @congvc-dev, could you rework it using the withId approach?

@@ -32,17 +40,17 @@ class StorytaleGradlePlugin : KotlinCompilerPluginSupportPlugin {
override fun applyToCompilation(kotlinCompilation: KotlinCompilation<*>) = kotlinCompilation.target.project.provider { emptyList<SubpluginOption>() }

private fun Project.processConfigurations(extension: StorytaleExtension) {
extension.targets.all {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@eymar Does all also work lazily?

Copy link
Collaborator

@eymar eymar May 26, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Executes the given action against all objects in this collection, and any objects subsequently added to this collection.

So yes, all {} will be invoked on all targets added before and after.

forEach will just iterate on the current state of the collection.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The same here. @congvc-dev could you use all instead of the forEach?

val composeEnabled = project.plugins.hasPlugin("org.jetbrains.compose")
val composePluginEnabled = project.plugins.hasPlugin("org.jetbrains.kotlin.plugin.compose")
if (
(composeEnabled || composePluginEnabled) &&
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Storytale strictly requires org.jetbrains.compose rather than org.jetbrains.kotlin.plugin.compose. So || is rather incorrect.

Did you want to make the new plugin to work on android without Compose Multiplatform?

@@ -32,17 +40,17 @@ class StorytaleGradlePlugin : KotlinCompilerPluginSupportPlugin {
override fun applyToCompilation(kotlinCompilation: KotlinCompilation<*>) = kotlinCompilation.target.project.provider { emptyList<SubpluginOption>() }

private fun Project.processConfigurations(extension: StorytaleExtension) {
extension.targets.all {
when (this) {
extension.targets.forEach {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why was all replaced by forEach?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

support Android native project
4 participants