jraska / modules-graph-assert

Gradle plugin to keep your modules graph healthy and lean.
https://plugins.gradle.org/plugin/com.jraska.module.graph.assertion
Apache License 2.0
528 stars 22 forks source link

Kotlin Multiplatform support #249

Closed IsakTheHacker closed 1 week ago

IsakTheHacker commented 8 months ago

Currently the module graph assertion plugin doesn't recognize dependencies in KMP modules, even if the dependencies are declared for the commonMain target.

Ideas for the future (if this feature was added) If this feature were to be implemented I also think it should be possible to specify a compilation target to use when checking for dependencies and maybe also generate all different module graphs at once (just an idea)

jraska commented 8 months ago

Hey, thanks for reporting this :)

Do you have maybe an example multi-module project where I could quickly reproduce it? Thanks

Ideas for the future ...

Could you elaborate a bit please? Ideally pointing to example to understand. I would assume compilation target would translate to Gradle configuration?

IsakTheHacker commented 8 months ago

Hmm, none of my projects are public and it would take too much time to create a reproducible sample project, I am sorry. But in my case, I had an Android application module that depended on a multiplatform library module with a build.gradle file that looked something like this:

plugins {
    id 'org.jetbrains.kotlin.multiplatform'
}

kotlin {
    targets {
        jvm()
    }

    sourceSets {
        commonMain {
            dependencies {
                api project(path: ':secondlibrary')
            }
        }
    }
}

I then had a second library module, also multiplatform that was a dependency of the first library module with a similar build.gradle configuration. The first library module appeared on the graph, but not the second one, maybe because the application module was not multiplatform.

Try this configuration and see if you can reproduce the issue, or perhaps I could try to tackle this issue myself.

Could you elaborate a bit please? Ideally pointing to example to understand. I would assume compilation target would translate to Gradle configuration? Not really the dependency configuration, but maybe that is what Gradle uses internally (I don't know). I meant that you could also define dependencies specific to a platform in a multiplatform project:

sourceSets {
commonMain {
dependencies {
//Common dependencies that are included for all platforms. For example KMP dependencies such as kotlinx-coroutines
}
}
jvmMain {
dependencies {
//Java dependencies such as javax.inject
}
androidMain {
dependencies {
//Android dependencies that should not be included when building for other platforms
}
}
//And so on
}

My proposol would be that we could generate different graphs depending on the target platform. So for example when building the project for Android all dependencies in commonMain, androidMain and jvmMain would be included in the graph. Otherwise dependenices that aren't consumed in the current target would show up in the graph if you would have an iosMain source set for example. Another solution would be to mark the dependencies that aren't common with iOS only, Android only etc.

Thank you for responding so quickly and for creating and maintaining this awesome Gradle plugin :)

jeffreyliu8 commented 7 months ago

same request, in my kmm project, only the android wear project was able to generate the graph.

jraska commented 7 months ago

Hey, to evaluate the Kotlin Multiplatform support, I would appreciate a sample project where the issue can be reproduced.

As mentioned

it would take too much time to create a reproducible sample project, I am sorry

Therefore without existing sample project the cost of exploring this is too high.

lihenggui commented 2 months ago

Hi @jraska https://github.com/lihenggui/nowinkmp

You can use this project as an example. Run the ./generateModuleGraphs.sh script in the terminal, and you can see changes in the git. It couldn't detect the dependencies for multiplatform modules correctly.

VMihalatiuk commented 1 week ago

I found a solution and it works for KMP projects!

moduleGraphAssert {
        configurations += setOf("commonMainImplementation", "commonMainApi")
        restricted = arrayOf(...)
}

Thanks to @VladislavSumin for this trick!

jraska commented 1 week ago

Thanks @VMihalatiuk to report this. I added docs #286 and I close this issue - please reopen if it still would be a problem.

Separate change could be a detection of KMP automatically to avoid the need of explicit configuration, but if the configuration change is truly all for now I think it is good enough.