utopia-rise / godot-kotlin-jvm

Godot Kotlin JVM Module
MIT License
576 stars 39 forks source link

Gradle Plugin fails with NullPointerException when used in a multi-module build #546

Closed MartinHaeusler closed 8 months ago

MartinHaeusler commented 8 months ago

My build setup is a fairly standard multi-module build and looks as follows:

root
  - build.gradle.kts
  - settings.gradle.kts
  - client                             (godot project lives here)
    -  build.gradle.kts
  - common
    - build.gradle.kts
  - server
    - build.gradle.kts 

The root build.gradle.kts looks like this:

plugins {
    id("org.jetbrains.kotlin.jvm") version "1.9.0" apply false
    id("com.utopia-rise.godot-kotlin-jvm") version "0.7.2-4.1.2" apply false
}

allprojects {

    repositories {
        mavenCentral()
    }

}

... and the client build.gradle.kts looks like this:

plugins {
    // the following dependencies have no versions attached to them on purpose,
    // because the versions are managed in the root "build.gradle.kts" file.
    id("org.jetbrains.kotlin.jvm")
    id("com.utopia-rise.godot-kotlin-jvm")
}

The other build.gradle.kts files are empty. The settings.gradle.kts looks like this:

rootProject.name = "mygame"
include("client")
include("server")
include("common")

From my point of view, this should work. Sadly, I get a NullPointerException when I attempt to run even basic gradle tasks (such as ./gradlew projects):

 org.gradle.api.internal.provider.AbstractProperty$PropertyQueryException: Failed to query the value of property 'buildFlowServiceProperty'.
   at org.gradle.api.internal.provider.AbstractProperty.doCalculateValue(AbstractProperty.java:145)
   at org.gradle.api.internal.provider.AbstractProperty.calculateOwnValue(AbstractProperty.java:136)
   at org.gradle.api.internal.provider.AbstractMinimalProvider.calculateOwnPresentValue(AbstractMinimalProvider.java:80)
   at org.gradle.api.internal.provider.AbstractMinimalProvider.get(AbstractMinimalProvider.java:100)
   at org.jetbrains.kotlin.gradle.plugin.BuildFinishFlowAction.execute(StatisticsBuildFlowManager.kt:75)
   at org.jetbrains.kotlin.gradle.plugin.BuildFinishFlowAction.execute(StatisticsBuildFlowManager.kt:61)
   at org.gradle.configurationcache.flow.FlowScheduler.schedule(FlowScheduler.kt:48)
   at org.gradle.configurationcache.flow.BuildFlowScope.schedulePendingActions(BuildFlowScope.kt:140)
   at org.gradle.configurationcache.flow.BuildFlowScope.buildFinished(BuildFlowScope.kt:118)
   at jdk.internal.reflect.GeneratedMethodAccessor48.invoke(Unknown Source)
   at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
   at java.base/java.lang.reflect.Method.invoke(Method.java:568)
   at org.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:36)
   at org.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:24)
   at org.gradle.internal.event.DefaultListenerManager$ListenerDetails.dispatch(DefaultListenerManager.java:472)
   at org.gradle.internal.event.DefaultListenerManager$ListenerDetails.dispatch(DefaultListenerManager.java:454)
   at org.gradle.internal.event.AbstractBroadcastDispatch.dispatch(AbstractBroadcastDispatch.java:83)
   at org.gradle.internal.event.AbstractBroadcastDispatch.dispatch(AbstractBroadcastDispatch.java:69)
   at org.gradle.internal.event.DefaultListenerManager$EventBroadcast$ListenerDispatch.dispatch(DefaultListenerManager.java:443)
   at org.gradle.internal.event.DefaultListenerManager$EventBroadcast$ListenerDispatch.dispatch(DefaultListenerManager.java:431)
   at org.gradle.internal.event.AbstractBroadcastDispatch.dispatch(AbstractBroadcastDispatch.java:43)
   at org.gradle.internal.event.BroadcastDispatch$SingletonDispatch.dispatch(BroadcastDispatch.java:268)
   at org.gradle.internal.event.BroadcastDispatch$SingletonDispatch.dispatch(BroadcastDispatch.java:170)
   at org.gradle.internal.event.AbstractBroadcastDispatch.dispatch(AbstractBroadcastDispatch.java:83)
   at org.gradle.internal.event.AbstractBroadcastDispatch.dispatch(AbstractBroadcastDispatch.java:69)
   at org.gradle.internal.event.BroadcastDispatch$CompositeDispatch.dispatch(BroadcastDispatch.java:381)
   at org.gradle.internal.event.BroadcastDispatch$CompositeDispatch.dispatch(BroadcastDispatch.java:272)
   at org.gradle.internal.event.ListenerBroadcast.dispatch(ListenerBroadcast.java:148)
   at org.gradle.internal.event.ListenerBroadcast.dispatch(ListenerBroadcast.java:37)
   at org.gradle.internal.dispatch.ProxyDispatchAdapter$DispatchingInvocationHandler.invoke(ProxyDispatchAdapter.java:94)
   at jdk.proxy1/jdk.proxy1.$Proxy36.buildFinished(Unknown Source)
   at org.gradle.internal.build.DefaultBuildLifecycleController.lambda$finishBuild$11(DefaultBuildLifecycleController.java:346)
   at org.gradle.internal.build.ExecutionResult.maybeFailing(ExecutionResult.java:94)
   at org.gradle.internal.build.DefaultBuildLifecycleController.lambda$finishBuild$12(DefaultBuildLifecycleController.java:346)
   at org.gradle.internal.model.StateTransitionController.doTransitionWithFailures(StateTransitionController.java:241)
   at org.gradle.internal.model.StateTransitionController.lambda$transition$13(StateTransitionController.java:232)
   at org.gradle.internal.work.DefaultSynchronizer.withLock(DefaultSynchronizer.java:44)
   at org.gradle.internal.model.StateTransitionController.transition(StateTransitionController.java:229)
   at org.gradle.internal.build.DefaultBuildLifecycleController.finishBuild(DefaultBuildLifecycleController.java:336)
   at org.gradle.internal.buildtree.DefaultBuildTreeFinishExecutor.finishBuildTree(DefaultBuildTreeFinishExecutor.java:57)
   at org.gradle.composite.internal.OperationFiringBuildTreeFinishExecutor$1.call(OperationFiringBuildTreeFinishExecutor.java:46)
   at org.gradle.composite.internal.OperationFiringBuildTreeFinishExecutor$1.call(OperationFiringBuildTreeFinishExecutor.java:42)
   at org.gradle.internal.operations.DefaultBuildOperationRunner$CallableBuildOperationWorker.execute(DefaultBuildOperationRunner.java:204)
   at org.gradle.internal.operations.DefaultBuildOperationRunner$CallableBuildOperationWorker.execute(DefaultBuildOperationRunner.java:199)
   at org.gradle.internal.operations.DefaultBuildOperationRunner$2.execute(DefaultBuildOperationRunner.java:66)
   at org.gradle.internal.operations.DefaultBuildOperationRunner$2.execute(DefaultBuildOperationRunner.java:59)
   at org.gradle.internal.operations.DefaultBuildOperationRunner.execute(DefaultBuildOperationRunner.java:157)
   at org.gradle.internal.operations.DefaultBuildOperationRunner.execute(DefaultBuildOperationRunner.java:59)
   at org.gradle.internal.operations.DefaultBuildOperationRunner.call(DefaultBuildOperationRunner.java:53)
   at org.gradle.internal.operations.DefaultBuildOperationExecutor.call(DefaultBuildOperationExecutor.java:73)
   at org.gradle.composite.internal.OperationFiringBuildTreeFinishExecutor.finishBuildTree(OperationFiringBuildTreeFinishExecutor.java:42)
   at org.gradle.internal.buildtree.DefaultBuildTreeLifecycleController.lambda$runBuild$4(DefaultBuildTreeLifecycleController.java:124)
   at org.gradle.internal.model.StateTransitionController.lambda$transition$6(StateTransitionController.java:169)
   at org.gradle.internal.model.StateTransitionController.doTransition(StateTransitionController.java:266)
   at org.gradle.internal.model.StateTransitionController.lambda$transition$7(StateTransitionController.java:169)
   at org.gradle.internal.work.DefaultSynchronizer.withLock(DefaultSynchronizer.java:44)
   at org.gradle.internal.model.StateTransitionController.transition(StateTransitionController.java:169)
   at org.gradle.internal.buildtree.DefaultBuildTreeLifecycleController.runBuild(DefaultBuildTreeLifecycleController.java:116)
   at org.gradle.internal.buildtree.DefaultBuildTreeLifecycleController.scheduleAndRunTasks(DefaultBuildTreeLifecycleController.java:76)
   at org.gradle.internal.buildtree.DefaultBuildTreeLifecycleController.scheduleAndRunTasks(DefaultBuildTreeLifecycleController.java:71)
   at org.gradle.tooling.internal.provider.ExecuteBuildActionRunner.run(ExecuteBuildActionRunner.java:31)
   at org.gradle.launcher.exec.ChainingBuildActionRunner.run(ChainingBuildActionRunner.java:35)
   at org.gradle.internal.buildtree.ProblemReportingBuildActionRunner.run(ProblemReportingBuildActionRunner.java:49)
   at org.gradle.launcher.exec.BuildOutcomeReportingBuildActionRunner.run(BuildOutcomeReportingBuildActionRunner.java:65)
   at org.gradle.tooling.internal.provider.FileSystemWatchingBuildActionRunner.run(FileSystemWatchingBuildActionRunner.java:140)
   at org.gradle.launcher.exec.BuildCompletionNotifyingBuildActionRunner.run(BuildCompletionNotifyingBuildActionRunner.java:41)
   at org.gradle.launcher.exec.RootBuildLifecycleBuildActionExecutor.lambda$execute$0(RootBuildLifecycleBuildActionExecutor.java:40)
   at org.gradle.composite.internal.DefaultRootBuildState.run(DefaultRootBuildState.java:123)
   at org.gradle.launcher.exec.RootBuildLifecycleBuildActionExecutor.execute(RootBuildLifecycleBuildActionExecutor.java:40)
   at org.gradle.internal.buildtree.InitDeprecationLoggingActionExecutor.execute(InitDeprecationLoggingActionExecutor.java:62)
   at org.gradle.internal.buildtree.InitProblems.execute(InitProblems.java:38)
   at org.gradle.internal.buildtree.DefaultBuildTreeContext.execute(DefaultBuildTreeContext.java:40)
   at org.gradle.launcher.exec.BuildTreeLifecycleBuildActionExecutor.lambda$execute$0(BuildTreeLifecycleBuildActionExecutor.java:58)
   at org.gradle.internal.buildtree.BuildTreeState.run(BuildTreeState.java:58)
   at org.gradle.launcher.exec.BuildTreeLifecycleBuildActionExecutor.execute(BuildTreeLifecycleBuildActionExecutor.java:58)
   at org.gradle.launcher.exec.RunAsBuildOperationBuildActionExecutor$3.call(RunAsBuildOperationBuildActionExecutor.java:61)
   at org.gradle.launcher.exec.RunAsBuildOperationBuildActionExecutor$3.call(RunAsBuildOperationBuildActionExecutor.java:57)
   at org.gradle.internal.operations.DefaultBuildOperationRunner$CallableBuildOperationWorker.execute(DefaultBuildOperationRunner.java:204)
   at org.gradle.internal.operations.DefaultBuildOperationRunner$CallableBuildOperationWorker.execute(DefaultBuildOperationRunner.java:199)
   at org.gradle.internal.operations.DefaultBuildOperationRunner$2.execute(DefaultBuildOperationRunner.java:66)
   at org.gradle.internal.operations.DefaultBuildOperationRunner$2.execute(DefaultBuildOperationRunner.java:59)
   at org.gradle.internal.operations.DefaultBuildOperationRunner.execute(DefaultBuildOperationRunner.java:157)
   at org.gradle.internal.operations.DefaultBuildOperationRunner.execute(DefaultBuildOperationRunner.java:59)
   at org.gradle.internal.operations.DefaultBuildOperationRunner.call(DefaultBuildOperationRunner.java:53)
   at org.gradle.internal.operations.DefaultBuildOperationExecutor.call(DefaultBuildOperationExecutor.java:73)
   at org.gradle.launcher.exec.RunAsBuildOperationBuildActionExecutor.execute(RunAsBuildOperationBuildActionExecutor.java:57)
   at org.gradle.launcher.exec.RunAsWorkerThreadBuildActionExecutor.lambda$execute$0(RunAsWorkerThreadBuildActionExecutor.java:36)
   at org.gradle.internal.work.DefaultWorkerLeaseService.withLocks(DefaultWorkerLeaseService.java:264)
   at org.gradle.internal.work.DefaultWorkerLeaseService.runAsWorkerThread(DefaultWorkerLeaseService.java:128)
   at org.gradle.launcher.exec.RunAsWorkerThreadBuildActionExecutor.execute(RunAsWorkerThreadBuildActionExecutor.java:36)
   at org.gradle.tooling.internal.provider.continuous.ContinuousBuildActionExecutor.execute(ContinuousBuildActionExecutor.java:110)
   at org.gradle.tooling.internal.provider.SubscribableBuildActionExecutor.execute(SubscribableBuildActionExecutor.java:64)
   at org.gradle.internal.session.DefaultBuildSessionContext.execute(DefaultBuildSessionContext.java:46)
   at org.gradle.tooling.internal.provider.BuildSessionLifecycleBuildActionExecuter$ActionImpl.apply(BuildSessionLifecycleBuildActionExecuter.java:92)
   at org.gradle.tooling.internal.provider.BuildSessionLifecycleBuildActionExecuter$ActionImpl.apply(BuildSessionLifecycleBuildActionExecuter.java:80)
   at org.gradle.internal.session.BuildSessionState.run(BuildSessionState.java:69)
   at org.gradle.tooling.internal.provider.BuildSessionLifecycleBuildActionExecuter.execute(BuildSessionLifecycleBuildActionExecuter.java:62)
   at org.gradle.tooling.internal.provider.BuildSessionLifecycleBuildActionExecuter.execute(BuildSessionLifecycleBuildActionExecuter.java:41)
   at org.gradle.tooling.internal.provider.StartParamsValidatingActionExecuter.execute(StartParamsValidatingActionExecuter.java:64)
   at org.gradle.tooling.internal.provider.StartParamsValidatingActionExecuter.execute(StartParamsValidatingActionExecuter.java:32)
   at org.gradle.tooling.internal.provider.SessionFailureReportingActionExecuter.execute(SessionFailureReportingActionExecuter.java:51)
   at org.gradle.tooling.internal.provider.SessionFailureReportingActionExecuter.execute(SessionFailureReportingActionExecuter.java:39)
   at org.gradle.tooling.internal.provider.SetupLoggingActionExecuter.execute(SetupLoggingActionExecuter.java:47)
   at org.gradle.tooling.internal.provider.SetupLoggingActionExecuter.execute(SetupLoggingActionExecuter.java:31)
   at org.gradle.launcher.daemon.server.exec.ExecuteBuild.doBuild(ExecuteBuild.java:65)
   at org.gradle.launcher.daemon.server.exec.BuildCommandOnly.execute(BuildCommandOnly.java:37)
   at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:104)
   at org.gradle.launcher.daemon.server.exec.WatchForDisconnection.execute(WatchForDisconnection.java:39)
   at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:104)
   at org.gradle.launcher.daemon.server.exec.ResetDeprecationLogger.execute(ResetDeprecationLogger.java:29)
   at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:104)
   at org.gradle.launcher.daemon.server.exec.RequestStopIfSingleUsedDaemon.execute(RequestStopIfSingleUsedDaemon.java:35)
   at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:104)
   at org.gradle.launcher.daemon.server.exec.ForwardClientInput$2.create(ForwardClientInput.java:78)
   at org.gradle.launcher.daemon.server.exec.ForwardClientInput$2.create(ForwardClientInput.java:75)
   at org.gradle.util.internal.Swapper.swap(Swapper.java:38)
   at org.gradle.launcher.daemon.server.exec.ForwardClientInput.execute(ForwardClientInput.java:75)
   at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:104)
   at org.gradle.launcher.daemon.server.exec.LogAndCheckHealth.execute(LogAndCheckHealth.java:64)
   at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:104)
   at org.gradle.launcher.daemon.server.exec.LogToClient.doBuild(LogToClient.java:63)
   at org.gradle.launcher.daemon.server.exec.BuildCommandOnly.execute(BuildCommandOnly.java:37)
   at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:104)
   at org.gradle.launcher.daemon.server.exec.EstablishBuildEnvironment.doBuild(EstablishBuildEnvironment.java:84)
   at org.gradle.launcher.daemon.server.exec.BuildCommandOnly.execute(BuildCommandOnly.java:37)
   at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:104)
   at org.gradle.launcher.daemon.server.exec.StartBuildOrRespondWithBusy$1.run(StartBuildOrRespondWithBusy.java:52)
   at org.gradle.launcher.daemon.server.DaemonStateCoordinator$1.run(DaemonStateCoordinator.java:297)
   at org.gradle.internal.concurrent.ExecutorPolicy$CatchAndRecordFailures.onExecute(ExecutorPolicy.java:64)
   at org.gradle.internal.concurrent.AbstractManagedExecutor$1.run(AbstractManagedExecutor.java:47)
   at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1136)
   at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635)
   at java.base/java.lang.Thread.run(Thread.java:840)
 Caused by: org.gradle.internal.snapshot.impl.IsolationException: Could not isolate value org.jetbrains.kotlin.gradle.plugin.statistics.BuildFlowService$Parameters_Decorated@31d3723b of type BuildFlowService.Parameters
   at org.gradle.internal.snapshot.impl.DefaultIsolatableFactory.isolate(DefaultIsolatableFactory.java:51)
   at org.gradle.api.services.internal.RegisteredBuildServiceProvider.instantiate(RegisteredBuildServiceProvider.java:127)
   at org.gradle.api.services.internal.RegisteredBuildServiceProvider.getInstance(RegisteredBuildServiceProvider.java:118)
   at org.gradle.api.services.internal.RegisteredBuildServiceProvider.calculateOwnValue(RegisteredBuildServiceProvider.java:111)
   at org.gradle.api.internal.provider.AbstractMinimalProvider.calculateValue(AbstractMinimalProvider.java:115)
   at org.gradle.api.internal.provider.DefaultProperty.calculateValueFrom(DefaultProperty.java:128)
   at org.gradle.api.internal.provider.DefaultProperty.calculateValueFrom(DefaultProperty.java:26)
   at org.gradle.api.internal.provider.AbstractProperty.doCalculateValue(AbstractProperty.java:142)
   ... 132 more
 Caused by: org.gradle.api.ProjectConfigurationException: A problem occurred configuring project ':client'.
   at org.gradle.configuration.project.LifecycleProjectEvaluator.wrapException(LifecycleProjectEvaluator.java:84)
   at org.gradle.configuration.project.LifecycleProjectEvaluator.addConfigurationFailure(LifecycleProjectEvaluator.java:77)
   at org.gradle.configuration.project.LifecycleProjectEvaluator.access$500(LifecycleProjectEvaluator.java:55)
   at org.gradle.configuration.project.LifecycleProjectEvaluator$NotifyAfterEvaluate.run(LifecycleProjectEvaluator.java:255)
   at org.gradle.internal.operations.DefaultBuildOperationRunner$1.execute(DefaultBuildOperationRunner.java:29)
   at org.gradle.internal.operations.DefaultBuildOperationRunner$1.execute(DefaultBuildOperationRunner.java:26)
   at org.gradle.internal.operations.DefaultBuildOperationRunner$2.execute(DefaultBuildOperationRunner.java:66)
   at org.gradle.internal.operations.DefaultBuildOperationRunner$2.execute(DefaultBuildOperationRunner.java:59)
   at org.gradle.internal.operations.DefaultBuildOperationRunner.execute(DefaultBuildOperationRunner.java:157)
   at org.gradle.internal.operations.DefaultBuildOperationRunner.execute(DefaultBuildOperationRunner.java:59)
   at org.gradle.internal.operations.DefaultBuildOperationRunner.run(DefaultBuildOperationRunner.java:47)
   at org.gradle.internal.operations.DefaultBuildOperationExecutor.run(DefaultBuildOperationExecutor.java:68)
   at org.gradle.configuration.project.LifecycleProjectEvaluator$EvaluateProject.lambda$run$0(LifecycleProjectEvaluator.java:114)
   at org.gradle.api.internal.project.DefaultProjectStateRegistry$ProjectStateImpl.lambda$applyToMutableState$1(DefaultProjectStateRegistry.java:406)
   at org.gradle.api.internal.project.DefaultProjectStateRegistry$ProjectStateImpl.lambda$fromMutableState$2(DefaultProjectStateRegistry.java:429)
   at org.gradle.internal.work.DefaultWorkerLeaseService.withReplacedLocks(DefaultWorkerLeaseService.java:360)
   at org.gradle.api.internal.project.DefaultProjectStateRegistry$ProjectStateImpl.fromMutableState(DefaultProjectStateRegistry.java:429)
   at org.gradle.api.internal.project.DefaultProjectStateRegistry$ProjectStateImpl.applyToMutableState(DefaultProjectStateRegistry.java:405)
   at org.gradle.configuration.project.LifecycleProjectEvaluator$EvaluateProject.run(LifecycleProjectEvaluator.java:100)
   at org.gradle.internal.operations.DefaultBuildOperationRunner$1.execute(DefaultBuildOperationRunner.java:29)
   at org.gradle.internal.operations.DefaultBuildOperationRunner$1.execute(DefaultBuildOperationRunner.java:26)
   at org.gradle.internal.operations.DefaultBuildOperationRunner$2.execute(DefaultBuildOperationRunner.java:66)
   at org.gradle.internal.operations.DefaultBuildOperationRunner$2.execute(DefaultBuildOperationRunner.java:59)
   at org.gradle.internal.operations.DefaultBuildOperationRunner.execute(DefaultBuildOperationRunner.java:157)
   at org.gradle.internal.operations.DefaultBuildOperationRunner.execute(DefaultBuildOperationRunner.java:59)
   at org.gradle.internal.operations.DefaultBuildOperationRunner.run(DefaultBuildOperationRunner.java:47)
   at org.gradle.internal.operations.DefaultBuildOperationExecutor.run(DefaultBuildOperationExecutor.java:68)
   at org.gradle.configuration.project.LifecycleProjectEvaluator.evaluate(LifecycleProjectEvaluator.java:72)
   at org.gradle.api.internal.project.DefaultProject.evaluate(DefaultProject.java:790)
   at org.gradle.api.internal.project.DefaultProject.evaluate(DefaultProject.java:156)
   at org.gradle.api.internal.project.ProjectLifecycleController.lambda$ensureSelfConfigured$2(ProjectLifecycleController.java:84)
   at org.gradle.internal.model.StateTransitionController.lambda$doTransition$14(StateTransitionController.java:255)
   at org.gradle.internal.model.StateTransitionController.doTransition(StateTransitionController.java:266)
   at org.gradle.internal.model.StateTransitionController.doTransition(StateTransitionController.java:254)
   at org.gradle.internal.model.StateTransitionController.lambda$maybeTransitionIfNotCurrentlyTransitioning$10(StateTransitionController.java:199)
   at org.gradle.internal.work.DefaultSynchronizer.withLock(DefaultSynchronizer.java:34)
   at org.gradle.internal.model.StateTransitionController.maybeTransitionIfNotCurrentlyTransitioning(StateTransitionController.java:195)
   at org.gradle.api.internal.project.ProjectLifecycleController.ensureSelfConfigured(ProjectLifecycleController.java:84)
   at org.gradle.api.internal.project.DefaultProjectStateRegistry$ProjectStateImpl.ensureConfigured(DefaultProjectStateRegistry.java:380)
   at org.gradle.execution.TaskPathProjectEvaluator.configure(TaskPathProjectEvaluator.java:34)
   at org.gradle.execution.TaskPathProjectEvaluator.configureHierarchy(TaskPathProjectEvaluator.java:50)
   at org.gradle.configuration.DefaultProjectsPreparer.prepareProjects(DefaultProjectsPreparer.java:42)
   at org.gradle.configuration.BuildTreePreparingProjectsPreparer.prepareProjects(BuildTreePreparingProjectsPreparer.java:65)
   at org.gradle.configuration.BuildOperationFiringProjectsPreparer$ConfigureBuild.run(BuildOperationFiringProjectsPreparer.java:52)
   at org.gradle.internal.operations.DefaultBuildOperationRunner$1.execute(DefaultBuildOperationRunner.java:29)
   at org.gradle.internal.operations.DefaultBuildOperationRunner$1.execute(DefaultBuildOperationRunner.java:26)
   at org.gradle.internal.operations.DefaultBuildOperationRunner$2.execute(DefaultBuildOperationRunner.java:66)
   at org.gradle.internal.operations.DefaultBuildOperationRunner$2.execute(DefaultBuildOperationRunner.java:59)
   at org.gradle.internal.operations.DefaultBuildOperationRunner.execute(DefaultBuildOperationRunner.java:157)
   at org.gradle.internal.operations.DefaultBuildOperationRunner.execute(DefaultBuildOperationRunner.java:59)
   at org.gradle.internal.operations.DefaultBuildOperationRunner.run(DefaultBuildOperationRunner.java:47)
   at org.gradle.internal.operations.DefaultBuildOperationExecutor.run(DefaultBuildOperationExecutor.java:68)
   at org.gradle.configuration.BuildOperationFiringProjectsPreparer.prepareProjects(BuildOperationFiringProjectsPreparer.java:40)
   at org.gradle.initialization.VintageBuildModelController.lambda$prepareProjects$2(VintageBuildModelController.java:84)
   at org.gradle.internal.model.StateTransitionController.lambda$doTransition$14(StateTransitionController.java:255)
   at org.gradle.internal.model.StateTransitionController.doTransition(StateTransitionController.java:266)
   at org.gradle.internal.model.StateTransitionController.doTransition(StateTransitionController.java:254)
   at org.gradle.internal.model.StateTransitionController.lambda$transitionIfNotPreviously$11(StateTransitionController.java:213)
   at org.gradle.internal.work.DefaultSynchronizer.withLock(DefaultSynchronizer.java:34)
   at org.gradle.internal.model.StateTransitionController.transitionIfNotPreviously(StateTransitionController.java:209)
   at org.gradle.initialization.VintageBuildModelController.prepareProjects(VintageBuildModelController.java:84)
   at org.gradle.initialization.VintageBuildModelController.prepareToScheduleTasks(VintageBuildModelController.java:71)
   at org.gradle.internal.build.DefaultBuildLifecycleController.lambda$prepareToScheduleTasks$6(DefaultBuildLifecycleController.java:175)
   at org.gradle.internal.model.StateTransitionController.lambda$doTransition$14(StateTransitionController.java:255)
   at org.gradle.internal.model.StateTransitionController.doTransition(StateTransitionController.java:266)
   at org.gradle.internal.model.StateTransitionController.doTransition(StateTransitionController.java:254)
   at org.gradle.internal.model.StateTransitionController.lambda$maybeTransition$9(StateTransitionController.java:190)
   at org.gradle.internal.work.DefaultSynchronizer.withLock(DefaultSynchronizer.java:34)
   at org.gradle.internal.model.StateTransitionController.maybeTransition(StateTransitionController.java:186)
   at org.gradle.internal.build.DefaultBuildLifecycleController.prepareToScheduleTasks(DefaultBuildLifecycleController.java:173)
   at org.gradle.internal.buildtree.DefaultBuildTreeWorkPreparer.scheduleRequestedTasks(DefaultBuildTreeWorkPreparer.java:36)
   at org.gradle.configurationcache.VintageBuildTreeWorkController$scheduleAndRunRequestedTasks$1.apply(VintageBuildTreeWorkController.kt:36)
   at org.gradle.configurationcache.VintageBuildTreeWorkController$scheduleAndRunRequestedTasks$1.apply(VintageBuildTreeWorkController.kt:35)
   at org.gradle.composite.internal.DefaultIncludedBuildTaskGraph.withNewWorkGraph(DefaultIncludedBuildTaskGraph.java:112)
   at org.gradle.configurationcache.VintageBuildTreeWorkController.scheduleAndRunRequestedTasks(VintageBuildTreeWorkController.kt:35)
   at org.gradle.internal.buildtree.DefaultBuildTreeLifecycleController.lambda$scheduleAndRunTasks$1(DefaultBuildTreeLifecycleController.java:76)
   at org.gradle.internal.buildtree.DefaultBuildTreeLifecycleController.lambda$runBuild$4(DefaultBuildTreeLifecycleController.java:119)
   at org.gradle.internal.model.StateTransitionController.lambda$transition$6(StateTransitionController.java:169)
   at org.gradle.internal.model.StateTransitionController.doTransition(StateTransitionController.java:266)
   at org.gradle.internal.model.StateTransitionController.lambda$transition$7(StateTransitionController.java:169)
   at org.gradle.internal.work.DefaultSynchronizer.withLock(DefaultSynchronizer.java:44)
   at org.gradle.internal.model.StateTransitionController.transition(StateTransitionController.java:169)
   at org.gradle.internal.buildtree.DefaultBuildTreeLifecycleController.runBuild(DefaultBuildTreeLifecycleController.java:116)
   at org.gradle.internal.buildtree.DefaultBuildTreeLifecycleController.scheduleAndRunTasks(DefaultBuildTreeLifecycleController.java:76)
   at org.gradle.internal.buildtree.DefaultBuildTreeLifecycleController.scheduleAndRunTasks(DefaultBuildTreeLifecycleController.java:71)
   at org.gradle.tooling.internal.provider.ExecuteBuildActionRunner.run(ExecuteBuildActionRunner.java:31)
   at org.gradle.launcher.exec.ChainingBuildActionRunner.run(ChainingBuildActionRunner.java:35)
   at org.gradle.internal.buildtree.ProblemReportingBuildActionRunner.run(ProblemReportingBuildActionRunner.java:49)
   at org.gradle.launcher.exec.BuildOutcomeReportingBuildActionRunner.run(BuildOutcomeReportingBuildActionRunner.java:65)
   at org.gradle.tooling.internal.provider.FileSystemWatchingBuildActionRunner.run(FileSystemWatchingBuildActionRunner.java:140)
   at org.gradle.launcher.exec.BuildCompletionNotifyingBuildActionRunner.run(BuildCompletionNotifyingBuildActionRunner.java:41)
   at org.gradle.launcher.exec.RootBuildLifecycleBuildActionExecutor.lambda$execute$0(RootBuildLifecycleBuildActionExecutor.java:40)
   at org.gradle.composite.internal.DefaultRootBuildState.run(DefaultRootBuildState.java:123)
   at org.gradle.launcher.exec.RootBuildLifecycleBuildActionExecutor.execute(RootBuildLifecycleBuildActionExecutor.java:40)
   at org.gradle.internal.buildtree.InitDeprecationLoggingActionExecutor.execute(InitDeprecationLoggingActionExecutor.java:62)
   at org.gradle.internal.buildtree.InitProblems.execute(InitProblems.java:38)
   at org.gradle.internal.buildtree.DefaultBuildTreeContext.execute(DefaultBuildTreeContext.java:40)
   at org.gradle.launcher.exec.BuildTreeLifecycleBuildActionExecutor.lambda$execute$0(BuildTreeLifecycleBuildActionExecutor.java:58)
   at org.gradle.internal.buildtree.BuildTreeState.run(BuildTreeState.java:58)
   at org.gradle.launcher.exec.BuildTreeLifecycleBuildActionExecutor.execute(BuildTreeLifecycleBuildActionExecutor.java:58)
   at org.gradle.launcher.exec.RunAsBuildOperationBuildActionExecutor$3.call(RunAsBuildOperationBuildActionExecutor.java:61)
   at org.gradle.launcher.exec.RunAsBuildOperationBuildActionExecutor$3.call(RunAsBuildOperationBuildActionExecutor.java:57)
   at org.gradle.internal.operations.DefaultBuildOperationRunner$CallableBuildOperationWorker.execute(DefaultBuildOperationRunner.java:204)
   at org.gradle.internal.operations.DefaultBuildOperationRunner$CallableBuildOperationWorker.execute(DefaultBuildOperationRunner.java:199)
   at org.gradle.internal.operations.DefaultBuildOperationRunner$2.execute(DefaultBuildOperationRunner.java:66)
   at org.gradle.internal.operations.DefaultBuildOperationRunner$2.execute(DefaultBuildOperationRunner.java:59)
   at org.gradle.internal.operations.DefaultBuildOperationRunner.execute(DefaultBuildOperationRunner.java:157)
   at org.gradle.internal.operations.DefaultBuildOperationRunner.execute(DefaultBuildOperationRunner.java:59)
   at org.gradle.internal.operations.DefaultBuildOperationRunner.call(DefaultBuildOperationRunner.java:53)
   at org.gradle.internal.operations.DefaultBuildOperationExecutor.call(DefaultBuildOperationExecutor.java:73)
   at org.gradle.launcher.exec.RunAsBuildOperationBuildActionExecutor.execute(RunAsBuildOperationBuildActionExecutor.java:57)
   at org.gradle.launcher.exec.RunAsWorkerThreadBuildActionExecutor.lambda$execute$0(RunAsWorkerThreadBuildActionExecutor.java:36)
   at org.gradle.internal.work.DefaultWorkerLeaseService.withLocks(DefaultWorkerLeaseService.java:264)
   at org.gradle.internal.work.DefaultWorkerLeaseService.runAsWorkerThread(DefaultWorkerLeaseService.java:128)
   at org.gradle.launcher.exec.RunAsWorkerThreadBuildActionExecutor.execute(RunAsWorkerThreadBuildActionExecutor.java:36)
   at org.gradle.tooling.internal.provider.continuous.ContinuousBuildActionExecutor.execute(ContinuousBuildActionExecutor.java:110)
   at org.gradle.tooling.internal.provider.SubscribableBuildActionExecutor.execute(SubscribableBuildActionExecutor.java:64)
   at org.gradle.internal.session.DefaultBuildSessionContext.execute(DefaultBuildSessionContext.java:46)
   at org.gradle.tooling.internal.provider.BuildSessionLifecycleBuildActionExecuter$ActionImpl.apply(BuildSessionLifecycleBuildActionExecuter.java:92)
   at org.gradle.tooling.internal.provider.BuildSessionLifecycleBuildActionExecuter$ActionImpl.apply(BuildSessionLifecycleBuildActionExecuter.java:80)
   at org.gradle.internal.session.BuildSessionState.run(BuildSessionState.java:69)
   at org.gradle.tooling.internal.provider.BuildSessionLifecycleBuildActionExecuter.execute(BuildSessionLifecycleBuildActionExecuter.java:62)
   at org.gradle.tooling.internal.provider.BuildSessionLifecycleBuildActionExecuter.execute(BuildSessionLifecycleBuildActionExecuter.java:41)
   at org.gradle.tooling.internal.provider.StartParamsValidatingActionExecuter.execute(StartParamsValidatingActionExecuter.java:64)
   at org.gradle.tooling.internal.provider.StartParamsValidatingActionExecuter.execute(StartParamsValidatingActionExecuter.java:32)
   at org.gradle.tooling.internal.provider.SessionFailureReportingActionExecuter.execute(SessionFailureReportingActionExecuter.java:51)
   at org.gradle.tooling.internal.provider.SessionFailureReportingActionExecuter.execute(SessionFailureReportingActionExecuter.java:39)
   at org.gradle.tooling.internal.provider.SetupLoggingActionExecuter.execute(SetupLoggingActionExecuter.java:47)
   at org.gradle.tooling.internal.provider.SetupLoggingActionExecuter.execute(SetupLoggingActionExecuter.java:31)
   at org.gradle.launcher.daemon.server.exec.ExecuteBuild.doBuild(ExecuteBuild.java:65)
   at org.gradle.launcher.daemon.server.exec.BuildCommandOnly.execute(BuildCommandOnly.java:37)
   at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:104)
   at org.gradle.launcher.daemon.server.exec.WatchForDisconnection.execute(WatchForDisconnection.java:39)
   at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:104)
   at org.gradle.launcher.daemon.server.exec.ResetDeprecationLogger.execute(ResetDeprecationLogger.java:29)
   at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:104)
   at org.gradle.launcher.daemon.server.exec.RequestStopIfSingleUsedDaemon.execute(RequestStopIfSingleUsedDaemon.java:35)
   at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:104)
   at org.gradle.launcher.daemon.server.exec.ForwardClientInput$2.create(ForwardClientInput.java:78)
   at org.gradle.launcher.daemon.server.exec.ForwardClientInput$2.create(ForwardClientInput.java:75)
   at org.gradle.util.internal.Swapper.swap(Swapper.java:38)
   at org.gradle.launcher.daemon.server.exec.ForwardClientInput.execute(ForwardClientInput.java:75)
   at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:104)
   at org.gradle.launcher.daemon.server.exec.LogAndCheckHealth.execute(LogAndCheckHealth.java:64)
   at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:104)
   at org.gradle.launcher.daemon.server.exec.LogToClient.doBuild(LogToClient.java:63)
   at org.gradle.launcher.daemon.server.exec.BuildCommandOnly.execute(BuildCommandOnly.java:37)
   at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:104)
   at org.gradle.launcher.daemon.server.exec.EstablishBuildEnvironment.doBuild(EstablishBuildEnvironment.java:84)
   at org.gradle.launcher.daemon.server.exec.BuildCommandOnly.execute(BuildCommandOnly.java:37)
   at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:104)
   at org.gradle.launcher.daemon.server.exec.StartBuildOrRespondWithBusy$1.run(StartBuildOrRespondWithBusy.java:52)
   at org.gradle.launcher.daemon.server.DaemonStateCoordinator$1.run(DaemonStateCoordinator.java:297)
   at org.gradle.internal.concurrent.ExecutorPolicy$CatchAndRecordFailures.onExecute(ExecutorPolicy.java:64)
   at org.gradle.internal.concurrent.AbstractManagedExecutor$1.run(AbstractManagedExecutor.java:47)
 Caused by: java.lang.NullPointerException: getProject(...) must not be null
   at godot.gradle.tasks.SetupSyncTaskKt.setupAfterIdeaSyncTasks(setupSyncTask.kt:13)
   at godot.gradle.projectExt.SetupTasksKt$setupTasks$1.invoke(setupTasks.kt:102)
   at godot.gradle.projectExt.SetupTasksKt$setupTasks$1.invoke(setupTasks.kt:24)
   at godot.gradle.projectExt.SetupTasksKt.setupTasks$lambda$0(setupTasks.kt:24)
   at org.gradle.internal.code.DefaultUserCodeApplicationContext$CurrentApplication$1.execute(DefaultUserCodeApplicationContext.java:122)
   at org.gradle.configuration.internal.DefaultListenerBuildOperationDecorator$BuildOperationEmittingAction$1.run(DefaultListenerBuildOperationDecorator.java:173)
   at org.gradle.internal.operations.DefaultBuildOperationRunner$1.execute(DefaultBuildOperationRunner.java:29)
   at org.gradle.internal.operations.DefaultBuildOperationRunner$1.execute(DefaultBuildOperationRunner.java:26)
   at org.gradle.internal.operations.DefaultBuildOperationRunner$2.execute(DefaultBuildOperationRunner.java:66)
   at org.gradle.internal.operations.DefaultBuildOperationRunner$2.execute(DefaultBuildOperationRunner.java:59)
   at org.gradle.internal.operations.DefaultBuildOperationRunner.execute(DefaultBuildOperationRunner.java:157)
   at org.gradle.internal.operations.DefaultBuildOperationRunner.execute(DefaultBuildOperationRunner.java:59)
   at org.gradle.internal.operations.DefaultBuildOperationRunner.run(DefaultBuildOperationRunner.java:47)
   at org.gradle.internal.operations.DefaultBuildOperationExecutor.run(DefaultBuildOperationExecutor.java:68)
   at org.gradle.configuration.internal.DefaultListenerBuildOperationDecorator$BuildOperationEmittingAction.execute(DefaultListenerBuildOperationDecorator.java:170)
   at org.gradle.internal.event.BroadcastDispatch$ActionInvocationHandler.dispatch(BroadcastDispatch.java:99)
   at org.gradle.internal.event.BroadcastDispatch$ActionInvocationHandler.dispatch(BroadcastDispatch.java:87)
   at org.gradle.internal.event.AbstractBroadcastDispatch.dispatch(AbstractBroadcastDispatch.java:43)
   at org.gradle.internal.event.BroadcastDispatch$SingletonDispatch.dispatch(BroadcastDispatch.java:268)
   at org.gradle.internal.event.BroadcastDispatch$SingletonDispatch.dispatch(BroadcastDispatch.java:170)
   at org.gradle.internal.event.AbstractBroadcastDispatch.dispatch(AbstractBroadcastDispatch.java:83)
   at org.gradle.internal.event.AbstractBroadcastDispatch.dispatch(AbstractBroadcastDispatch.java:69)
   at org.gradle.internal.event.BroadcastDispatch$CompositeDispatch.dispatch(BroadcastDispatch.java:381)
   at org.gradle.internal.event.BroadcastDispatch$CompositeDispatch.dispatch(BroadcastDispatch.java:272)
   at org.gradle.internal.event.ListenerBroadcast.dispatch(ListenerBroadcast.java:148)
   at org.gradle.internal.event.ListenerBroadcast.dispatch(ListenerBroadcast.java:37)
   at org.gradle.internal.dispatch.ProxyDispatchAdapter$DispatchingInvocationHandler.invoke(ProxyDispatchAdapter.java:94)
   at jdk.proxy1/jdk.proxy1.$Proxy64.afterEvaluate(Unknown Source)
   at org.gradle.configuration.project.LifecycleProjectEvaluator$NotifyAfterEvaluate$1.execute(LifecycleProjectEvaluator.java:247)
   at org.gradle.configuration.project.LifecycleProjectEvaluator$NotifyAfterEvaluate$1.execute(LifecycleProjectEvaluator.java:244)
   at org.gradle.api.internal.project.DefaultProject.stepEvaluationListener(DefaultProject.java:1497)
   at org.gradle.configuration.project.LifecycleProjectEvaluator$NotifyAfterEvaluate.run(LifecycleProjectEvaluator.java:253)
   ... 151 more

Aside from all the noise, the last part is interesting:

 Caused by: java.lang.NullPointerException: getProject(...) must not be null
   at godot.gradle.tasks.SetupSyncTaskKt.setupAfterIdeaSyncTasks(setupSyncTask.kt:13)

I've had a quick look into the source code of the godot gradle plugin. It seems to attempt some sort of interaction with then IntelliJ IDEA plugin. I tried adding that plugin, but unfortunately it changed nothing.

Using the gradle plugin in a standalone setup (i.e. without sub-modules) it works just fine, but it doesn't seem to play nice with multi-module builds.

MartinHaeusler commented 8 months ago

New insight: The idea plugin itself only seems to operate as a top-level plugin.

For instance, if I do this in a sub-project:

plugins {
    idea
}

println(idea.project)

... it prints null (which explains the NullPointerException).

If I do the same thing in the top-level project, I get:

org.gradle.plugins.ide.idea.model.IdeaProject_Decorated@100fc7c0

This is consistent with my other observations and explains the NullPointerException. The questions that remain are:

Frontrider commented 8 months ago

This looks like a bug to me, but in the case of the example I'd try not to apply the godot plugin to the root project.

MartinHaeusler commented 8 months ago

@Frontrider I didn't apply the plugin top-level (apply false). I'm already working on a fix but currently struggling with the local test setup. Got some clues om discord. If things work out the way I want them to there will be a PR this weekend.

chippmann commented 8 months ago

@MartinHaeusler thx for looking into this. If you need more help with the gradle setup for local development, feel free to ask.

I'll assign you the issue for now then.

MartinHaeusler commented 8 months ago

@chippmann I've made some progress thanks to your hints, but testing the godot-kotlin-jvm gradle plugin locally turns out to be an extremely deep rabbit hole. So here's what I've found.

Short Version

I'm still having a lot of issues with the local (debug) deployment of the godot-kotlin-jvm gradle plugin. The bug I set out to fix has been addressed, the errors I'm seeing now (KSP) seem completely unrelated to my changes and may be due to a local setup problem.

I'm uncertain how to proceed. Do you want me to create a pull request so someone with a proper test setup can verify the fix, even though I can't seem to create a fully working build with my local snapshot?

Long Version

The godot-kotlin-jvm plugin relies on the lifecycle of the idea plugin to carry out a task which distributes .gdignore files to make the editor ignore certain directories (e.g. build output). To do so, the task is registered like this (setupSyncTask.kt):

ideaExtension.project.settings {
        taskTriggers {
            afterSync(generateGdIgnoreFilesTask)
        }
}

Unfortunately that doesn't work if the godot-kotlin-jvm plugin gets applied to a sub-module, because the ideaExtension.project returns null for every gradle sub-module. It only returns a non-null value for the root project. We can work around this by doing:

  rootProject.ideaExtension.project.settings {
      taskTriggers {
          afterSync(generateGdIgnoreFilesTask)
      }
  }

A few adaptions in generateGdIgnoreFilesTask.kt were also necessary to ensure that the task accesses the folders of the project it was started on (and not the root project). Also, in configureThirdPartyPlugins I had to ensure that the idea and idea-ext plugins are added to the root project as well:

    // apply the idea plugin to the *root* project.
    // this is necessary because the IntelliJ IDEA plugin is used for managing some
    // of our tasks, and its capabilities are available only on the root project.
    if(this.rootProject != this.project) {
        this.rootProject.pluginManager.apply(IdeaPlugin::class.java)
        this.rootProject.pluginManager.apply(IdeaExtPlugin::class.java)
    }

That's it. With this I attempted to test my project again. I built the plugin as you suggested via:

./gradlew :tools-common:publishToMavenLocal publishToMavenLocal

This worked (after I manually created the folder home/<user>/Documents/doc/classes which for some reason needs to exist for the task to run correctly).

In my settings.gradle.kts file I've added your proposed configuration:

pluginManagement {
    repositories {
        mavenLocal()
        mavenCentral()
        gradlePluginPortal()
        google()
    }

    resolutionStrategy.eachPlugin {
        if (requested.id.id == "com.utopia-rise.godot-kotlin-jvm") {
            useModule("com.utopia-rise:godot-gradle-plugin:${requested.version}")
        }
    }
}

This did the trick - kind of. My test project can now successfully apply the godot-kotlin-jvm plugin in a sub-module (from maven local, with my snapshot version) and run the gradle task ./gradlew generateGdIgnoreFiles with no issues. I checked, the .gdignore files are generated in the correct locations. This was the task which previously threw the NullPointerException that was reported in this github issue.

However, ./gradlew build doesn't work in my test project anymore, because it requires com.utopia-rise.godot-library-debug at version 0.7.2-4.1.2. The build task you've proposed (:tools-common:publishToMavenLocal publishToMavenLocal) seems to generate a different artifact which has the version 0.7.2-4.1.2-fc2f3ea-SNAPSHOT. To work around this (at least temporarily) I did something really dirty and renamed the folders and maven entries in my .m2 directory to make gradle believe that my locally built godot-library-debug had the version it was looking for.

With this hack in place, I'm now stuck at this error:

> Task :client:kspKotlin FAILED
e: [ksp] java.util.NoSuchElementException: Collection contains no element matching the predicate.
        at com.google.devtools.ksp.UtilsKt.createInvocationHandler$lambda$8(utils.kt:553)
        at jdk.proxy4/jdk.proxy4.$Proxy28.localResPath(Unknown Source)
        at godot.annotation.processor.visitor.MetadataAnnotationVisitor.visitClassDeclaration(MetadataAnnotationVisitor.kt:30)
        at godot.annotation.processor.visitor.MetadataAnnotationVisitor.visitClassDeclaration(MetadataAnnotationVisitor.kt:14)

... and I'm really at my wits end here, I have no clue about KSP or why this fails. Also, I can't see how this would be caused by the changes I made. If anything, I believe that this is due to the semi-faulty local deployment I have here.

Should I create a PR anyway for testing by someone with a proper local test setup?

Frontrider commented 8 months ago

The godot-kotlin-jvm plugin relies on the lifecycle of the idea plugin to carry out a task which distributes .gdignore files to make the editor ignore certain directories (e.g. build output). To do so, the task is registered like this (setupSyncTask.kt):

Why does it must depend on it? That would be good to know, because it might be more feasible to just do a makedir on the build folder for example.

That example is one where nobody cares which plugin creates it, and intellij should not need it as far as I'm aware.

MartinHaeusler commented 8 months ago

Why does it must depend on it? That would be good to know, because it might be more feasible to just do a makedir on the build folder for example.

That example is one where nobody cares which plugin creates it, and intellij should not need it as far as I'm aware.

Excellent question. To be honest: I don't know the exact purpose. I initially assumed that it has something to do with timing and execution order, and that the task handed to the idea plugin needs to be executed in a certain point in the lifecycle in order to work properly. But considering that it literally only creates some empty marker files, I question that decision as well. I don't know the original reasoning for it.

Frontrider commented 8 months ago

I can see it as "the idea plugin makes a few folders, let's do work after it is done", but that is really not needed. I don't know if it does anything you actually need other than letting you configure intellij from your build. The default compat is usually more than enough for what I need.

@chippmann what was the original goal? Does it do something with editor plugin?

chippmann commented 8 months ago

The reason was/is mainly the initial project creation project creation from the wizard in the intellij plugin. After the project is created and indexed by the ide, the appropriate files are created so that even before a user builds the project, the corresponding folders are ignored and the godot editor does not show them.

But i do agree that this is not really needed. A better way would be to add the corresponding files in the project template in the idea plugin and regenerate them when the user builds the project. Then we'd have a pretty standard task dependency setup without relying on the idea sync task. But the dependency is still needed as the idea plugin is also applied to the users project so idea does recognize the generated files and provides the user with some info (like syntax highlighting, and source code navigation): https://github.com/utopia-rise/godot-kotlin-jvm/blob/fc2f3eacf779c21ce18d2161cca63e6dffdb1c91/kt/plugins/godot-gradle-plugin/src/main/kotlin/godot/gradle/projectExt/configureThirdPartyPlugins.kt#L83

@MartinHaeusler i really appreciate your work here. Thanks a lot for your time! So depending on what you want to do I'm fine with either your proposed way of just creating a PR regardless of your local build so others (like myself) can look at it, or you could directly implemented the suggested change. If you're not comfortable with or do not want to edit the idea plugin template project, or do not want to invest more time, i could take over as well. I leave that up to you :-)

chippmann commented 8 months ago

Regarding your local setup, we can discuss this on discord if that's ok for you

MartinHaeusler commented 8 months ago

@chippmann PR containing a minimal fix is open: https://github.com/utopia-rise/godot-kotlin-jvm/pull/549

Thanks to your efforts I've been able to build the plugin locally and also consume it within my project to verify that the fix indeed works. There are also other issues I've encountered but I'll create separate tickets for them.

MartinHaeusler commented 8 months ago

@chippmann The PR contains the promised fix for the NullPonterException. In the grand scheme of things, I think generating these files in the gradle plugin at all is not really necessary, and doing so with a dependency on the idea plugin doesn't seem like the best approach. Details below.

What's the worst case? The .gdignore files are not there. This will cause the godot editor to scan a few hundred text files more. Not really dramatic (unless I'm missing something?) I think, if at all, it's enough to generate the .gdignore files once in the intellij project wizard plugin / project template. Users with small projects won't notice a big difference either way, and power users with large projects likely know about .gdignore files already and will place them manually as they see fit.

Regarding the interplay between the intellij ide and the gradle plugin, to me as an "outside observer" who's not familiar with the details, it would make sense that the intellij ide plugin fetches information from the project, but the project should not depend on intellij (or their gradle module).

So, to summarize: generate the .gdignore files in the intellij project template once, but don't touch them afterwards is what I would do. Cut any dependency from the godot-kotlin-jvm plugin towards intellij.

Just my 5 cents, please correct me if I'm wrong, still pretty new to all of this.