SpineEventEngine / mc-java

Model Compiler for Java
Apache License 2.0
0 stars 2 forks source link

Apply script plugin to configure modules #81

Closed alexander-yevsyukov closed 1 year ago

alexander-yevsyukov commented 1 year ago

This PR partially applies the approach for configuring project modules using a script plugin, conventionally called module.gradle.kts. This approach was recently introduced in ProtoData, and then adopted in Validation.

Why does this PR do it patially, and what does it mean?

It means that part of the module (i.e. a Gradle subproject) in mc-java still has to be configured on the level of the root build.gradle.kts because of the following. These parts are:

  1. Configuring ProtoData — the protoData { } block.
  2. Adding user classpath dependency for ProtoData — the dependencies { protoData(...) } block.

Why is it so?

  1. Unlike ProtoData and Validation — which use McJava plugin for code generation — McJava itself relies on ProtoData and configures it via DSL provided by the ProtoData Gradle plugin.

  2. In order to use this DSL the plugin in a script plugin, the ProtoData Gradle plugin must be added as implementation dependency to buildSrc/build.gradle.kts. We cannot add the plugin via plugins { } syntax because it is not a core plugin, AND the version syntax for plugins is not allowed at the level of script plugins. We have to use only implementation dependency of buildSrc.

  3. The implementation("io.spine:protodata:$protoDataVersion") cannot be fully resolved because ProtoData Gradle plugin is not a fat JAR. Its dependencies cannot be resolved at the level of buildSrc/build.gradle.kts because the repositories where these artifacts reside could not be added yet. All our machinery with repositories.standardToSpineSdk() becomes available only after the root script compiles. We can probably duplicate the code of accessing these directories in buildSrc/build.gradle.kts. But it feels as too much work and code duplication for very little gain.

Possible solution to this issue

... could be turning ProtoData into a FAT jar someday so that users can use it in various places without being tied to our repositories.

Note on plugins at the root level

Because of not being able to use io.spine.protodata plugin as script implementation dependency, we have to have java plugin enabled at the root project. We could avoid it in ProtoData and Validation, but cannot do it in McJava, because this plugin is required by Protobuf Gradle Plugin and ProtoData.

alexander-yevsyukov commented 1 year ago

@armiol, I've tried to push it a big further in #82 (following this one). But there's a strange build anomaly about building mc-java-validation module on applying Protobuf Gradle Plugin:

Caused by: org.gradle.api.internal.AbstractMutationGuard$IllegalMutationException: Project#afterEvaluate(Closure) on project ':mc-java-validation' cannot be executed in the current context.
        at org.gradle.api.internal.AbstractMutationGuard.createIllegalStateException(AbstractMutationGuard.java:39)
        at org.gradle.api.internal.AbstractMutationGuard.assertMutationAllowed(AbstractMutationGuard.java:34)
        at org.gradle.api.internal.project.DefaultProject.assertMutatingMethodAllowed(DefaultProject.java:1449)
        at org.gradle.api.internal.project.DefaultProject.afterEvaluate(DefaultProject.java:1066)
        at org.gradle.api.Project$afterEvaluate.call(Unknown Source)
        at com.google.protobuf.gradle.ProtobufPlugin.doApply(ProtobufPlugin.groovy:151)
        at com.google.protobuf.gradle.ProtobufPlugin.access$2(ProtobufPlugin.groovy)
        at com.google.protobuf.gradle.ProtobufPlugin$_apply_closure1.doCall(ProtobufPlugin.groovy:99)
        at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)

I'll try to give into it a bit deeper on Monday or Tuesday next week.